Use headers for all routes
This commit is contained in:
parent
213bb1c179
commit
30abe56325
@ -10,6 +10,8 @@ const headerKeyPassword = "password";
|
|||||||
const headerKeyToken = "token";
|
const headerKeyToken = "token";
|
||||||
const headerKeyName = "name";
|
const headerKeyName = "name";
|
||||||
const headerKeyMail = "email";
|
const headerKeyMail = "email";
|
||||||
|
const headerKeyVisibility = "visibility";
|
||||||
|
const headerKeyAction = "action";
|
||||||
|
|
||||||
function webSocketPath() {
|
function webSocketPath() {
|
||||||
const prefix = (window.location.protocol === "https:") ? "wss://" : "ws://"
|
const prefix = (window.location.protocol === "https:") ? "wss://" : "ws://"
|
||||||
@ -29,29 +31,50 @@ async function performRegisterPlayerRequest(name, password, email) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function performDeletePlayerRequest(name, password) {
|
async function performDeletePlayerRequest(name, password) {
|
||||||
return fetch(apiPath + "/player/delete/" + name, { method: 'POST', body: password })
|
return fetch(apiPath + "/player/delete", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
[headerKeyName]: name,
|
||||||
|
[headerKeyPassword]: password,
|
||||||
|
}
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
.then(function(value) {})
|
.then(function(value) {})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performLoginPlayerRequest(name, password) {
|
async function performLoginPlayerRequest(name, password) {
|
||||||
return fetch(apiPath + "/player/login/" + name, { method: 'POST', body: password })
|
return fetch(apiPath + "/player/login", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
[headerKeyName]: name,
|
||||||
|
[headerKeyPassword]: password,
|
||||||
|
}
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performLogoutRequest(token) {
|
async function performLogoutRequest(token) {
|
||||||
return fetch(apiPath + "/player/logout", { method: 'POST', body: token })
|
return fetch(apiPath + "/player/logout", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { [headerKeyToken]: token },
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
.then(function(value) {})
|
.then(function(value) {})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resumeSessionRequest(token) {
|
async function resumeSessionRequest(token) {
|
||||||
return fetch(apiPath + "/player/resume", { method: 'POST', body: token })
|
return fetch(apiPath + "/player/resume", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { [headerKeyToken]: token },
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performGetCurrentTableRequest(token) {
|
async function performGetCurrentTableRequest(token) {
|
||||||
return fetch(apiPath + "/player/table", { method: 'POST', body: token })
|
return fetch(apiPath + "/player/table", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: [headerKeyToken]: token,
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
.then(convertJsonResponse)
|
.then(convertJsonResponse)
|
||||||
}
|
}
|
||||||
@ -65,7 +88,7 @@ async function performRecoveryEmailRequest(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function performResetPasswordRequest(token, password) {
|
async function performResetPasswordRequest(token, password) {
|
||||||
return fetch(apiPath + "/player/reset", {
|
return fetch(apiPath + "/player/password/new", {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { [headerKeyPassword] : password, [headerKeyToken] : token }
|
headers: { [headerKeyPassword] : password, [headerKeyToken] : token }
|
||||||
})
|
})
|
||||||
@ -74,36 +97,68 @@ async function performResetPasswordRequest(token, password) {
|
|||||||
|
|
||||||
async function performCreateTableRequest(token, name, visibility) {
|
async function performCreateTableRequest(token, name, visibility) {
|
||||||
const vis = visibility ? "public" : "private";
|
const vis = visibility ? "public" : "private";
|
||||||
return fetch(apiPath + "/table/create/" + vis + "/" + name, { method: 'POST', body: token })
|
return fetch(apiPath + "/table/create", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
[headerKeyVisibility]: vis,
|
||||||
|
[headerKeyToken]: token,
|
||||||
|
[headerKeyName]: name,
|
||||||
|
}
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
.then(convertJsonResponse)
|
.then(convertJsonResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performJoinTableRequest(tableId, token) {
|
async function performJoinTableRequest(tableId, token) {
|
||||||
return fetch(apiPath + "/table/join/" + tableId, { method: 'POST', body: token })
|
return fetch(apiPath + "/table/join", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
[headerKeyName]: tableId,
|
||||||
|
[headerKeyToken]: token,
|
||||||
|
}
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
.then(convertJsonResponse)
|
.then(convertJsonResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performGetPublicTablesRequest(token) {
|
async function performGetPublicTablesRequest(token) {
|
||||||
return fetch(apiPath + "/tables/public", { method: 'POST', body: token })
|
return fetch(apiPath + "/tables/public", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { [headerKeyToken] : token }
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
.then(convertJsonResponse)
|
.then(convertJsonResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performLeaveTableRequest(token) {
|
async function performLeaveTableRequest(token) {
|
||||||
return fetch(apiPath + "/table/leave", { method: 'POST', body: token })
|
return fetch(apiPath + "/table/leave", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { [headerKeyToken] : token },
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
.then(function(value) {})
|
.then(function(value) {})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performPlayerActionRequest(token, action) {
|
async function performPlayerActionRequest(token, action) {
|
||||||
return fetch(apiPath + "/player/action/" + action, { method: 'POST', body: token })
|
return fetch(apiPath + "/player/action", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
[headerKeyToken] : token,
|
||||||
|
[headerKeyAction] : action,
|
||||||
|
},
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
|
.then(function(value) {})
|
||||||
}
|
}
|
||||||
|
|
||||||
async function performPlayCardRequest(token, card) {
|
async function performPlayCardRequest(token, card) {
|
||||||
return fetch(apiPath + "/player/card/" + card, { method: 'POST', body: token })
|
return fetch(apiPath + "/player/card", {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
[headerKeyToken] : token,
|
||||||
|
[headerKeyAction] : card,
|
||||||
|
},
|
||||||
|
})
|
||||||
.then(convertServerResponse)
|
.then(convertServerResponse)
|
||||||
.then(function(value) {})
|
.then(function(value) {})
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ enum HeaderKey: String {
|
|||||||
case password
|
case password
|
||||||
case email
|
case email
|
||||||
case token
|
case token
|
||||||
|
case visibility
|
||||||
|
case action
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Request {
|
extension Request {
|
||||||
|
@ -98,7 +98,7 @@ func requestPlayerPasswordReset(_ app: Application) {
|
|||||||
- `424`: Password could not be hashed
|
- `424`: Password could not be hashed
|
||||||
*/
|
*/
|
||||||
func resetPlayerPasswordWithEmailToken(_ app: Application) {
|
func resetPlayerPasswordWithEmailToken(_ app: Application) {
|
||||||
app.post("player", "reset") { req async throws -> HTTPResponseStatus in
|
app.post("player", "password", "new") { req async throws -> HTTPResponseStatus in
|
||||||
let token = try req.header(.token) // 400
|
let token = try req.header(.token) // 400
|
||||||
let hash = try req.hashedPassword() // errors: 400, 424
|
let hash = try req.hashedPassword() // errors: 400, 424
|
||||||
try await server.updatePassword(password: hash, forResetToken: token, in: req.db) // 417
|
try await server.updatePassword(password: hash, forResetToken: token, in: req.db) // 417
|
||||||
@ -109,21 +109,20 @@ func resetPlayerPasswordWithEmailToken(_ app: Application) {
|
|||||||
/**
|
/**
|
||||||
Delete a player.
|
Delete a player.
|
||||||
|
|
||||||
- Parameter name: The name of the player, included in the url
|
**Headers**
|
||||||
- Parameter password: The password of the player, as a string in the request body
|
- `name`: The name of the player
|
||||||
|
- `password`: The password of the player
|
||||||
|
|
||||||
Possible errors:
|
**Possible errors**
|
||||||
- `400`: Missing name or password
|
- `400`: Missing name or password
|
||||||
- `401`: The password or user name is invalid
|
- `401`: The password or user name is invalid
|
||||||
- `424`: The password could not be hashed
|
- `424`: The password could not be hashed
|
||||||
- Returns: Nothing
|
|
||||||
*/
|
*/
|
||||||
func deletePlayer(_ app: Application) {
|
func deletePlayer(_ app: Application) {
|
||||||
app.post("player", "delete", ":name") { request async throws -> HTTPResponseStatus in
|
app.post("player", "delete") { request async throws -> HTTPResponseStatus in
|
||||||
guard let name = request.parameters.get("name"),
|
let name = try request.header(.name) // 400
|
||||||
let password = request.body.string else {
|
let password = try request.header(.password) // 400
|
||||||
return .badRequest // 400
|
|
||||||
}
|
|
||||||
let hash = try await server.passwordHashForExistingPlayer(named: name, in: request.db)
|
let hash = try await server.passwordHashForExistingPlayer(named: name, in: request.db)
|
||||||
guard try request.password.verify(password, created: hash) else {
|
guard try request.password.verify(password, created: hash) else {
|
||||||
return .unauthorized // 401
|
return .unauthorized // 401
|
||||||
@ -135,22 +134,24 @@ func deletePlayer(_ app: Application) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Log in as an existing player.
|
Log in as an existing player.
|
||||||
- Parameter name: The name of the player, included in the url
|
|
||||||
- Parameter password: The password of the player, as a string in the request body
|
|
||||||
|
|
||||||
Possible errors:
|
**Headers**
|
||||||
|
- `name`: The name of the player
|
||||||
|
- `password`: The password of the player
|
||||||
|
|
||||||
|
**Possible errors**
|
||||||
- `400`: Missing name or password
|
- `400`: Missing name or password
|
||||||
- `401`: The password or user name is invalid
|
- `401`: The password or user name is invalid
|
||||||
- `424`: The password could not be hashed
|
- `424`: The password could not be hashed
|
||||||
|
|
||||||
- Returns: The session token for the user
|
**Response**
|
||||||
|
- `body`: The session token for the user
|
||||||
*/
|
*/
|
||||||
func loginPlayer(_ app: Application) {
|
func loginPlayer(_ app: Application) {
|
||||||
app.post("player", "login", ":name") { request async throws -> String in
|
app.post("player", "login") { request async throws -> String in
|
||||||
guard let name = request.parameters.get("name"),
|
let name = try request.header(.name) // 400
|
||||||
let password = request.body.string else {
|
let password = try request.header(.password) // 400
|
||||||
throw Abort(.badRequest) // 400
|
|
||||||
}
|
|
||||||
let hash = try await server.passwordHashForExistingPlayer(named: name, in: request.db)
|
let hash = try await server.passwordHashForExistingPlayer(named: name, in: request.db)
|
||||||
guard try request.password.verify(password, created: hash) else {
|
guard try request.password.verify(password, created: hash) else {
|
||||||
throw Abort(.unauthorized) // 401
|
throw Abort(.unauthorized) // 401
|
||||||
@ -159,19 +160,23 @@ func loginPlayer(_ app: Application) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Log in using a session token.
|
Log in using a session token.
|
||||||
- Parameter token: The session token of the player, as a string in the request body
|
|
||||||
- Throws:
|
**Headers**
|
||||||
- 400: Missing token
|
- `token`: The session token of the player
|
||||||
- 401: The token is invalid
|
|
||||||
- Returns: The player name associated with the session token
|
**Possible errors**
|
||||||
|
- `400`: Missing token
|
||||||
|
- `401`: The token is invalid
|
||||||
|
|
||||||
|
**Response**
|
||||||
|
- `body`: The player name associated with the session token
|
||||||
*/
|
*/
|
||||||
func resumeSession(_ app: Application) {
|
func resumeSession(_ app: Application) {
|
||||||
app.post("player", "resume") { req -> String in
|
app.post("player", "resume") { request -> String in
|
||||||
guard let token = req.body.string else {
|
let token = try request.header(.token)
|
||||||
throw Abort(.badRequest) // 400
|
|
||||||
}
|
|
||||||
guard let player = server.registeredPlayerExists(withSessionToken: token) else {
|
guard let player = server.registeredPlayerExists(withSessionToken: token) else {
|
||||||
throw Abort(.unauthorized) // 401
|
throw Abort(.unauthorized) // 401
|
||||||
}
|
}
|
||||||
@ -179,38 +184,43 @@ func resumeSession(_ app: Application) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Log out.
|
Log out.
|
||||||
- Parameter name: The name of the player, included in the url
|
|
||||||
- Parameter token: The session token of the player, as a string in the request body
|
**Headers**
|
||||||
- Throws:
|
- `token`: The session token of the player
|
||||||
- 400: Missing token
|
|
||||||
- Returns: Nothing
|
**Possible errors**
|
||||||
|
- `400`: Missing token
|
||||||
|
|
||||||
- Note: The request always succeeds when correctly formed, even for invalid and expired tokens
|
- Note: The request always succeeds when correctly formed, even for invalid and expired tokens
|
||||||
*/
|
*/
|
||||||
func logoutPlayer(_ app: Application) {
|
func logoutPlayer(_ app: Application) {
|
||||||
app.post("player", "logout") { req -> String in
|
app.post("player", "logout") { request -> HTTPResponseStatus in
|
||||||
guard let token = req.body.string else {
|
let token = try request.header(.token)
|
||||||
throw Abort(.badRequest) // 400
|
|
||||||
}
|
|
||||||
server.endSession(forSessionToken: token)
|
server.endSession(forSessionToken: token)
|
||||||
return ""
|
return .ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the current table of the player, if one exists.
|
Get the current table of the player, if one exists.
|
||||||
- Parameter token: The session token of the player, as a string in the request body
|
|
||||||
- Throws:
|
**Headers**
|
||||||
- 400: Missing token
|
- `token`: The session token of the player
|
||||||
- 401: Invalid token
|
|
||||||
- Returns: The table info, or an empty string
|
**Possible errors**
|
||||||
|
- `400`: Missing token
|
||||||
|
- `401`: The token is invalid
|
||||||
|
|
||||||
|
**Response**
|
||||||
|
- `body`: The table info, or an empty string
|
||||||
*/
|
*/
|
||||||
func getTableForPlayer(_ app: Application) {
|
func getTableForPlayer(_ app: Application) {
|
||||||
app.post("player", "table") { req -> String in
|
app.post("player", "table") { request -> String in
|
||||||
guard let token = req.body.string else {
|
let token = try request.header(.token)
|
||||||
throw Abort(.badRequest) // 400
|
|
||||||
}
|
|
||||||
guard let player = server.registeredPlayerExists(withSessionToken: token) else {
|
guard let player = server.registeredPlayerExists(withSessionToken: token) else {
|
||||||
throw Abort(.unauthorized) // 401
|
throw Abort(.unauthorized) // 401
|
||||||
}
|
}
|
||||||
@ -221,9 +231,9 @@ func getTableForPlayer(_ app: Application) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Start a new websocket connection for the client to receive table updates from the server
|
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.
|
- Note: The first (and only) message from the client over the connection must be a valid session token.
|
||||||
*/
|
*/
|
||||||
func openWebsocket(_ app: Application) {
|
func openWebsocket(_ app: Application) {
|
||||||
@ -237,24 +247,29 @@ func openWebsocket(_ app: Application) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Tables
|
// MARK: Tables
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create a new table.
|
Create a new table.
|
||||||
- Parameter visibility: Indicate a `"public"` or `"private"` table
|
|
||||||
- Parameter token: The session token of the player, as a string in the request body
|
**Headers**
|
||||||
- Returns: The table id
|
- `name`: The name of the table
|
||||||
- Throws:
|
- `token`: The session token of the player
|
||||||
- 400: Missing token, table name or invalid visibility
|
- `visibility`: The visibility of the table (`private` or `public`)
|
||||||
- 401: The session token is invalid
|
|
||||||
|
**Errors**
|
||||||
|
- `400`: Missing token, table name or invalid visibility
|
||||||
|
- `401`: The session token is invalid
|
||||||
|
|
||||||
|
**Response**
|
||||||
|
- `body`: The table id
|
||||||
*/
|
*/
|
||||||
func createTable(_ app: Application) {
|
func createTable(_ app: Application) {
|
||||||
app.post("table", "create", ":visibility", ":name") { request -> String in
|
app.post("table", "create") { request -> String in
|
||||||
guard let visibility = request.parameters.get("visibility"),
|
let tableName = try request.header(.name)
|
||||||
let tableName = request.parameters.get("name"),
|
let token = try request.header(.token)
|
||||||
let token = request.body.string else {
|
let visibility = try request.header(.visibility)
|
||||||
throw Abort(.badRequest) // 400
|
|
||||||
}
|
|
||||||
let isPublic: Bool
|
let isPublic: Bool
|
||||||
if visibility == "private" {
|
if visibility == "private" {
|
||||||
isPublic = false
|
isPublic = false
|
||||||
@ -276,18 +291,19 @@ func createTable(_ app: Application) {
|
|||||||
List the public tables.
|
List the public tables.
|
||||||
|
|
||||||
**Headers**
|
**Headers**
|
||||||
- `token`: The session token of the player, as a string in the request body
|
- `token`: The session token of the player
|
||||||
|
|
||||||
**Possible errors**
|
**Possible errors**
|
||||||
- `400`: Missing token
|
- `400`: Missing token
|
||||||
- `401`: The session token is invalid
|
- `401`: The session token is invalid
|
||||||
- Returns: A JSON object with a list of public tables (id, name, player list)
|
|
||||||
|
**Response**
|
||||||
|
- `body`: A JSON object with a list of public tables (id, name, player list)
|
||||||
*/
|
*/
|
||||||
func getPublicTables(_ app: Application) {
|
func getPublicTables(_ app: Application) {
|
||||||
app.post("tables", "public") { req -> String in
|
app.post("tables", "public") { request -> String in
|
||||||
guard let token = req.body.string else {
|
let token = try request.header(.token)
|
||||||
throw Abort(.badRequest) // 400
|
|
||||||
}
|
|
||||||
guard server.isValid(sessionToken: token) else {
|
guard server.isValid(sessionToken: token) else {
|
||||||
throw Abort(.unauthorized) // 401
|
throw Abort(.unauthorized) // 401
|
||||||
}
|
}
|
||||||
@ -296,24 +312,25 @@ func getPublicTables(_ app: Application) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Join a table.
|
Join a table.
|
||||||
- Parameter table: The table id
|
|
||||||
- Parameter token: The session token of the player, as a string in the request body
|
|
||||||
- Throws:
|
|
||||||
- 400: Missing token
|
|
||||||
- 401: The session token is invalid
|
|
||||||
- 403: The player already sits at another table
|
|
||||||
- 410: The table id doesn't exist
|
|
||||||
- 417: The table is already full and can't be joined
|
|
||||||
- Returns: Nothing
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
**Headers**
|
||||||
|
- `name`: The table id
|
||||||
|
- `token`: The session token of the player
|
||||||
|
|
||||||
|
**Possible errors**
|
||||||
|
- `400`: Missing token
|
||||||
|
- `401`: The session token is invalid
|
||||||
|
- `403`: The player already sits at another table
|
||||||
|
- `410`: The table id doesn't exist
|
||||||
|
- `417`: The table is already full and can't be joined
|
||||||
|
*/
|
||||||
func joinTable(_ app: Application) {
|
func joinTable(_ app: Application) {
|
||||||
app.post("table", "join", ":table") { request -> String in
|
app.post("table", "join") { request -> String in
|
||||||
guard let string = request.parameters.get("table"),
|
let string = try request.header(.name)
|
||||||
let table = UUID(uuidString: string),
|
let token = try request.header(.token)
|
||||||
let token = request.body.string else {
|
guard let table = UUID(uuidString: string) else {
|
||||||
throw Abort(.badRequest)
|
throw Abort(.badRequest)
|
||||||
}
|
}
|
||||||
let result = try await server.join(tableId: table, playerToken: token, in: request.db)
|
let result = try await server.join(tableId: table, playerToken: token, in: request.db)
|
||||||
@ -321,30 +338,42 @@ func joinTable(_ app: Application) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Leave the current table.
|
Leave the current table.
|
||||||
- Parameter token: The session token of the player, as a string in the request body
|
|
||||||
- Throws:
|
**Headers**
|
||||||
- 400: Missing token
|
- `token`: The session token of the player
|
||||||
- 401: The session token is invalid
|
|
||||||
- Returns: Nothing
|
**Possible errors**
|
||||||
|
- `400`: Missing token
|
||||||
|
- `401`: The session token is invalid
|
||||||
*/
|
*/
|
||||||
func leaveTable(_ app: Application) {
|
func leaveTable(_ app: Application) {
|
||||||
app.post("table", "leave") { request -> HTTPResponseStatus in
|
app.post("table", "leave") { request -> HTTPResponseStatus in
|
||||||
guard let token = request.body.string else {
|
let token = try request.header(.token)
|
||||||
throw Abort(.badRequest)
|
|
||||||
}
|
|
||||||
try await server.leaveTable(playerToken: token, in: request.db)
|
try await server.leaveTable(playerToken: token, in: request.db)
|
||||||
return .ok
|
return .ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Perform an action, either a game selection or a player action.
|
||||||
|
|
||||||
|
**Headers**
|
||||||
|
- `token`: The session token of the player
|
||||||
|
- `action`: The action to perform
|
||||||
|
|
||||||
|
**Possible errors**
|
||||||
|
- `400`: Missing token or action
|
||||||
|
- `401`: The session token is invalid
|
||||||
|
- `412`: The action is not allowed
|
||||||
|
*/
|
||||||
func performActionForPlayer(_ app: Application) {
|
func performActionForPlayer(_ app: Application) {
|
||||||
app.post("player", "action", ":action") { req -> String in
|
app.post("player", "action") { request -> HTTPResponseStatus in
|
||||||
guard let token = req.body.string,
|
let token = try request.header(.token)
|
||||||
let actionString = req.parameters.get("action") else {
|
let actionString = try request.header(.action)
|
||||||
throw Abort(.badRequest)
|
|
||||||
}
|
|
||||||
let result: PlayerActionResult
|
let result: PlayerActionResult
|
||||||
if let action = PlayerAction(rawValue: actionString) {
|
if let action = PlayerAction(rawValue: actionString) {
|
||||||
result = server.performAction(playerToken: token, action: action)
|
result = server.performAction(playerToken: token, action: action)
|
||||||
@ -355,41 +384,54 @@ func performActionForPlayer(_ app: Application) {
|
|||||||
}
|
}
|
||||||
switch result {
|
switch result {
|
||||||
case .success:
|
case .success:
|
||||||
return ""
|
return .ok
|
||||||
case .invalidToken:
|
case .invalidToken:
|
||||||
throw Abort(.unauthorized) // 401
|
return .unauthorized // 401
|
||||||
case .noTableJoined:
|
case .noTableJoined:
|
||||||
throw Abort(.preconditionFailed) // 412
|
return .preconditionFailed // 412
|
||||||
case .tableNotFull:
|
case .tableNotFull:
|
||||||
throw Abort(.preconditionFailed) // 412
|
return .preconditionFailed // 412
|
||||||
case .tableStateInvalid:
|
case .tableStateInvalid:
|
||||||
throw Abort(.preconditionFailed) // 412
|
return .preconditionFailed // 412
|
||||||
case .invalidCard:
|
case .invalidCard:
|
||||||
throw Abort(.preconditionFailed) // 412
|
return .preconditionFailed // 412
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Play a card as the active player.
|
||||||
|
|
||||||
|
**Headers**
|
||||||
|
- `token`: The session token of the player
|
||||||
|
- `action`: The id of the card to play
|
||||||
|
|
||||||
|
**Possible errors**
|
||||||
|
- `400`: Missing token or card id
|
||||||
|
- `401`: The session token is invalid
|
||||||
|
- `412`: The action is not allowed
|
||||||
|
*/
|
||||||
func playCard(_ app: Application) {
|
func playCard(_ app: Application) {
|
||||||
app.post("player", "card", ":card") { req -> String in
|
app.post("player", "card") { request -> HTTPResponseStatus in
|
||||||
guard let token = req.body.string,
|
let token = try request.header(.token)
|
||||||
let cardId = req.parameters.get("card"),
|
let cardId = try request.header(.action)
|
||||||
let card = Card(id: cardId) else {
|
guard let card = Card(id: cardId) else {
|
||||||
throw Abort(.badRequest)
|
throw Abort(.badRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch server.play(card: card, playerToken: token) {
|
switch server.play(card: card, playerToken: token) {
|
||||||
case .success:
|
case .success:
|
||||||
return ""
|
return .ok
|
||||||
case .invalidToken:
|
case .invalidToken:
|
||||||
throw Abort(.unauthorized) // 401
|
return .unauthorized // 401
|
||||||
case .noTableJoined:
|
case .noTableJoined:
|
||||||
throw Abort(.preconditionFailed) // 412
|
return .preconditionFailed // 412
|
||||||
case .tableStateInvalid:
|
case .tableStateInvalid:
|
||||||
throw Abort(.preconditionFailed) // 412
|
return .preconditionFailed // 412
|
||||||
case .invalidCard:
|
case .invalidCard:
|
||||||
throw Abort(.preconditionFailed) // 412
|
return .preconditionFailed // 412
|
||||||
case .tableNotFull:
|
case .tableNotFull:
|
||||||
throw Abort(.preconditionFailed) // 412
|
return .preconditionFailed // 412
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user