Spring (Kotlin)

Spring (Kotlin)

Installation

Add the dependency:

1
2
3
4
5
<dependency>
    <groupId>com.botbye</groupId>
    <artifactId>kotlin-module</artifactId>
    <version>3.0.1</version>
</dependency>
1
implementation("com.botbye:kotlin-module:3.0.1")

Configuration

Expose the dedicated BotbyePhishingClient as a Spring bean. Phishing is separate from the evaluate Botbye client and is identified by a public, browser-safe clientKey, so it needs no server key. On construction it makes a one-off, best-effort server-integration init handshake that reports this server-side integration to BotBye; it is non-blocking, so expose it as a singleton bean and reuse it.

BotbyePhishingConfig takes 2 values: endpoint (optional, defaults to https://verify.botbye.com) and clientKey.

Getting clientKey

clientKey is the public, browser-safe identifier of your phishing project. It travels in the asset URL path, so it is safe to expose — no secret token and no Base64 encoding are required.

Find it on the Get Started screen of your phishing project in the BotBye dashboard.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import com.botbye.phishing.BotbyePhishingClient
import com.botbye.phishing.BotbyePhishingConfig
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class AppConfig {

    @Bean
    fun phishingClient(): BotbyePhishingClient =
        BotbyePhishingClient(
            BotbyePhishingConfig(
                endpoint = "https://verify.botbye.com",
                clientKey = "<public-client-key>",
            )
        )
}

Usage

Inject the client into a controller and expose a single endpoint that proxies phishing pixel requests. fetchImage is a suspend function, so the controller method is suspend too.

When you use an SVG image, your application must also expose an endpoint on the client origin that handles requests to /{imageId}.png, where imageId is the value that arrives in the forwarded pixel query as image_id.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@RestController
@RequestMapping("/api/phishing")
class PhishingController(
    private val phishing: BotbyePhishingClient,
) {

    @GetMapping("/image")
    suspend fun image(
        @RequestHeader(name = "Origin", required = false) origin: String?,
        @RequestParam params: Map<String, String>,
    ): ResponseEntity<ByteArray> {
        val response = phishing.fetchImage(origin = origin, query = params)

        if (response.error != null) {
            return ResponseEntity.status(502).build()
        }

        val contentType = response.headers["Content-Type"] ?: "image/png"

        return ResponseEntity
            .status(response.status)
            .contentType(MediaType.valueOf(contentType))
            .body(response.body)
    }
}

Settings

Configuration parameters for phishing integration:

Setting Description Required Default Value
endpoint Host of the phishing API no https://verify.botbye.com
clientKey Public client-key of your phishing project yes -