From ea6aad506d1d6776c63014ea7e9586e67399b84f Mon Sep 17 00:00:00 2001 From: usbharu Date: Thu, 3 Aug 2023 11:16:58 +0900 Subject: [PATCH] Revert "Feature/web UI" --- .gitignore | 2 - build.gradle.kts | 2 - openapitools.json | 22 -- .../kotlin/dev/usbharu/hideout/Application.kt | 10 +- .../usbharu/hideout/domain/model/ap/Note.kt | 2 - .../domain/model/ap/ObjectDeserializer.kt | 1 - .../domain/model/hideout/dto/PostResponse.kt | 31 --- .../domain/model/hideout/entity/User.kt | 4 +- .../usbharu/hideout/plugins/Compression.kt | 19 -- .../dev/usbharu/hideout/plugins/Routing.kt | 12 +- .../dev/usbharu/hideout/plugins/Security.kt | 39 ++- .../hideout/repository/PostRepositoryImpl.kt | 4 +- .../hideout/routing/api/internal/v1/Auth.kt | 48 ---- .../hideout/routing/api/internal/v1/Users.kt | 16 +- .../hideout/service/api/IPostApiService.kt | 10 +- .../hideout/service/api/PostApiServiceImpl.kt | 65 ++--- .../kjob/exposed/ExposedJobRepository.kt | 1 - src/main/resources/openapi/api.yaml | 143 ++--------- src/main/web/App.tsx | 88 ++++--- src/main/web/atoms/Avatar.tsx | 8 - src/main/web/atoms/SidebarButton.tsx | 14 -- src/main/web/lib/ApiProvider.tsx | 8 - src/main/web/lib/ApiWrapper.ts | 16 -- .../web/molecules/ShareScopeIndicator.tsx | 29 --- src/main/web/organisms/Post.tsx | 45 ---- src/main/web/organisms/PostForm.tsx | 43 ---- src/main/web/pages/LoginPage.tsx | 58 ----- src/main/web/pages/TopPage.tsx | 24 -- src/main/web/templates/MainPage.tsx | 20 -- src/main/web/templates/PostList.tsx | 14 -- src/main/web/templates/Sidebar.tsx | 13 - .../usbharu/hideout/plugins/SecurityKtTest.kt | 82 ++----- .../routing/api/internal/v1/PostsTest.kt | 228 +++++------------- .../routing/api/internal/v1/UsersTest.kt | 26 +- ...ActivityPubReceiveFollowServiceImplTest.kt | 23 +- vite.config.ts | 13 +- 36 files changed, 261 insertions(+), 922 deletions(-) delete mode 100644 openapitools.json delete mode 100644 src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/PostResponse.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt delete mode 100644 src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Auth.kt delete mode 100644 src/main/web/atoms/Avatar.tsx delete mode 100644 src/main/web/atoms/SidebarButton.tsx delete mode 100644 src/main/web/lib/ApiProvider.tsx delete mode 100644 src/main/web/lib/ApiWrapper.ts delete mode 100644 src/main/web/molecules/ShareScopeIndicator.tsx delete mode 100644 src/main/web/organisms/Post.tsx delete mode 100644 src/main/web/organisms/PostForm.tsx delete mode 100644 src/main/web/pages/LoginPage.tsx delete mode 100644 src/main/web/pages/TopPage.tsx delete mode 100644 src/main/web/templates/MainPage.tsx delete mode 100644 src/main/web/templates/PostList.tsx delete mode 100644 src/main/web/templates/Sidebar.tsx diff --git a/.gitignore b/.gitignore index 2165d593..635e4370 100644 --- a/.gitignore +++ b/.gitignore @@ -37,5 +37,3 @@ out/ *.db /src/main/resources/static/ /node_modules/ -/src/main/web/generated/ -/stats.html diff --git a/build.gradle.kts b/build.gradle.kts index 91ca0a6a..a3b71261 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -80,14 +80,12 @@ 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/openapitools.json b/openapitools.json deleted file mode 100644 index a43405c3..00000000 --- a/openapitools.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", - "spaces": 2, - "generator-cli": { - "version": "6.6.0", - "generators": { - "v3.0": { - "generatorName": "typescript-fetch", - "output": "src/main/web/generated", - "glob": "src/main/resources/openapi/api.yaml", - "additionalProperties": { - "modelPropertyNaming": "camelCase", - "supportsES6": true, - "withInterfaces": true, - "typescriptThreePlus": true, - "useSingleRequestParameter": false, - "prependFormOrBodyParameters": true - } - } - } - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index a80d3399..5052c79c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -95,15 +95,17 @@ fun Application.parent() { runBlocking { inject().value.init() } - configureCompression() configureHTTP() configureStaticRouting() configureMonitoring() configureSerialization() register(inject().value) configureSecurity( + inject().value, + inject().value, + inject().value, + inject().value, inject().value, - inject().value ) configureRouting( httpSignatureVerifyService = inject().value, @@ -112,10 +114,6 @@ fun Application.parent() { activityPubUserService = inject().value, postService = inject().value, userApiService = inject().value, - userAuthService = inject().value, - userRepository = inject().value, - jwtService = inject().value, - metaService = inject().value ) } diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt index 21c2f25c..8425fc79 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/Note.kt @@ -10,8 +10,6 @@ open class Note : Object { var inReplyTo: String? = null protected constructor() : super() - - @Suppress("LongParameterList") constructor( type: List = emptyList(), name: String, diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/ObjectDeserializer.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/ObjectDeserializer.kt index 6656ee14..ba2f9868 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/ObjectDeserializer.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/ap/ObjectDeserializer.kt @@ -7,7 +7,6 @@ import com.fasterxml.jackson.databind.JsonNode import dev.usbharu.hideout.service.activitypub.ExtendedActivityVocabulary class ObjectDeserializer : JsonDeserializer() { - @Suppress("LongMethod") override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): Object { requireNotNull(p) val treeNode: JsonNode = requireNotNull(p.codec?.readTree(p)) diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/PostResponse.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/PostResponse.kt deleted file mode 100644 index c6845da9..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/dto/PostResponse.kt +++ /dev/null @@ -1,31 +0,0 @@ -package dev.usbharu.hideout.domain.model.hideout.dto - -import dev.usbharu.hideout.domain.model.hideout.entity.Post -import dev.usbharu.hideout.domain.model.hideout.entity.User -import dev.usbharu.hideout.domain.model.hideout.entity.Visibility - -data class PostResponse( - val id: Long, - val user: UserResponse, - val overview: String? = null, - val text: String? = null, - val createdAt: Long, - val visibility: Visibility, - val url: String, - val sensitive: Boolean = false, -) { - companion object { - fun from(post: Post, user: User): PostResponse { - return PostResponse( - id = post.id, - user = UserResponse.from(user), - overview = post.overview, - text = post.text, - createdAt = post.createdAt, - visibility = post.visibility, - url = post.url, - sensitive = post.sensitive - ) - } - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt index 6754df4f..45af9cc2 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/hideout/entity/User.kt @@ -18,7 +18,7 @@ data class User( ) { override fun toString(): String { return "User(id=$id, name='$name', domain='$domain', screenName='$screenName', description='$description'," + - " password=****, inbox='$inbox', outbox='$outbox', url='$url', publicKey='$publicKey'," + - " privateKey=****, createdAt=$createdAt)" + " password=****, inbox='$inbox', outbox='$outbox', url='$url', publicKey='$publicKey'," + + " privateKey=****, createdAt=$createdAt)" } } diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt deleted file mode 100644 index e13fa4c9..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Compression.kt +++ /dev/null @@ -1,19 +0,0 @@ -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/kotlin/dev/usbharu/hideout/plugins/Routing.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt index 501b4e43..5931ad53 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Routing.kt @@ -1,10 +1,8 @@ package dev.usbharu.hideout.plugins -import dev.usbharu.hideout.repository.IUserRepository import dev.usbharu.hideout.routing.activitypub.inbox import dev.usbharu.hideout.routing.activitypub.outbox import dev.usbharu.hideout.routing.activitypub.usersAP -import dev.usbharu.hideout.routing.api.internal.v1.auth import dev.usbharu.hideout.routing.api.internal.v1.posts import dev.usbharu.hideout.routing.api.internal.v1.users import dev.usbharu.hideout.routing.wellknown.webfinger @@ -13,9 +11,6 @@ import dev.usbharu.hideout.service.activitypub.ActivityPubUserService import dev.usbharu.hideout.service.api.IPostApiService import dev.usbharu.hideout.service.api.IUserApiService import dev.usbharu.hideout.service.auth.HttpSignatureVerifyService -import dev.usbharu.hideout.service.auth.IJwtService -import dev.usbharu.hideout.service.core.IMetaService -import dev.usbharu.hideout.service.user.IUserAuthService import dev.usbharu.hideout.service.user.IUserService import io.ktor.server.application.* import io.ktor.server.plugins.autohead.* @@ -28,11 +23,7 @@ fun Application.configureRouting( userService: IUserService, activityPubUserService: ActivityPubUserService, postService: IPostApiService, - userApiService: IUserApiService, - userAuthService: IUserAuthService, - userRepository: IUserRepository, - jwtService: IJwtService, - metaService: IMetaService + userApiService: IUserApiService ) { install(AutoHeadResponse) routing { @@ -43,7 +34,6 @@ fun Application.configureRouting( route("/api/internal/v1") { posts(postService) users(userService, userApiService) - auth(userAuthService, userRepository, jwtService) } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt b/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt index 84966882..a98eee18 100644 --- a/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt +++ b/src/main/kotlin/dev/usbharu/hideout/plugins/Security.kt @@ -2,12 +2,19 @@ package dev.usbharu.hideout.plugins import com.auth0.jwk.JwkProvider import dev.usbharu.hideout.config.Config +import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken +import dev.usbharu.hideout.domain.model.hideout.form.UserLogin +import dev.usbharu.hideout.exception.UserNotFoundException +import dev.usbharu.hideout.repository.IUserRepository +import dev.usbharu.hideout.service.auth.IJwtService import dev.usbharu.hideout.service.core.IMetaService +import dev.usbharu.hideout.service.user.IUserAuthService import dev.usbharu.hideout.util.JsonWebKeyUtil import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.auth.* import io.ktor.server.auth.jwt.* +import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* @@ -15,8 +22,11 @@ const val TOKEN_AUTH = "jwt-auth" @Suppress("MagicNumber") fun Application.configureSecurity( - jwkProvider: JwkProvider, - metaService: IMetaService + userAuthService: IUserAuthService, + metaService: IMetaService, + userRepository: IUserRepository, + jwtService: IJwtService, + jwkProvider: JwkProvider ) { val issuer = Config.configData.url install(Authentication) { @@ -38,6 +48,24 @@ fun Application.configureSecurity( } routing { + post("/login") { + val loginUser = call.receive() + val check = userAuthService.verifyAccount(loginUser.username, loginUser.password) + if (check.not()) { + return@post call.respond(HttpStatusCode.Unauthorized) + } + + val user = userRepository.findByNameAndDomain(loginUser.username, Config.configData.domain) + ?: throw UserNotFoundException("${loginUser.username} was not found.") + + return@post call.respond(jwtService.createToken(user)) + } + + post("/refresh-token") { + val refreshToken = call.receive() + return@post call.respond(jwtService.refreshToken(refreshToken)) + } + get("/.well-known/jwks.json") { //language=JSON val jwt = metaService.getJwtMeta() @@ -46,5 +74,12 @@ fun Application.configureSecurity( text = JsonWebKeyUtil.publicKeyToJwk(jwt.publicKey, jwt.kid.toString()) ) } + authenticate(TOKEN_AUTH) { + get("/auth-check") { + val principal = call.principal() ?: throw IllegalStateException("no principal") + val username = principal.payload.getClaim("uid") + call.respondText("Hello $username") + } + } } } diff --git a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt index 12156818..6360e609 100644 --- a/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/repository/PostRepositoryImpl.kt @@ -88,9 +88,7 @@ class PostRepositoryImpl(database: Database, private val idGenerateService: IdGe limit: Int?, userId: Long? ): List { - return query { - Posts.select { Posts.visibility eq Visibility.PUBLIC.ordinal }.map { it.toPost() } - } + TODO("Not yet implemented") } override suspend fun findByUserNameAndDomain( diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Auth.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Auth.kt deleted file mode 100644 index f185e832..00000000 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Auth.kt +++ /dev/null @@ -1,48 +0,0 @@ -package dev.usbharu.hideout.routing.api.internal.v1 - -import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken -import dev.usbharu.hideout.domain.model.hideout.form.UserLogin -import dev.usbharu.hideout.exception.UserNotFoundException -import dev.usbharu.hideout.plugins.TOKEN_AUTH -import dev.usbharu.hideout.repository.IUserRepository -import dev.usbharu.hideout.service.auth.IJwtService -import dev.usbharu.hideout.service.user.IUserAuthService -import io.ktor.http.* -import io.ktor.server.application.* -import io.ktor.server.auth.* -import io.ktor.server.auth.jwt.* -import io.ktor.server.request.* -import io.ktor.server.response.* -import io.ktor.server.routing.* - -fun Route.auth( - userAuthService: IUserAuthService, - userRepository: IUserRepository, - jwtService: IJwtService -) { - post("/login") { - val loginUser = call.receive() - val check = userAuthService.verifyAccount(loginUser.username, loginUser.password) - if (check.not()) { - return@post call.respond(HttpStatusCode.Unauthorized) - } - - val user = userRepository.findByNameAndDomain(loginUser.username, Config.configData.domain) - ?: throw UserNotFoundException("${loginUser.username} was not found.") - - return@post call.respond(jwtService.createToken(user)) - } - - post("/refresh-token") { - val refreshToken = call.receive() - return@post call.respond(jwtService.refreshToken(refreshToken)) - } - authenticate(TOKEN_AUTH) { - get("/auth-check") { - val principal = call.principal() ?: throw IllegalStateException("no principal") - val username = principal.payload.getClaim("uid") - call.respondText("Hello $username") - } - } -} diff --git a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt index 24a45006..8609e439 100644 --- a/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt +++ b/src/main/kotlin/dev/usbharu/hideout/routing/api/internal/v1/Users.kt @@ -42,11 +42,11 @@ fun Route.users(userService: IUserService, userApiService: IUserApiService) { authenticate(TOKEN_AUTH, optional = true) { get { val userParameter = ( - call.parameters["name"] - ?: throw ParameterNotExistException( - "Parameter(name='userName@domain') does not exist." + call.parameters["name"] + ?: throw ParameterNotExistException( + "Parameter(name='userName@domain') does not exist." + ) ) - ) if (userParameter.toLongOrNull() != null) { return@get call.respond(userApiService.findById(userParameter.toLong())) } else { @@ -92,11 +92,11 @@ fun Route.users(userService: IUserService, userApiService: IUserApiService) { route("/following") { get { val userParameter = ( - call.parameters["name"] - ?: throw ParameterNotExistException( - "Parameter(name='userName@domain') does not exist." + call.parameters["name"] + ?: throw ParameterNotExistException( + "Parameter(name='userName@domain') does not exist." + ) ) - ) if (userParameter.toLongOrNull() != null) { return@get call.respond(userApiService.findFollowings(userParameter.toLong())) } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/IPostApiService.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/IPostApiService.kt index 6aa54403..eb7eb97a 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/IPostApiService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/IPostApiService.kt @@ -1,12 +1,12 @@ package dev.usbharu.hideout.service.api -import dev.usbharu.hideout.domain.model.hideout.dto.PostResponse +import dev.usbharu.hideout.domain.model.hideout.entity.Post import java.time.Instant @Suppress("LongParameterList") interface IPostApiService { - suspend fun createPost(postForm: dev.usbharu.hideout.domain.model.hideout.form.Post, userId: Long): PostResponse - suspend fun getById(id: Long, userId: Long?): PostResponse + suspend fun createPost(postForm: dev.usbharu.hideout.domain.model.hideout.form.Post, userId: Long): Post + suspend fun getById(id: Long, userId: Long?): Post suspend fun getAll( since: Instant? = null, until: Instant? = null, @@ -14,7 +14,7 @@ interface IPostApiService { maxId: Long? = null, limit: Int? = null, userId: Long? = null - ): List + ): List suspend fun getByUser( nameOrId: String, @@ -24,5 +24,5 @@ interface IPostApiService { maxId: Long? = null, limit: Int? = null, userId: Long? = null - ): List + ): List } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiServiceImpl.kt index b8957f87..35e05585 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/api/PostApiServiceImpl.kt @@ -2,16 +2,11 @@ package dev.usbharu.hideout.service.api import dev.usbharu.hideout.config.Config import dev.usbharu.hideout.domain.model.hideout.dto.PostCreateDto -import dev.usbharu.hideout.domain.model.hideout.dto.PostResponse -import dev.usbharu.hideout.repository.* +import dev.usbharu.hideout.domain.model.hideout.entity.Post +import dev.usbharu.hideout.exception.PostNotFoundException +import dev.usbharu.hideout.repository.IPostRepository import dev.usbharu.hideout.service.post.IPostService import dev.usbharu.hideout.util.AcctUtil -import kotlinx.coroutines.Dispatchers -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.innerJoin -import org.jetbrains.exposed.sql.select -import org.jetbrains.exposed.sql.selectAll -import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction import org.koin.core.annotation.Single import java.time.Instant import dev.usbharu.hideout.domain.model.hideout.form.Post as FormPost @@ -19,11 +14,10 @@ import dev.usbharu.hideout.domain.model.hideout.form.Post as FormPost @Single class PostApiServiceImpl( private val postService: IPostService, - private val postRepository: IPostRepository, - private val userRepository: IUserRepository + private val postRepository: IPostRepository ) : IPostApiService { - override suspend fun createPost(postForm: FormPost, userId: Long): PostResponse { - val createdPost = postService.createLocal( + override suspend fun createPost(postForm: FormPost, userId: Long): Post { + return postService.createLocal( PostCreateDto( text = postForm.text, overview = postForm.overview, @@ -33,20 +27,11 @@ class PostApiServiceImpl( userId = userId ) ) - val creator = userRepository.findById(userId) - return PostResponse.from(createdPost, creator!!) } - @Suppress("InjectDispatcher") - suspend fun query(block: suspend () -> T): T = - newSuspendedTransaction(Dispatchers.IO) { block() } - - override suspend fun getById(id: Long, userId: Long?): PostResponse { - val query = query { - Posts.innerJoin(Users, onColumn = { Posts.userId }, otherColumn = { Users.id }).select { Posts.id eq id } - .single() - } - return PostResponse.from(query.toPost(), query.toUser()) + override suspend fun getById(id: Long, userId: Long?): Post { + return postRepository.findOneById(id, userId) + ?: throw PostNotFoundException("$id was not found or is not authorized.") } override suspend fun getAll( @@ -56,12 +41,7 @@ class PostApiServiceImpl( maxId: Long?, limit: Int?, userId: Long? - ): List { - return query { - Posts.innerJoin(Users, onColumn = { Posts.userId }, otherColumn = { id }).selectAll() - .map { PostResponse.from(it.toPost(), it.toUser()) } - } - } + ): List = postRepository.findAll(since, until, minId, maxId, limit, userId) override suspend fun getByUser( nameOrId: String, @@ -71,22 +51,23 @@ class PostApiServiceImpl( maxId: Long?, limit: Int?, userId: Long? - ): List { + ): List { val idOrNull = nameOrId.toLongOrNull() return if (idOrNull == null) { val acct = AcctUtil.parse(nameOrId) - query { - Posts.innerJoin(Users, onColumn = { Posts.userId }, otherColumn = { id }).select { - Users.name.eq(acct.username) - .and(Users.domain eq (acct.domain ?: Config.configData.domain)) - }.map { PostResponse.from(it.toPost(), it.toUser()) } - } + postRepository.findByUserNameAndDomain( + username = acct.username, + s = acct.domain + ?: Config.configData.domain, + since = since, + until = until, + minId = minId, + maxId = maxId, + limit = limit, + userId = userId + ) } else { - query { - Posts.innerJoin(Users, onColumn = { Posts.userId }, otherColumn = { id }).select { - Posts.userId eq idOrNull - }.map { PostResponse.from(it.toPost(), it.toUser()) } - } + postRepository.findByUserId(idOrNull, since, until, minId, maxId, limit, userId) } } } diff --git a/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt b/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt index c9ff10c5..f2cccc4d 100644 --- a/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt +++ b/src/main/kotlin/dev/usbharu/kjob/exposed/ExposedJobRepository.kt @@ -73,7 +73,6 @@ class ExposedJobRepository( } } - @Suppress("SuspendFunWithFlowReturnType") override suspend fun findNext(names: Set, status: Set, limit: Int): Flow { return query { jobs.select( diff --git a/src/main/resources/openapi/api.yaml b/src/main/resources/openapi/api.yaml index 3cc79aab..5ff2768a 100644 --- a/src/main/resources/openapi/api.yaml +++ b/src/main/resources/openapi/api.yaml @@ -20,7 +20,7 @@ paths: schema: type: array items: - $ref: "#/components/schemas/PostResponse" + $ref: "#/components/schemas/Post" 401: $ref: "#/components/responses/Unauthorized" 403: @@ -37,7 +37,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/PostRequest" + $ref: "#/components/schemas/Post" responses: 200: description: 成功 @@ -65,7 +65,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/PostResponse" + $ref: "#/components/schemas/Post" 401: $ref: "#/components/responses/Unauthorized" 403: @@ -90,7 +90,7 @@ paths: schema: type: array items: - $ref: "#/components/schemas/PostResponse" + $ref: "#/components/schemas/Post" 401: $ref: "#/components/responses/Unauthorized" 403: @@ -114,7 +114,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/PostResponse" + $ref: "#/components/schemas/Post" 401: $ref: "#/components/responses/Unauthorized" 403: @@ -137,7 +137,7 @@ paths: schema: type: array items: - $ref: "#/components/schemas/UserResponse" + $ref: "#/components/schemas/User" post: summary: ユーザーを作成する @@ -181,7 +181,7 @@ paths: content: application/json: schema: - $ref: "#/components/schemas/UserResponse" + $ref: "#/components/schemas/User" 404: $ref: "#/components/responses/NotFound" @@ -198,7 +198,7 @@ paths: schema: type: array items: - $ref: "#/components/schemas/UserResponse" + $ref: "#/components/schemas/User" post: summary: ユーザーをフォローする security: @@ -228,47 +228,7 @@ paths: schema: type: array 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 - + $ref: "#/components/schemas/User" components: responses: @@ -301,23 +261,8 @@ components: type: string schemas: - Visibility: - type: string - enum: - - public - - unlisted - - followers - - direct - UserResponse: + User: type: object - required: - - id - - name - - domain - - screenName - - description - - url - - createdAt properties: id: type: number @@ -332,30 +277,23 @@ components: type: string description: type: string - nullable: true url: type: string readOnly: true createdAt: type: number readOnly: true - PostResponse: + Post: type: object - required: - - id - - user - - text - - createdAt - - visibility - - url - - sensitive properties: id: type: integer format: int64 readOnly: true - user: - $ref: "#/components/schemas/UserResponse" + userId: + type: integer + format: int64 + readOnly: true overview: type: string text: @@ -365,7 +303,12 @@ components: format: int64 readOnly: true visibility: - $ref: "#/components/schemas/Visibility" + type: string + enum: + - public + - unlisted + - followers + - direct url: type: string format: uri @@ -380,49 +323,13 @@ components: readOnly: true sensitive: type: boolean + apId: + type: string + format: url + readOnly: true - PostRequest: - type: object - properties: - overview: - type: string - text: - type: string - visibility: - $ref: "#/components/schemas/Visibility" - repostId: - type: integer - format: int64 - replyId: - type: integer - format: int64 - 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: type: http scheme: bearer - bearerFormat: JWT diff --git a/src/main/web/App.tsx b/src/main/web/App.tsx index 3a833754..0da03fa6 100644 --- a/src/main/web/App.tsx +++ b/src/main/web/App.tsx @@ -1,44 +1,58 @@ -import {Component, createEffect, createSignal} from "solid-js"; -import {Route, Router, Routes} from "@solidjs/router"; -import {TopPage} from "./pages/TopPage"; -import {createTheme, CssBaseline, ThemeProvider, useMediaQuery} from "@suid/material"; -import {createCookieStorage} from "@solid-primitives/storage"; -import {ApiProvider} from "./lib/ApiProvider"; -import {Configuration, DefaultApi} from "./generated"; -import {LoginPage} from "./pages/LoginPage"; +import {Component, createSignal} from "solid-js"; 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", - accessToken: cookie.token as string - }))) - createEffect(() => { - setApi( - new DefaultApi(new Configuration({ - basePath: window.location.origin + "/api/internal/v1", - accessToken : cookie.token as string - }))) - }) + const fn = (form: HTMLButtonElement) => { + console.log(form) + } + + const [username, setUsername] = createSignal("") + const [password, setPassword] = createSignal("") - const theme = createTheme({ - palette: { - mode: prefersDarkMode() ? 'dark' : 'light', - } - }) return ( - - - - - - - - - - - +
res.json()) + // .then(res => fetch("/auth-check", { + // method: "GET", + // headers: { + // 'Authorization': 'Bearer ' + res.token + // } + // })) + // .then(res => res.json()) + .then(res => { + console.log(res.token); + fetch("/refresh-token", { + method: "POST", + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({refreshToken: res.refreshToken}), + }).then(res=> res.json()).then(res => console.log(res.token)) + }) + } + + }> + setUsername(e.currentTarget.value)}/> + setPassword(e.currentTarget.value)}/> + +
) } + + +declare module 'solid-js' { + namespace JSX { + interface Directives { + fn: (form: HTMLFormElement) => void + } + } +} diff --git a/src/main/web/atoms/Avatar.tsx b/src/main/web/atoms/Avatar.tsx deleted file mode 100644 index 76db2222..00000000 --- a/src/main/web/atoms/Avatar.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import {Avatar as SuidAvatar} from "@suid/material"; -import {Component, JSXElement} from "solid-js"; - -export const Avatar: Component<{ src: string }> = (props): JSXElement => { - return ( - - ) -} \ No newline at end of file diff --git a/src/main/web/atoms/SidebarButton.tsx b/src/main/web/atoms/SidebarButton.tsx deleted file mode 100644 index cfce597a..00000000 --- a/src/main/web/atoms/SidebarButton.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import {ParentComponent} from "solid-js"; -import {Button, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText} from "@suid/material"; -import {Link} from "@solidjs/router"; - -export const SidebarButton: ParentComponent<{ text: string,linkTo:string }> = (props) => { - return ( - - - {props.children} - - - - ) -} diff --git a/src/main/web/lib/ApiProvider.tsx b/src/main/web/lib/ApiProvider.tsx deleted file mode 100644 index 006f9897..00000000 --- a/src/main/web/lib/ApiProvider.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import {createContextProvider} from "@solid-primitives/context"; -import {createSignal} from "solid-js"; -import {DefaultApi, DefaultApiInterface} from "../generated"; - -export const [ApiProvider,useApi] = createContextProvider((props:{api:DefaultApiInterface}) => { - const [api,setApi] = createSignal(props.api); - return api -},()=>new DefaultApi()); diff --git a/src/main/web/lib/ApiWrapper.ts b/src/main/web/lib/ApiWrapper.ts deleted file mode 100644 index 2fbf3266..00000000 --- a/src/main/web/lib/ApiWrapper.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {DefaultApiInterface} from "../generated"; - -export class ApiWrapper { - api: DefaultApiInterface; - - constructor(initApi: DefaultApiInterface) { - this.api = initApi; - console.log(this.api); - console.log(this.postsGet()); - } - - postsGet = async () => this.api.postsGet() - - usersUserNameGet = async (userName: string) => this.api.usersUserNameGet(userName); - -} diff --git a/src/main/web/molecules/ShareScopeIndicator.tsx b/src/main/web/molecules/ShareScopeIndicator.tsx deleted file mode 100644 index 7d5ccc7c..00000000 --- a/src/main/web/molecules/ShareScopeIndicator.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import {Component, Match, Switch} from "solid-js"; -import {Home, Lock, Mail, Public} from "@suid/icons-material"; -import {IconButton} from "@suid/material"; -import {Visibility} from "../generated"; - -export const ShareScopeIndicator: Component<{ visibility: Visibility }> = (props) => { - return }> - - - - - - - - - - - - - - - - - - - - - -} diff --git a/src/main/web/organisms/Post.tsx b/src/main/web/organisms/Post.tsx deleted file mode 100644 index f3680354..00000000 --- a/src/main/web/organisms/Post.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import {Component, createSignal} from "solid-js"; -import {Box, Card, CardActions, CardContent, CardHeader, IconButton, Menu, MenuItem, Typography} from "@suid/material"; -import {Avatar} from "../atoms/Avatar"; -import {Favorite, MoreVert, Reply, ScreenRotationAlt} from "@suid/icons-material"; -import {ShareScopeIndicator} from "../molecules/ShareScopeIndicator"; -import {PostResponse} from "../generated"; - -export const Post: Component<{ post: PostResponse }> = (props) => { - const [anchorEl, setAnchorEl] = createSignal(null) - const open = () => Boolean(anchorEl()); - const handleClose = () => { - setAnchorEl(null); - } - - return ( - - } title={props.post.user.screenName} - subheader={`${props.post.user.name}@${props.post.user.domain}`} - action={ { - setAnchorEl(event.currentTarget) - }}>aaa }/> - - - {props.post.text} - - - - - - - - - - - - - - {new Date(props.post.createdAt).toDateString()} - - - - - ) -} diff --git a/src/main/web/organisms/PostForm.tsx b/src/main/web/organisms/PostForm.tsx deleted file mode 100644 index 3d11515a..00000000 --- a/src/main/web/organisms/PostForm.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import {Component, createSignal} from "solid-js"; -import {Button, IconButton, Paper, Stack, TextField, Typography} from "@suid/material"; -import {Avatar} from "../atoms/Avatar"; -import {AddPhotoAlternate, Poll, Public} from "@suid/icons-material"; -import {useApi} from "../lib/ApiProvider"; - -export const PostForm: Component<{ label: string }> = (props) => { - const [text, setText] = createSignal("") - const api = useApi() - return ( - - - - - setText(event.target.value)} fullWidth/> - - - - - - - - - - - - - - - - aaa - - - - - - - ) -} diff --git a/src/main/web/pages/LoginPage.tsx b/src/main/web/pages/LoginPage.tsx deleted file mode 100644 index decb6990..00000000 --- a/src/main/web/pages/LoginPage.tsx +++ /dev/null @@ -1,58 +0,0 @@ -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"; -import {useNavigate} from "@solidjs/router"; - -export const LoginPage: Component = () => { - const [username, setUsername] = createSignal("") - const [password, setPassword] = createSignal("") - - const [cookie, setCookie] = createCookieStorage(); - - const navigator = useNavigate(); - - const api = useApi(); - - const onSubmit: () => void = () => { - api().loginPost({password: password(), username: username()}).then(value => { - setCookie("token", value.token); - setCookie("refresh-token", value.refreshToken) - navigator("/") - }).catch(reason => { - console.log(reason); - setPassword("") - }) - } - - return ( - - - - - - - - setUsername(event.target.value)} - label="Username" - type="text" - autoComplete="username" - variant="standard" - /> - setPassword(event.target.value)} - label="Password" - type="password" - autoComplete="current-password" - variant="standard" - /> - - - - - - ) -} diff --git a/src/main/web/pages/TopPage.tsx b/src/main/web/pages/TopPage.tsx deleted file mode 100644 index b62c2665..00000000 --- a/src/main/web/pages/TopPage.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import {Component} from "solid-js"; -import {MainPage} from "../templates/MainPage"; -import {PostForm} from "../organisms/PostForm"; -import {Stack} from "@suid/material"; -import {PostResponse} from "../generated"; -import {PostList} from "../templates/PostList"; -import {useApi} from "../lib/ApiProvider"; -import {createStore} from "solid-js/store"; - - -export const TopPage: Component = () => { - const api = useApi() - const [posts, setPosts] = createStore([]) - api().postsGet().then((res)=>setPosts(res)) - - return ( - - - - - - - ) -} diff --git a/src/main/web/templates/MainPage.tsx b/src/main/web/templates/MainPage.tsx deleted file mode 100644 index cf183a8e..00000000 --- a/src/main/web/templates/MainPage.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import {createSignal, ParentComponent} from "solid-js"; -import {Grid} from "@suid/material"; -import {Sidebar} from "./Sidebar"; - -export const MainPage: ParentComponent = (props) => { - return ( - - - - - - {props.children} - - - - - - - ) -} diff --git a/src/main/web/templates/PostList.tsx b/src/main/web/templates/PostList.tsx deleted file mode 100644 index 82930d8e..00000000 --- a/src/main/web/templates/PostList.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import {Component, For} from "solid-js"; -import {CircularProgress} from "@suid/material"; -import {Post} from "../organisms/Post"; -import {PostResponse} from "../generated"; - -export const PostList: Component<{ posts: PostResponse[] | undefined }> = (props) => { - return ( - }> - { - (item, index) => - } - - ) -} diff --git a/src/main/web/templates/Sidebar.tsx b/src/main/web/templates/Sidebar.tsx deleted file mode 100644 index cf8d16de..00000000 --- a/src/main/web/templates/Sidebar.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import {Component} from "solid-js"; -import {Button, List, Stack} from "@suid/material"; -import {Home} from "@suid/icons-material"; -import {SidebarButton} from "../atoms/SidebarButton"; - -export const Sidebar: Component = (props) => { - return ( - - - - - ) -} diff --git a/src/test/kotlin/dev/usbharu/hideout/plugins/SecurityKtTest.kt b/src/test/kotlin/dev/usbharu/hideout/plugins/SecurityKtTest.kt index 8c1f4d13..9da64ff0 100644 --- a/src/test/kotlin/dev/usbharu/hideout/plugins/SecurityKtTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/plugins/SecurityKtTest.kt @@ -15,7 +15,6 @@ import dev.usbharu.hideout.domain.model.hideout.form.RefreshToken import dev.usbharu.hideout.domain.model.hideout.form.UserLogin import dev.usbharu.hideout.exception.InvalidRefreshTokenException import dev.usbharu.hideout.repository.IUserRepository -import dev.usbharu.hideout.routing.api.internal.v1.auth import dev.usbharu.hideout.service.auth.IJwtService import dev.usbharu.hideout.service.core.IMetaService import dev.usbharu.hideout.service.user.IUserAuthService @@ -25,7 +24,6 @@ import io.ktor.client.request.* import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.server.config.* -import io.ktor.server.routing.* import io.ktor.server.testing.* import org.junit.jupiter.api.Test import org.mockito.ArgumentMatchers.anyString @@ -72,10 +70,7 @@ class SecurityKtTest { val jwkProvider = mock() application { configureSerialization() - configureSecurity(jwkProvider, metaService) - routing { - auth(userAuthService, userRepository, jwtService) - } + configureSecurity(userAuthService, metaService, userRepository, jwtService, jwkProvider) } client.post("/login") { @@ -102,10 +97,7 @@ class SecurityKtTest { val jwkProvider = mock() application { configureSerialization() - configureSecurity(jwkProvider, metaService) - routing { - auth(userAuthService, userRepository, jwtService) - } + configureSecurity(userAuthService, metaService, userRepository, jwtService, jwkProvider) } client.post("/login") { contentType(ContentType.Application.Json) @@ -130,10 +122,7 @@ class SecurityKtTest { val jwkProvider = mock() application { configureSerialization() - configureSecurity(jwkProvider, metaService) - routing { - auth(userAuthService, userRepository, jwtService) - } + configureSecurity(userAuthService, metaService, userRepository, jwtService, jwkProvider) } client.post("/login") { contentType(ContentType.Application.Json) @@ -151,10 +140,7 @@ class SecurityKtTest { Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper()) application { configureSerialization() - configureSecurity(mock(), mock()) - routing { - auth(mock(), mock(), mock()) - } + configureSecurity(mock(), mock(), mock(), mock(), mock()) } client.get("/auth-check").apply { assertEquals(HttpStatusCode.Unauthorized, call.response.status) @@ -169,10 +155,7 @@ class SecurityKtTest { Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper()) application { configureSerialization() - configureSecurity(mock(), mock()) - routing { - auth(mock(), mock(), mock()) - } + configureSecurity(mock(), mock(), mock(), mock(), mock()) } client.get("/auth-check") { header("Authorization", "Digest dsfjjhogalkjdfmlhaog") @@ -189,10 +172,7 @@ class SecurityKtTest { Config.configData = ConfigData(url = "http://example.com", objectMapper = jacksonObjectMapper()) application { configureSerialization() - configureSecurity(mock(), mock()) - routing { - auth(mock(), mock(), mock()) - } + configureSecurity(mock(), mock(), mock(), mock(), mock()) } client.get("/auth-check") { header("Authorization", "") @@ -210,10 +190,7 @@ class SecurityKtTest { application { configureSerialization() - configureSecurity(mock(), mock()) - routing { - auth(mock(), mock(), mock()) - } + configureSecurity(mock(), mock(), mock(), mock(), mock()) } client.get("/auth-check") { header("Authorization", "Bearer ") @@ -267,12 +244,11 @@ class SecurityKtTest { ) ) } + val userRepository = mock() + val jwtService = mock() application { configureSerialization() - configureSecurity(jwkProvider, metaService) - routing { - auth(mock(), mock(), mock()) - } + configureSecurity(mock(), metaService, userRepository, jwtService, jwkProvider) } client.get("/auth-check") { @@ -328,12 +304,11 @@ class SecurityKtTest { ) ) } + val userRepository = mock() + val jwtService = mock() application { configureSerialization() - configureSecurity(jwkProvider, metaService) - routing { - auth(mock(), mock(), mock()) - } + configureSecurity(mock(), metaService, userRepository, jwtService, jwkProvider) } client.get("/auth-check") { header("Authorization", "Bearer $token") @@ -387,12 +362,11 @@ class SecurityKtTest { ) ) } + val userRepository = mock() + val jwtService = mock() application { configureSerialization() - configureSecurity(jwkProvider, metaService) - routing { - auth(mock(), mock(), mock()) - } + configureSecurity(mock(), metaService, userRepository, jwtService, jwkProvider) } client.get("/auth-check") { header("Authorization", "Bearer $token") @@ -446,12 +420,11 @@ class SecurityKtTest { ) ) } + val userRepository = mock() + val jwtService = mock() application { configureSerialization() - configureSecurity(jwkProvider, metaService) - routing { - auth(mock(), mock(), mock()) - } + configureSecurity(mock(), metaService, userRepository, jwtService, jwkProvider) } client.get("/auth-check") { header("Authorization", "Bearer $token") @@ -504,12 +477,11 @@ class SecurityKtTest { ) ) } + val userRepository = mock() + val jwtService = mock() application { configureSerialization() - configureSecurity(jwkProvider, metaService) - routing { - auth(mock(), mock(), mock()) - } + configureSecurity(mock(), metaService, userRepository, jwtService, jwkProvider) } client.get("/auth-check") { header("Authorization", "Bearer $token") @@ -529,10 +501,7 @@ class SecurityKtTest { } application { configureSerialization() - configureSecurity(mock(), mock()) - routing { - auth(mock(), mock(), jwtService) - } + configureSecurity(mock(), mock(), mock(), jwtService, mock()) } client.post("/refresh-token") { header("Content-Type", "application/json") @@ -554,10 +523,7 @@ class SecurityKtTest { application { configureStatusPages() configureSerialization() - configureSecurity(mock(), mock()) - routing { - auth(mock(), mock(), jwtService) - } + configureSecurity(mock(), mock(), mock(), jwtService, mock()) } client.post("/refresh-token") { header("Content-Type", "application/json") diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsTest.kt index bb057308..0f2c1627 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/PostsTest.kt @@ -4,8 +4,6 @@ import com.auth0.jwt.interfaces.Claim import com.auth0.jwt.interfaces.Payload import com.fasterxml.jackson.module.kotlin.readValue import dev.usbharu.hideout.config.Config -import dev.usbharu.hideout.domain.model.hideout.dto.PostResponse -import dev.usbharu.hideout.domain.model.hideout.dto.UserResponse import dev.usbharu.hideout.domain.model.hideout.entity.Post import dev.usbharu.hideout.domain.model.hideout.entity.Visibility import dev.usbharu.hideout.plugins.TOKEN_AUTH @@ -34,27 +32,18 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ) val posts = listOf( - PostResponse( + Post( id = 12345, - user = user, + userId = 4321, text = "test1", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - PostResponse( + Post( id = 123456, - user = user, + userId = 4322, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -75,7 +64,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) @@ -100,35 +89,27 @@ class PostsTest { val payload = mock { on { getClaim(eq("uid")) } doReturn claim } - val user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ) + val posts = listOf( - PostResponse( + Post( id = 12345, - user = user, + userId = 4321, text = "test1", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - PostResponse( + Post( id = 123456, - user = user, + userId = 4322, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/2" ), - PostResponse( + Post( id = 1234567, - user = user, + userId = 4333, text = "Followers only", visibility = Visibility.FOLLOWERS, createdAt = Instant.now().toEpochMilli(), @@ -175,18 +156,9 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ) - val post = PostResponse( - id = 12345, - user = user, + val post = Post( + 12345, + 1234, text = "aaa", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -197,7 +169,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) @@ -215,17 +187,9 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val post = PostResponse( + val post = Post( 12345, - UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ), + 1234, text = "aaa", visibility = Visibility.FOLLOWERS, createdAt = Instant.now().toEpochMilli(), @@ -278,22 +242,14 @@ class PostsTest { onBlocking { createPost(any(), any()) } doAnswer { val argument = it.getArgument(0) val userId = it.getArgument(1) - PostResponse( - id = 123L, - user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ), - overview = null, - text = argument.text, - createdAt = Instant.now().toEpochMilli(), - visibility = Visibility.PUBLIC, - url = "https://example.com" + Post( + 123L, + userId, + null, + argument.text, + Instant.now().toEpochMilli(), + Visibility.PUBLIC, + "https://example.com" ) } } @@ -334,27 +290,18 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ) val posts = listOf( - PostResponse( + Post( id = 12345, - user = user, + userId = 1, text = "test1", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - PostResponse( + Post( id = 123456, - user = user, + userId = 1, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -376,7 +323,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) @@ -395,27 +342,18 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ) val posts = listOf( - PostResponse( + Post( id = 12345, - user = user, + userId = 1, text = "test1", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - PostResponse( + Post( id = 123456, - user = user, + userId = 1, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -437,7 +375,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) @@ -456,27 +394,18 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ) val posts = listOf( - PostResponse( + Post( id = 12345, - user = user, + userId = 1, text = "test1", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - PostResponse( + Post( id = 123456, - user = user, + userId = 1, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -498,7 +427,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) @@ -517,27 +446,18 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ) val posts = listOf( - PostResponse( + Post( id = 12345, - user = user, + userId = 1, text = "test1", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), url = "https://example.com/posts/1" ), - PostResponse( + Post( id = 123456, - user = user, + userId = 1, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -559,7 +479,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) @@ -578,17 +498,9 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val post = PostResponse( + val post = Post( id = 123456, - user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ), + userId = 1, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -599,7 +511,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) @@ -618,17 +530,9 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val post = PostResponse( + val post = Post( id = 123456, - user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ), + userId = 1, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -639,7 +543,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) @@ -658,17 +562,9 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val post = PostResponse( + val post = Post( id = 123456, - user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ), + userId = 1, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -679,7 +575,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) @@ -698,17 +594,9 @@ class PostsTest { environment { config = ApplicationConfig("empty.conf") } - val post = PostResponse( + val post = Post( id = 123456, - user = UserResponse( - id = 54321, - name = "user1", - domain = "example.com", - screenName = "user 1", - description = "Test user", - url = "https://example.com/users/54321", - createdAt = Instant.now().toEpochMilli() - ), + userId = 1, text = "test2", visibility = Visibility.PUBLIC, createdAt = Instant.now().toEpochMilli(), @@ -719,7 +607,7 @@ class PostsTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { posts(postService) diff --git a/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/UsersTest.kt b/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/UsersTest.kt index 0f738579..ea9d703b 100644 --- a/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/UsersTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/routing/api/internal/v1/UsersTest.kt @@ -58,7 +58,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userService) @@ -96,7 +96,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(userService, mock()) @@ -127,7 +127,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(userService, mock()) @@ -162,7 +162,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) @@ -195,7 +195,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) @@ -228,7 +228,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) @@ -261,7 +261,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) @@ -306,7 +306,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) @@ -351,7 +351,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) @@ -396,7 +396,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) @@ -591,7 +591,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) @@ -636,7 +636,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) @@ -681,7 +681,7 @@ class UsersTest { } application { configureSerialization() - configureSecurity(mock(), mock()) + configureSecurity(mock(), mock(), mock(), mock(), mock()) routing { route("/api/internal/v1") { users(mock(), userApiService) diff --git a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubReceiveFollowServiceImplTest.kt b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubReceiveFollowServiceImplTest.kt index 0d703801..5d15c039 100644 --- a/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubReceiveFollowServiceImplTest.kt +++ b/src/test/kotlin/dev/usbharu/hideout/service/activitypub/ActivityPubReceiveFollowServiceImplTest.kt @@ -48,21 +48,13 @@ class ActivityPubReceiveFollowServiceImplTest { firstValue.invoke(scheduleContext, ReceiveFollowJob) val actor = scheduleContext.props.props[ReceiveFollowJob.actor.name] val targetActor = scheduleContext.props.props[ReceiveFollowJob.targetActor.name] - val follow = scheduleContext.props.props[ReceiveFollowJob.follow.name] as String + val follow = scheduleContext.props.props[ReceiveFollowJob.follow.name] assertEquals("https://follower.example.com", actor) assertEquals("https://example.com", targetActor) //language=JSON assertEquals( - Json.parseToJsonElement( - """{ - "type": "Follow", - "name": "Follow", - "actor": "https://follower.example.com", - "object": "https://example.com", - "@context": null -}""" - ), - Json.parseToJsonElement(follow) + """{"type":"Follow","name":"Follow","actor":"https://follower.example.com","object":"https://example.com","@context":null}""", + follow ) } } @@ -163,14 +155,7 @@ class ActivityPubReceiveFollowServiceImplTest { data = mapOf( ReceiveFollowJob.actor.name to "https://follower.example.com", ReceiveFollowJob.targetActor.name to "https://example.com", - //language=JSON - ReceiveFollowJob.follow.name to """{ - "type": "Follow", - "name": "Follow", - "object": "https://example.com", - "actor": "https://follower.example.com", - "@context": null -}""" + ReceiveFollowJob.follow.name to """{"type":"Follow","name":"Follow","object":"https://example.com","actor":"https://follower.example.com","@context":null}""" ), json = Json ) diff --git a/vite.config.ts b/vite.config.ts index bf6b9be6..3f3c0c58 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,24 +1,21 @@ -import {defineConfig, splitVendorChunkPlugin} from 'vite'; +import { defineConfig } from 'vite'; import solidPlugin from 'vite-plugin-solid'; import suidPlugin from "@suid/vite-plugin"; -import visualizer from "rollup-plugin-visualizer"; export default defineConfig({ - plugins: [solidPlugin(),suidPlugin(),splitVendorChunkPlugin()], + plugins: [solidPlugin(),suidPlugin()], server: { port: 3000, proxy: { '/api': 'http://localhost:8080', + '/login': 'http://localhost:8080', + '/auth-check': 'http://localhost:8080', + '/refresh-token': 'http://localhost:8080', } }, root: './src/main/web', build: { target: 'esnext', outDir: '../resources/static', - rollupOptions:{ - plugins: [ - visualizer() - ] - } }, });