diff --git a/.gitignore b/.gitignore index 831c9d5..6b3d03b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ server/build server/.gradle server/userDatabase -server/messageHistory +server/chatHistory client-cli/build client-cli/.gradle client-cli/.chookpen.profile diff --git a/server/build.gradle.kts b/server/build.gradle.kts index 6b36b3a..d78af3f 100644 --- a/server/build.gradle.kts +++ b/server/build.gradle.kts @@ -24,6 +24,8 @@ tasks.withType { dependencies { testImplementation(kotlin("test")) + implementation("io.javalin:javalin:6.3.0") + implementation("org.slf4j:slf4j-simple:2.0.16") } tasks.test { diff --git a/server/src/main/kotlin/Main.kt b/server/src/main/kotlin/Main.kt index 9604d96..ff3480f 100644 --- a/server/src/main/kotlin/Main.kt +++ b/server/src/main/kotlin/Main.kt @@ -1,5 +1,7 @@ package xyz.maxwellj.chookpen +import io.javalin.Javalin + import com.sun.net.httpserver.HttpExchange import com.sun.net.httpserver.HttpHandler import com.sun.net.httpserver.HttpServer @@ -9,211 +11,298 @@ import java.io.File import java.io.BufferedReader fun main(args: Array) { - // Crete a server and start listening for arguments - val server = HttpServer.create(InetSocketAddress(8000), 0) - server.createContext("/test", ServerTester()) - server.createContext("/api", ApiHandler()) - server.createContext("/api/createAccount", CreateAccount()) - server.executor = null - server.start() - println("Server has started on port 8000") + val app = Javalin.create() + .get("/") { ctx -> ctx.result("dingus") } + .get("/api/send/{content}") { ctx -> ctx.result(handleSentMessage(ctx.pathParam("content")))} + .get("/api/createaccount/{content}") { ctx -> ctx.result(createAccount(ctx.pathParam("content")))} + .get("/api/syncmessages/{content}") { ctx -> ctx.result(syncMessages(ctx.pathParam("content")))} + .get("/api/authkey/{content}") { ctx -> ctx.result(authKey(ctx.pathParam("content")))} + .start(7070) } -class ServerTester : HttpHandler { - override fun handle(t: HttpExchange) { - val response = "Testing, testing, 1, 2, 3... Somehow this is going to make it to production one day" - t.sendResponseHeaders(200, response.length.toLong()) - val os = t.responseBody - os.write(response.toByteArray()) - println("Test request recieved!") - os.close() - } -} - -class ApiHandler : HttpHandler { - override fun handle(t: HttpExchange) { - println("Request recieved...") - // Get the data - val path = t.requestURI.path - val inputData = path.substringAfter("/api/") - println("API request recieved: $inputData") - - // Parse data sent to the server by client - var username = "" - var token = "" - var message = "" - var dataType = "" - var isParsingData = 0 - for (char in inputData) { - val character = char - if (character == ':') { - isParsingData = 1 - } else if (isParsingData == 1) { - if (character == '}') { - isParsingData = 0 - dataType = "" - } else if (character != '{') { - if (dataType == "username") { - username += character - } else if (dataType == "token") { - token += character - } else if (dataType == "message") { - message += character - } +fun handleSentMessage(inputData: String): String { + println("API request recieved: $inputData") + // Parse data sent to the server by client + var username = "" + var token = "" + var message = "" + var dataType = "" + var isParsingData = 0 + for (char in inputData) { + val character = char + if (character == ':') { + isParsingData = 1 + } else if (isParsingData == 1) { + if (character == '}') { + isParsingData = 0 + dataType = "" + } else if (character != '{') { + if (dataType == "username") { + username += character + } else if (dataType == "token") { + token += character + } else if (dataType == "message") { + message += character } - } else { - dataType += character } + } else { + dataType += character } - val userDatabaseParser = BufferedReader(File("userDatabase").reader()) - var lineNumber = 1 - var userLine = "" + } + val userDatabaseParser = BufferedReader(File("userDatabase").reader()) + var lineNumber = 1 + var userLine = "" - // Search the user database to find required information about the user - userDatabaseParser.forEachLine { line -> - if (line.contains(username)) { - userLine = line - } - lineNumber++ + // Search the user database to find required information about the user + userDatabaseParser.forEachLine { line -> + if (line.contains(username)) { + userLine = line } - userDatabaseParser.close() + lineNumber++ + } + userDatabaseParser.close() - if (userLine == "") { - val response = "That account does not exist on this server." - t.sendResponseHeaders(403, response.length.toLong()) - val os = t.responseBody - os.write(response.toByteArray()) - os.close() - return - } + if (userLine == "") { + return("That account does not exist on this server.") + } - var usernameInDatabase = "" - var tokenInDatabase = "" - var currentStage = 0 - for (char in userLine) { - if (char == ':') { - currentStage ++ - } - if (currentStage == 0) { - usernameInDatabase += char - } else if (currentStage == 1) { - tokenInDatabase += char - } + var usernameInDatabase = "" + var tokenInDatabase = "" + var currentStage = 0 + for (char in userLine) { + if (char == ':') { + currentStage ++ } - tokenInDatabase = tokenInDatabase.replace(":", "") - if (token != tokenInDatabase) { - val response = "Invalid token! Please try putting in your password right" - t.sendResponseHeaders(403, response.length.toLong()) - val os = t.responseBody - os.write(response.toByteArray()) - os.close() - return + if (currentStage == 0) { + usernameInDatabase += char + } else if (currentStage == 1) { + tokenInDatabase += char } - // Make the message to respond to the client - val chatHistoryView = File("chatHistory") - var fullMessage = "" - if (message != "") { - fullMessage = "${chatHistoryView.readText()}$username: $message" - // Add the client's message to the chat history - val chatHistory = File("chatHistory") - chatHistory.appendText("$username: $message ${System.lineSeparator()}") - message = "" - } else { - fullMessage = "${chatHistoryView.readText()}" - } - val response = if (inputData.isNotEmpty()) { - fullMessage - } else { - "No data provided" - } - - // Send the message to the client - t.sendResponseHeaders(200, response.length.toLong()) - val os = t.responseBody - os.write(response.toByteArray()) - println("API request handled: $inputData") - os.close() - + } + tokenInDatabase = tokenInDatabase.replace(":", "") + if (token != tokenInDatabase) { + return("Invalid token! Please try putting in your password right") + } + // Make the message to respond to the client + val chatHistoryView = File("chatHistory") + var fullMessage = "" + if (message != "") { + fullMessage = "${chatHistoryView.readText()}$username: $message" + // Add the client's message to the chat history + val chatHistory = File("chatHistory") + chatHistory.appendText("$username: $message ${System.lineSeparator()}") + message = "" + return("Success") + } else { + return("No data provided") } } -class CreateAccount : HttpHandler { - override fun handle(t: HttpExchange) { - val path = t.requestURI.path - val inputData = path.substringAfter("/api/createAccount/") - println("Account creation request recieved: $inputData") - - // Parse data sent to the server by client - var username = "" - var token = "" - var message = "" - var dataType = "" - var isParsingData = 0 - for (char in inputData) { - val character = char - if (character == ':') { - isParsingData = 1 - } else if (isParsingData == 1) { - if (character == '}') { - isParsingData = 0 - dataType = "" - } else if (character != '{') { - if (dataType == "username") { - username += character - } else if (dataType == "token") { - token += character - } else if (dataType == "message") { - message += character - } + +fun syncMessages(inputData: String): String { + println("API request recieved: $inputData") + // Parse data sent to the server by client + var username = "" + var token = "" + var dataType = "" + var isParsingData = 0 + for (char in inputData) { + val character = char + if (character == ':') { + isParsingData = 1 + } else if (isParsingData == 1) { + if (character == '}') { + isParsingData = 0 + dataType = "" + } else if (character != '{') { + if (dataType == "username") { + username += character + } else if (dataType == "token") { + token += character } - } else { - dataType += character } + } else { + dataType += character } - val userDatabaseParser = BufferedReader(File("userDatabase").reader()) - var lineNumber = 1 - var userExists = 0 - - // Search the user database to find required information about the user - userDatabaseParser.forEachLine { line -> - if (line.contains(username)) { - val response = "That username already exists on the server! Please choose a different username" - t.sendResponseHeaders(422, response.length.toLong()) - val os = t.responseBody - os.write(response.toByteArray()) - os.close() - userExists = 1 - } - lineNumber++ - } - userDatabaseParser.close() - if (userExists == 1) {return} - println("$username:$token") - - if (username == "") { - val response = "Please input a username" - t.sendResponseHeaders(422, response.length.toLong()) - val os = t.responseBody - os.write(response.toByteArray()) - os.close() - return - } - - if (token == "") { - val response = "Please input a password" - t.sendResponseHeaders(422, response.length.toLong()) - val os = t.responseBody - os.write(response.toByteArray()) - os.close() - return - } - - val userDatabaseFile = File("userDatabase") - userDatabaseFile.appendText("${System.lineSeparator()}$username:$token") - val response = "Creating account was successful!" - t.sendResponseHeaders(200, response.length.toLong()) - val os = t.responseBody - os.write(response.toByteArray()) - println("") - os.close() } + val userDatabaseParser = BufferedReader(File("userDatabase").reader()) + var lineNumber = 1 + var userLine = "" + + // Search the user database to find required information about the user + userDatabaseParser.forEachLine { line -> + if (line.contains(username)) { + userLine = line + } + lineNumber++ + } + userDatabaseParser.close() + + if (userLine == "") { + return("Account not found") + } + + var usernameInDatabase = "" + var tokenInDatabase = "" + var currentStage = 0 + for (char in userLine) { + if (char == ':') { + currentStage ++ + } + if (currentStage == 0) { + usernameInDatabase += char + } else if (currentStage == 1) { + tokenInDatabase += char + } + } + tokenInDatabase = tokenInDatabase.replace(":", "") + if (token != tokenInDatabase) { + return("Invalid token") + } + // Send back message history + val chatHistoryView = File("chatHistory") + return(chatHistoryView.readText()) } + +fun createAccount(inputData: String): String { + println("Account creation request recieved: $inputData") + // Parse data sent to the server by client + var username = "" + var token = "" + var message = "" + var dataType = "" + var isParsingData = 0 + for (char in inputData) { + val character = char + if (character == ':') { + isParsingData = 1 + } else if (isParsingData == 1) { + if (character == '}') { + isParsingData = 0 + dataType = "" + } else if (character != '{') { + if (dataType == "username") { + username += character + } else if (dataType == "token") { + token += character + } else if (dataType == "message") { + message += character + } + } + } else { + dataType += character + } + } + val userDatabaseParser = BufferedReader(File("userDatabase").reader()) + var lineNumber = 1 + var userExists = 0 + + // Search the user database to find required information about the user + var response = "" + userDatabaseParser.forEachLine { line -> + if (line.contains(username)) { + response = "Username already exists" + } + lineNumber++ + } + if (response != "") { + return(response) + } + userDatabaseParser.close() + if (username == "") { + return("No username") + } + + if (token == "") { + return("No token") + } + + val userDatabaseFile = File("userDatabase") + userDatabaseFile.appendText("${System.lineSeparator()}$username:$token") + return("Success") +} +fun authKey(inputData: String): String { + println("API request recieved: $inputData") + + // Parse data sent to the server by client + var username = "" + var token = "" + var authKey = "" + var dataType = "" + var isParsingData = 0 + for (char in inputData) { + val character = char + if (character == ':') { + isParsingData = 1 + } else if (isParsingData == 1) { + if (character == '}') { + isParsingData = 0 + dataType = "" + } else if (character != '{') { + if (dataType == "username") { + username += character + } else if (dataType == "token") { + token += character + } else if (dataType == "authkey") { + authKey += character + } + } + } else { + dataType += character + } + } + val userDatabaseParser = BufferedReader(File("userDatabase").reader()) + var lineNumber = 1 + var userLine = "" + + // Search the user database to find required information about the user + userDatabaseParser.forEachLine { line -> + if (line.contains(username)) { + userLine = line + } + lineNumber++ + } + userDatabaseParser.close() + + if (userLine == "") { + return("Account not found") + } + + var usernameInDatabase = "" + var tokenInDatabase = "" + var currentStage = 0 + for (char in userLine) { + if (char == ':') { + currentStage ++ + } + if (currentStage == 0) { + usernameInDatabase += char + } else if (currentStage == 1) { + tokenInDatabase += char + } + } + tokenInDatabase = tokenInDatabase.replace(":", "") + if (token != tokenInDatabase) { + return("Invalid token") + } + if (authKey == "") { + return("No auth key provided") + } + // Make the message to respond to the client + val chatHistoryView = File("chatHistory") + var fullMessage = "" + if (authKey != "") { + fullMessage = "encryptionKey:$username:$authKey" + authKey = "" + } else { + fullMessage = "${chatHistoryView.readText()}" + } + val response = if (inputData.isNotEmpty()) { + fullMessage + } else { + "No data provided" + } + + // Send the message to the client + return("Success") +} +