From 539a9cf41fb481770ab27fc77a0afd4591d2ad69 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Thu, 6 Jul 2023 17:50:28 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=AD=E3=82=B0=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E3=83=9A=E3=83=BC=E3=82=B8=E3=81=A7=E3=83=AD=E3=82=B0=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E6=88=90=E5=8A=9F=E6=99=82=E3=81=AB=E3=83=88=E3=83=BC?= =?UTF-8?q?=E3=82=AF=E3=83=B3=E3=82=92=E4=BF=9D=E5=AD=98=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 + .../kotlin/dev/usbharu/hideout/Application.kt | 1 + .../usbharu/hideout/plugins/Compression.kt | 19 ++++++ src/main/resources/openapi/api.yaml | 61 +++++++++++++++++++ src/main/web/App.tsx | 2 +- src/main/web/pages/LoginPage.tsx | 29 ++++++--- 6 files changed, 106 insertions(+), 8 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt diff --git a/build.gradle.kts b/build.gradle.kts index a3b71261..91ca0a6a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -80,12 +80,14 @@ dependencies { implementation("org.xerial:sqlite-jdbc:3.40.1.0") implementation("io.ktor:ktor-server-websockets-jvm:$ktor_version") implementation("io.ktor:ktor-server-cio-jvm:$ktor_version") + implementation("io.ktor:ktor-server-compression:$ktor_version") implementation("ch.qos.logback:logback-classic:$logback_version") implementation("io.insert-koin:koin-core:$koin_version") implementation("io.insert-koin:koin-ktor:$koin_version") implementation("io.insert-koin:koin-logger-slf4j:$koin_version") implementation("io.insert-koin:koin-annotations:1.2.0") + implementation("io.ktor:ktor-server-compression-jvm:2.3.0") ksp("io.insert-koin:koin-ksp-compiler:1.2.0") diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index 5052c79c..4a6d4f68 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -95,6 +95,7 @@ fun Application.parent() { runBlocking { inject().value.init() } + configureCompression() configureHTTP() configureStaticRouting() configureMonitoring() diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt new file mode 100644 index 00000000..e13fa4c9 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt @@ -0,0 +1,19 @@ +package dev.usbharu.hideout.plugins + +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.plugins.compression.* + +fun Application.configureCompression() { + install(Compression) { + gzip { + matchContentType(ContentType.Application.JavaScript) + priority = 1.0 + } + deflate { + matchContentType(ContentType.Application.JavaScript) + priority = 10.0 + minimumSize(1024) // condition + } + } +} diff --git a/src/main/resources/openapi/api.yaml b/src/main/resources/openapi/api.yaml index 82f8f3e5..17efe775 100644 --- a/src/main/resources/openapi/api.yaml +++ b/src/main/resources/openapi/api.yaml @@ -230,6 +230,46 @@ paths: items: $ref: "#/components/schemas/UserResponse" + /login: + post: + summary: ログインする + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/UserLogin" + responses: + 200: + description: ログイン成功 + content: + application/json: + schema: + $ref: "#/components/schemas/JwtToken" + + /refresh-token: + post: + summary: 期限切れトークンの再発行をする + responses: + 200: + description: トークンの再発行に成功 + content: + application/json: + schema: + $ref: "#/components/schemas/JwtToken" + + /auth-check: + get: + summary: 認証チェック + responses: + 200: + description: 認証に成功 + content: + text/plain: + schema: + type: string + + components: responses: Unauthorized: @@ -359,6 +399,27 @@ components: sensitive: type: boolean + JwtToken: + type: object + properties: + token: + type: string + refreshToken: + type: string + + RefreshToken: + type: object + properties: + refreshToken: + type: string + + UserLogin: + type: object + properties: + username: + type: string + password: + type: string securitySchemes: BearerAuth: diff --git a/src/main/web/App.tsx b/src/main/web/App.tsx index 7e925695..8114059a 100644 --- a/src/main/web/App.tsx +++ b/src/main/web/App.tsx @@ -10,7 +10,7 @@ import {LoginPage} from "./pages/LoginPage"; export const App: Component = () => { const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)'); const [cookie,setCookie] = createCookieStorage() - const [api,setApi] = createSignal(new DefaultApi(new Configuration({basePath:window.location.origin+"/api/internal/v1/",apiKey:cookie.key as string}))) + const [api,setApi] = createSignal(new DefaultApi(new Configuration({basePath:window.location.origin+"/api/internal/v1",apiKey:cookie.key as string}))) const theme = createTheme({ palette: { mode: prefersDarkMode() ? 'dark' : 'light', diff --git a/src/main/web/pages/LoginPage.tsx b/src/main/web/pages/LoginPage.tsx index d5ccc4f1..a2d1b1ff 100644 --- a/src/main/web/pages/LoginPage.tsx +++ b/src/main/web/pages/LoginPage.tsx @@ -1,9 +1,25 @@ import {Button, Card, CardContent, CardHeader, Modal, Stack, TextField} from "@suid/material"; import {Component, createSignal} from "solid-js"; +import {createCookieStorage} from "@solid-primitives/storage"; +import {useApi} from "../lib/ApiProvider"; -export const LoginPage:Component = () => { - const [username,setUsername] = createSignal("") - const [password,setPassword] = createSignal("") +export const LoginPage: Component = () => { + const [username, setUsername] = createSignal("") + const [password, setPassword] = createSignal("") + + const [cookie, setCookie] = createCookieStorage(); + + const api = useApi(); + + const onSubmit: () => void = () => { + api().loginPost({password: password(), username: username()}).then(value => { + setCookie("token", value.token); + setCookie("refresh-token", value.refreshToken) + }).catch(reason => { + console.log(reason); + setPassword("") + }) + } return ( @@ -15,7 +31,7 @@ export const LoginPage:Component = () => { setUsername(event.target.value)} + onChange={(event) => setUsername(event.target.value)} label="Username" type="text" autoComplete="username" @@ -23,14 +39,13 @@ export const LoginPage:Component = () => { /> setPassword(event.target.value)} + onChange={(event) => setPassword(event.target.value)} label="Password" type="password" autoComplete="current-password" variant="standard" /> - +