Change data-mutating endpoints from GET to POST
authorTheSaminator <TheSaminator@users.noreply.github.com>
Mon, 14 Feb 2022 22:26:14 +0000 (17:26 -0500)
committerTheSaminator <TheSaminator@users.noreply.github.com>
Mon, 14 Feb 2022 22:26:14 +0000 (17:26 -0500)
src/jsMain/kotlin/starshipfights/game/client_matchmaking.kt
src/jvmMain/kotlin/starshipfights/auth/providers.kt
src/jvmMain/kotlin/starshipfights/info/html_utils.kt [new file with mode: 0644]
src/jvmMain/kotlin/starshipfights/info/view_nav.kt
src/jvmMain/kotlin/starshipfights/info/views_user.kt
src/jvmMain/resources/static/init.js

index 9c30999013e0dc15d75a3e810df181cc044c7e16..a376af0d071f155091370ed673309d7e3734e975 100644 (file)
@@ -11,9 +11,10 @@ import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.launch
 import kotlinx.html.FormEncType
 import kotlinx.html.FormMethod
-import kotlinx.html.dom.create
+import kotlinx.html.dom.append
 import kotlinx.html.hiddenInput
 import kotlinx.html.js.form
+import kotlinx.html.style
 
 suspend fun setupBackground() {
        val camera = PerspectiveCamera(69, window.aspectRatio, 0.01, 1_000)
@@ -44,7 +45,8 @@ suspend fun setupBackground() {
 }
 
 private suspend fun enterGame(connectToken: String): Nothing {
-       document.create.form(action = "/play", method = FormMethod.post, encType = FormEncType.applicationXWwwFormUrlEncoded) {
+       document.body!!.append.form(action = "/play", method = FormMethod.post, encType = FormEncType.applicationXWwwFormUrlEncoded) {
+               style = "display:none"
                hiddenInput {
                        name = "token"
                        value = connectToken
index e675c2a9822bda80d62e50d2a389797af5c49408..eac623730a1999e2c4dff232a3b17b5762b8368c 100644 (file)
@@ -280,7 +280,7 @@ interface AuthProvider {
                                        redirect("/me")
                                }
                                
-                               get("/logout") {
+                               post("/logout") {
                                        call.getUserSession()?.let { sess ->
                                                launch {
                                                        val newTime = Instant.now().minusMillis(100)
@@ -292,7 +292,7 @@ interface AuthProvider {
                                        redirect("/")
                                }
                                
-                               get("/logout/{id}") {
+                               post("/logout/{id}") {
                                        val id = Id<UserSession>(call.parameters.getOrFail("id"))
                                        call.getUserSession()?.let { sess ->
                                                launch {
@@ -304,7 +304,7 @@ interface AuthProvider {
                                        redirect("/me/manage")
                                }
                                
-                               get("/logout-all") {
+                               post("/logout-all") {
                                        call.getUserSession()?.let { sess ->
                                                launch {
                                                        val newTime = Instant.now().minusMillis(100)
@@ -315,7 +315,7 @@ interface AuthProvider {
                                        redirect("/me/manage")
                                }
                                
-                               get("/clear-expired/{id}") {
+                               post("/clear-expired/{id}") {
                                        val id = Id<UserSession>(call.parameters.getOrFail("id"))
                                        call.getUserSession()?.let { sess ->
                                                launch {
@@ -327,7 +327,7 @@ interface AuthProvider {
                                        redirect("/me/manage")
                                }
                                
-                               get("/clear-all-expired") {
+                               post("/clear-all-expired") {
                                        call.getUserSession()?.let { sess ->
                                                launch {
                                                        val now = Instant.now()
diff --git a/src/jvmMain/kotlin/starshipfights/info/html_utils.kt b/src/jvmMain/kotlin/starshipfights/info/html_utils.kt
new file mode 100644 (file)
index 0000000..aefdd94
--- /dev/null
@@ -0,0 +1,12 @@
+package starshipfights.info
+
+import kotlinx.html.A
+
+var A.method: String?
+       get() = attributes["data-method"]
+       set(value) {
+               if (value != null)
+                       attributes["data-method"] = value
+               else
+                       attributes.remove("data-method")
+       }
index 7cf3f67d8067a3546947165db3829132e8e24b96..21c3425e7147bbde6475a33cb096f0ecf5e2511e 100644 (file)
@@ -21,9 +21,11 @@ data class NavHead(val label: String) : NavItem() {
        }
 }
 
-data class NavLink(val to: String, val text: String) : NavItem() {
+data class NavLink(val to: String, val text: String, val isPost: Boolean = false) : NavItem() {
        override fun DIV.display() {
                a(href = to) {
+                       if (isPost)
+                               method = "post"
                        +text
                }
        }
@@ -43,7 +45,7 @@ suspend fun ApplicationCall.standardNavBar(): List<NavItem> = listOf(
                NavLink("/me", user.profileName),
                NavLink("/me/manage", "User Preferences"),
                NavLink("/lobby", "Enter Game Lobby"),
-               NavLink("/logout", "Log Out"),
+               NavLink("/logout", "Log Out", isPost = true),
        )
 } + listOf(
        NavHead("External Information"),
index 2fdede0a135a15eab4b8f180de723fb5556b7467..2e7cf08b9f8100dd1914aa6187fb797cd287a82b 100644 (file)
@@ -240,14 +240,20 @@ suspend fun ApplicationCall.manageUserPage(): HTML.() -> Unit {
                                                                +"Current Session"
                                                                br
                                                        }
-                                                       a(href = "/logout/${session.id}") { +"Logout" }
+                                                       a(href = "/logout/${session.id}") {
+                                                               method = "post"
+                                                               +"Logout"
+                                                       }
                                                }
                                        }
                                }
                                tr {
                                        td {
                                                colSpan = if (currentUser.logIpAddresses) "3" else "2"
-                                               a(href = "/logout-all") { +"Logout All" }
+                                               a(href = "/logout-all") {
+                                                       method = "post"
+                                                       +"Logout All"
+                                               }
                                        }
                                }
                                expiredSessions.forEach { session ->
@@ -267,7 +273,10 @@ suspend fun ApplicationCall.manageUserPage(): HTML.() -> Unit {
                                                                +session.expiration.toEpochMilli().toString()
                                                        }
                                                        br
-                                                       a(href = "/clear-expired/${session.id}") { +"Clear" }
+                                                       a(href = "/clear-expired/${session.id}") {
+                                                               method = "post"
+                                                               +"Clear"
+                                                       }
                                                }
                                        }
                                }
@@ -275,7 +284,10 @@ suspend fun ApplicationCall.manageUserPage(): HTML.() -> Unit {
                                        tr {
                                                td {
                                                        colSpan = if (currentUser.logIpAddresses) "3" else "2"
-                                                       a(href = "/clear-all-expired") { +"Clear All Expired Sessions" }
+                                                       a(href = "/clear-all-expired") {
+                                                               method = "post"
+                                                               +"Clear All Expired Sessions"
+                                                       }
                                                }
                                        }
                        }
@@ -673,9 +685,7 @@ suspend fun ApplicationCall.manageAdmiralPage(): HTML.() -> Unit {
                                                        +admiral.faction.currencyName
                                                        +"s"
                                                        br
-                                                       a(href = "/admiral/${admiralId}/buy/${st.toUrlSlug()}") {
-                                                               +"Buy"
-                                                       }
+                                                       a(href = "/admiral/${admiralId}/buy/${st.toUrlSlug()}") { +"Buy" }
                                                }
                                        }
                                }
index 2630a198bd01eff68b9fd27c02a4cdbcb31b4406..9609d14ccfc2677d7ce240e3a1f1344e12224ad3 100644 (file)
@@ -1,4 +1,5 @@
 window.addEventListener("load", function () {
+       // Load and render OBJ meshes
        if (!window.sfShipMeshViewer) return;
 
        const canvases = document.getElementsByTagName("canvas");
@@ -67,6 +68,7 @@ window.addEventListener("load", function () {
 });
 
 window.addEventListener("load", function () {
+       // Localize dates and times
        const moments = document.getElementsByClassName("moment");
        for (let moment of moments) {
                let date = new Date(Number(moment.innerHTML.trim()));
@@ -76,6 +78,7 @@ window.addEventListener("load", function () {
 });
 
 window.addEventListener("load", function () {
+       // Generate random admiral names
        if (!window.sfAdmiralNameGen) return;
 
        const nameBox = document.getElementById("name");
@@ -93,6 +96,7 @@ window.addEventListener("load", function () {
 });
 
 window.addEventListener("load", function () {
+       // Indicate maximum and used length of <textarea>s
        const textareas = document.getElementsByTagName("textarea");
        for (let textarea of textareas) {
                if (!textarea.hasAttribute("maxLength")) continue;
@@ -119,3 +123,24 @@ window.addEventListener("load", function () {
                updateIndicator();
        }
 });
+
+window.addEventListener("load", function () {
+       // Allow POSTing with <a>s
+       const anchors = document.getElementsByTagName("a");
+       for (let anchor of anchors) {
+               const method = anchor.getAttribute("data-method");
+               if (method == null) continue;
+
+               anchor.onclick = e => {
+                       e.preventDefault();
+
+                       let form = document.createElement("form");
+                       form.style.display = "none";
+                       form.action = anchor.href;
+                       form.method = method;
+
+                       document.body.append(form);
+                       form.submit();
+               };
+       }
+});