Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file.
Binary file added application-files/products/1/test.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added application-files/products/1/test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added application-files/products/1/test.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ services:
- POSTGRES_DB=ex-dock
volumes:
- ./database/ex-dock.sql:/docker-entrypoint-initdb.d/datadump.sql
- ./application-files:/app/application-files
ports:
- "8890:5432"
networks:
Expand Down
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-launcher-application</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
Expand Down Expand Up @@ -202,6 +207,11 @@
<artifactId>oshi-core</artifactId>
<version>6.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.18.0</version>
</dependency>
</dependencies>

<build>
Expand Down
2 changes: 0 additions & 2 deletions src/main/kotlin/com/ex_dock/ex_dock/ExtensionsLauncher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import com.ex_dock.ex_dock.frontend.FrontendVerticle
import com.ex_dock.ex_dock.helper.deployVerticleHelper
import com.ex_dock.ex_dock.helper.registerVerticleIds
import io.github.oshai.kotlinlogging.KotlinLogging
import io.vertx.core.AbstractVerticle
import io.vertx.core.Future
import io.vertx.core.Promise
import io.vertx.core.VerticleBase
import io.vertx.ext.web.client.WebClient
import java.util.*
Expand Down
9 changes: 7 additions & 2 deletions src/main/kotlin/com/ex_dock/ex_dock/MainVerticle.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import com.ex_dock.ex_dock.frontend.text_pages.router.initTextPages
import com.ex_dock.ex_dock.helper.registerGenericCodec
import com.ex_dock.ex_dock.helper.sendError
import io.github.oshai.kotlinlogging.KotlinLogging
import io.vertx.core.AbstractVerticle
import io.vertx.core.Future
import io.vertx.core.Promise
import io.vertx.core.VerticleBase
import io.vertx.core.eventbus.EventBus
import io.vertx.core.http.CookieSameSite
import io.vertx.core.http.HttpServerOptions
import io.vertx.ext.web.Router
import io.vertx.ext.web.handler.CorsHandler
import io.vertx.ext.web.handler.SessionHandler
import io.vertx.ext.web.sstore.SessionStore
import java.util.Properties
Expand Down Expand Up @@ -51,10 +51,14 @@ class MainVerticle : VerticleBase() {
logger.error { "Failed to start MainVerticle: $err" }
}

val eventBus = vertx.eventBus()
val mainRouter : Router = Router.router(vertx)
val store = SessionStore.create(vertx)
val sessionHandler = SessionHandler.create(store)
val eventBus: EventBus = vertx.eventBus()

if (!areCodecsRegistered) {
eventBus.registerGenericCodec(ServerStartException::class)
}

eventBus.registerGenericCodec(List::class)
eventBus.consumer<List<String>>("process.main.registerVerticleId").handler { message ->
Expand Down Expand Up @@ -84,6 +88,7 @@ class MainVerticle : VerticleBase() {
sessionHandler.setCookieSameSite(CookieSameSite.STRICT)

mainRouter.route().handler(sessionHandler)
mainRouter.route().handler(CorsHandler.create())

mainRouter.enableBackendRouter(vertx, logger)

Expand Down
3 changes: 1 addition & 2 deletions src/main/kotlin/com/ex_dock/ex_dock/backend/BackendRouter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.ex_dock.ex_dock.backend.v1.router.auth.AuthProvider
import com.ex_dock.ex_dock.backend.v1.router.auth.enableAuthRouter
import com.ex_dock.ex_dock.backend.v1.router.docker.initDocker
import com.ex_dock.ex_dock.backend.v1.router.enableBackendV1Router
import com.ex_dock.ex_dock.backend.v1.router.file.initFileRouter
import com.ex_dock.ex_dock.backend.v1.router.websocket.initWebsocket
import com.ex_dock.ex_dock.helper.registerGenericCodec
import io.github.oshai.kotlinlogging.KLogger
Expand Down Expand Up @@ -45,8 +46,6 @@ fun Router.enableBackendRouter(vertx: Vertx, logger: KLogger) {
pairDeliveryOptions
)

backendRouter.route().handler(CorsHandler.create())

backendRouter.enableAuthRouter(vertx)

// Only use these routers for websockets, because they use other authorization methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.ex_dock.ex_dock.backend.v1.router

import com.ex_dock.ex_dock.backend.apiMountingPath
import com.ex_dock.ex_dock.backend.v1.router.auth.AuthProvider
import com.ex_dock.ex_dock.backend.v1.router.file.initFileRouter
import com.ex_dock.ex_dock.database.backend_block.FullBlockInfo
import com.ex_dock.ex_dock.frontend.auth.ExDockAuthHandler
import com.ex_dock.ex_dock.backend.v1.router.image.initImage
Expand Down Expand Up @@ -76,6 +77,7 @@ fun Router.enableBackendV1Router(vertx: Vertx, absoluteMounting: Boolean = false
"images",
jsonElement.findValueByFieldName("images").convertJsonElement()
)
blockInformationJson.put("attributes", blockAttributesList)
} else {
blockInformationJson.put("attributes", blockAttributesList)
}
Expand Down Expand Up @@ -115,6 +117,7 @@ fun Router.enableBackendV1Router(vertx: Vertx, absoluteMounting: Boolean = false
// TODO: routing
backendV1Router.initImage(vertx)
backendV1Router.enableSystemRouter(vertx)
backendV1Router.initFileRouter(vertx)

this.route(
if (absoluteMounting) "$apiMountingPath/v1*" else "/v1*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package com.ex_dock.ex_dock.backend.v1.router.auth

import java.security.KeyPair
import java.security.KeyPairGenerator
import java.util.Base64
import java.util.*

class AuthProvider {
private val generator: KeyPairGenerator = KeyPairGenerator.getInstance("RSA")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package com.ex_dock.ex_dock.backend.v1.router.file

import com.ex_dock.ex_dock.database.backend_block.FullBlockInfo
import io.vertx.core.Vertx
import io.vertx.core.buffer.Buffer
import io.vertx.core.eventbus.DeliveryOptions
import io.vertx.core.json.JsonObject
import io.vertx.ext.web.Router
import kotlinx.serialization.Serializable
import java.nio.file.Paths
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
import kotlin.io.path.isDirectory

@OptIn(ExperimentalEncodingApi::class)
fun Router.initFileRouter(vertx: Vertx) {
val fileRouter = Router.router(vertx)

fileRouter["/getAll"].handler { ctx ->
val fullList = getRootFiles()

ctx.response().putHeader("Content-Type", "application/json")
.end(JsonObject().put("files", fullList).encode())
}

fileRouter["/getAll/:path"].handler { ctx ->
val folders = emptyList<EngineFile>().toMutableList()
val files = emptyList<EngineFile>().toMutableList()
var path = ctx.pathParam("path")
path = path.replace("%2F", "/")
path = "application-files/$path"
val fullPath = Paths.get(path)

if (!fullPath.toFile().exists()) {
ctx.fail(400, Error("Path does not exist"))
}

if (fullPath.toFile().isDirectory) {
fullPath.toFile().listFiles()?.forEach { file ->
if (file.isDirectory) {
val engineFile = EngineFile(file.name, "folder", file.length().toInt())
folders.add(engineFile)
} else {
val engineFile = EngineFile(file.name, file.extension, file.length().toInt())
files.add(engineFile)
}
}

val fullList = folders + files
ctx.response().putHeader("Content-Type", "application/json")
.end(JsonObject().put("files", fullList).encode())
} else {
val contentType: String = when (fullPath.toFile().extension) {
"png" -> "image"
"jpg" -> "image"
"jpeg" -> "image"
"gif" -> "image"
"avif" -> "image"
"md" -> "markdown"
"mp4" -> "mp4"
"pdf" -> "pdf"
"txt" -> "plain"
"webp" -> "image"
else -> "unknown"
}

ctx.response().putHeader("Content-Type", "application/octet-stream")
.end(
JsonObject()
.put("contentType", contentType)
.put("fileName", fullPath.toFile().name)
.put("fileSize", fullPath.toFile().length())
.put("fileExtension", fullPath.toFile().extension)
.put("data", Base64.Default.encode(fullPath.toFile().readBytes())).encode()
)
}
}

fileRouter["/getBlockData/:blockName"].handler { ctx ->
val blockName = ctx.pathParam("blockName")

vertx.eventBus().request<MutableList<FullBlockInfo>>(
"process.backend_block.getAllFullInfoByBlockNames",
blockName, DeliveryOptions().setCodecName("ListCodec")
).onFailure {
ctx.fail(500, it)
}.onSuccess { result ->
val blocks = result.body()
val jsonResponse = JsonObject()
blocks.forEach { block ->
val blockInformationJson = JsonObject()
val blockAttributesList = mutableListOf<JsonObject>()
val fullList = getRootFiles()

block.blockAttributes.forEach { blockAttribute ->
if (blockAttribute.attributeName == "Files") {
val attributeJson = JsonObject()
attributeJson.put("attribute_id", blockAttribute.attributeId)
attributeJson.put("attribute_name", blockAttribute.attributeName)
attributeJson.put("attribute_type", blockAttribute.attributeType)
attributeJson.put(
"current_attribute_value",
fullList
)
blockAttributesList.add(attributeJson)
}
}

blockInformationJson.put("block_type", block.backendBlock.blockType)
blockInformationJson.put("attributes", blockAttributesList)
jsonResponse.put(block.backendBlock.blockName, blockInformationJson)
}

ctx.end(jsonResponse.encode())
}
}

this.route("/file*").subRouter(fileRouter)
}

fun getRootFiles(): List<EngineFile> {
val folders = emptyList<EngineFile>().toMutableList()
val files = emptyList<EngineFile>().toMutableList()
val path = "application-files"
val fullPath = Paths.get(path)

fullPath.toFile().listFiles()?.forEach { file ->
if (file.isDirectory) {
val engineFile = EngineFile(file.name, "folder", file.length().toInt())
folders.add(engineFile)
} else {
val engineFile = EngineFile(file.name, file.extension, file.length().toInt())
files.add(engineFile)
}
}

val fullList = folders + files
return fullList
}

@Serializable
data class EngineFile(
val fileName: String,
val extension: String,
val fileSize: Int
)
Original file line number Diff line number Diff line change
@@ -1,25 +1,62 @@
package com.ex_dock.ex_dock.backend.v1.router.image

import com.ex_dock.ex_dock.MainVerticle
import io.vertx.core.Vertx
import io.vertx.core.buffer.Buffer
import io.vertx.ext.web.Router
import io.vertx.ext.web.handler.BodyHandler
import io.vertx.ext.web.handler.StaticHandler
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Paths
import kotlin.io.path.extension

fun Router.initImage(vertx: Vertx) {
val imageRouter = Router.router(vertx)
val eventBus = vertx.eventBus()

imageRouter.post().handler(BodyHandler.create()
.setUploadsDirectory("src/main/resources/images")
.setUploadsDirectory("application-files/images")
.setMergeFormAttributes(true))

imageRouter.post("/").handler(StaticHandler.create("src/main/resources/images").setCachingEnabled(false))
imageRouter.post("/").handler(StaticHandler.create("application-files/images").setCachingEnabled(false))

imageRouter.post("/").handler { ctx ->
val path = ctx.request().getFormAttribute("path")
imageRouter.post("/:path").handler { ctx ->
var path = ctx.pathParam("path")
path = path.replace("%2F", "/")
eventBus.send("process.service.convertImage", path)
ctx.end("request to imageRouter successful")
}

imageRouter.get("/get/:path").handler { ctx ->
var path = ctx.pathParam("path")
path = path.replace("%2F", "/")
path = "application-files/$path"
val imagePath = Paths.get(path)

// Check if the requested image exists
if (!Files.exists(imagePath)) {
MainVerticle.logger.error { "Image not found: $path" }
ctx.response().setStatusCode(404).end("Image not found")
}

try {
// Read the image file into a byte array
val imageData: ByteArray = Files.readAllBytes(imagePath)

// Get the image extension type
var extension = imagePath.extension
if (extension == "jpg") extension = "jpeg"
val contentType = "image/$extension"

ctx.response().putHeader("Content-Type", contentType)
ctx.response().end(Buffer.buffer(imageData))
} catch (e: IOException) {
MainVerticle.logger.error { "Error reading image file: $path" }
ctx.response().setStatusCode(500).end("Error reading image file")
}

}

this.route("/image*").subRouter(imageRouter)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.ex_dock.ex_dock.backend.v1.router.system

import com.ex_dock.ex_dock.helper.load
import io.github.oshai.kotlinlogging.KotlinLogging
import io.vertx.core.AbstractVerticle
import io.vertx.core.Future
import io.vertx.core.VerticleBase
import io.vertx.core.eventbus.EventBus
Expand Down
2 changes: 0 additions & 2 deletions src/main/kotlin/com/ex_dock/ex_dock/database/JDBCStarter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,7 @@ import com.ex_dock.ex_dock.database.text_pages.TextPagesSeo
import com.ex_dock.ex_dock.database.url.*
import com.ex_dock.ex_dock.frontend.cache.CacheVerticle
import com.ex_dock.ex_dock.helper.*
import io.vertx.core.AbstractVerticle
import io.vertx.core.Future
import io.vertx.core.Promise
import io.vertx.core.VerticleBase
import io.vertx.core.eventbus.DeliveryOptions
import io.vertx.core.eventbus.EventBus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.ex_dock.ex_dock.database.account

import com.ex_dock.ex_dock.database.connection.getConnection
import com.ex_dock.ex_dock.frontend.cache.setCacheFlag
import io.vertx.core.AbstractVerticle
import io.vertx.core.Future
import io.vertx.core.VerticleBase
import io.vertx.core.eventbus.DeliveryOptions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package com.ex_dock.ex_dock.database.auth

import com.ex_dock.ex_dock.database.account.BackendPermissions
import com.ex_dock.ex_dock.database.account.FullUser
import com.ex_dock.ex_dock.database.account.convertUser
import com.ex_dock.ex_dock.frontend.auth.ExDockAuthHandler
import io.vertx.core.AbstractVerticle
import io.vertx.core.Future
import io.vertx.core.VerticleBase
import io.vertx.core.eventbus.EventBus
Expand All @@ -15,8 +13,6 @@ import io.vertx.ext.auth.authentication.TokenCredentials
import io.vertx.ext.auth.authentication.UsernamePasswordCredentials
import io.vertx.ext.auth.jwt.JWTAuth
import io.vertx.ext.auth.jwt.JWTAuthOptions
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.util.*

class AuthenticationVerticle: VerticleBase() {
Expand Down
Loading