Skip to content
Merged
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
6 changes: 6 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ application {
mainClass = "dev.lavalink.config.server.Launcher"
}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

repositories {
mavenCentral()
}
Expand All @@ -25,6 +30,7 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-security:3.3.0")
implementation("org.springframework.boot:spring-boot-starter-web:3.3.0")
implementation("org.springframework.cloud:spring-cloud-config-server:4.1.5")
implementation("org.springframework.boot:spring-boot-starter-thymeleaf:3.3.0")
implementation("ch.qos.logback:logback-classic:1.5.6")
}

Expand Down
22 changes: 22 additions & 0 deletions src/main/java/dev/lavalink/config/server/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package dev.lavalink.config.server;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.formLogin(form -> form.loginPage("/login").permitAll())
.authorizeHttpRequests(auth -> auth
.requestMatchers("/style.css", "/lavalink.svg").permitAll()
.anyRequest().authenticated())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package dev.lavalink.config.server.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {

@GetMapping(value = "/login", produces = "text/html;charset=UTF-8")
public String login() {
return "login";
}

}
60 changes: 1 addition & 59 deletions src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,7 @@
<title>Lavalink Config Server</title>
<link rel="icon" href="lavalink.svg" type="image/svg+xml">
<meta name="darkreader-lock">
<style>
:root {
--font-family: Arial;
--button-border-radius: 20px;
--transition-duration: 0.3s;
}

@media (prefers-color-scheme: dark) {
:root {
--background-color: #1e1e1e;
--text-color: #ffffff;
--button-bg: #ff624a;
--button-hover-bg: #e65c00;
}
}

@media (prefers-color-scheme: light) {
:root {
--background-color: #ffffff;
--text-color: #000000;
--button-bg: #ff624a;
--button-hover-bg: #e65c00;
}
}

body {
background-color: var(--background-color);
color: var(--text-color);
font-family: var(--font-family), sans-serif;
text-align: center;
padding-top: 100px;
transition: background-color var(--transition-duration) ease, color var(--transition-duration) ease;
}

img {
width: 150px;
margin-bottom: 30px;
}

h1 {
font-size: 36px;
margin-bottom: 20px;
}

a.button {
display: inline-block;
padding: 12px 24px;
background-color: var(--button-bg);
color: #ffffff;
text-decoration: none;
border-radius: var(--button-border-radius);
font-size: 18px;
transition: background-color var(--transition-duration) ease, color var(--transition-duration) ease;
}

a.button:hover {
background-color: var(--button-hover-bg);
}
</style>
<link rel="stylesheet" href="style.css">
</head>
<body>
<img src="lavalink.svg" alt="Lavalink Logo">
Expand Down
150 changes: 150 additions & 0 deletions src/main/resources/static/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
*,
*::before,
*::after {
box-sizing: border-box;
}
:root {
--font-family: Arial;
--button-border-radius: 20px;
--transition-duration: 0.3s;
--primary: #ff624a;
--primary-hover: #fc5827;

--alert-danger: #f8d7da;
--alert-danger-text: #721c24;
--alert-danger-border: #f5c6cb;

--alert-success: #14a936;
--alert-success-text: #154724;
--alert-success-border: #c3e6cb;
}

@media (prefers-color-scheme: dark) {
:root {
--background-color: #1e1e1e;
--background-second-color: #2c2c2c;
--background-third-color: #3c3c3c;
--text-color: #ffffff;
}
}

@media (prefers-color-scheme: light) {
:root {
--background-color: #ffffff;
--background-second-color: #f0f0f0;
--background-third-color: #e0e0e0;
--text-color: #000000;
}
}

body {
background-color: var(--background-color);
color: var(--text-color);
font-family: var(--font-family), sans-serif;
text-align: center;
padding-top: 100px;
transition: background-color var(--transition-duration) ease, color var(--transition-duration) ease;
}

img {
width: 150px;
margin-bottom: 30px;
}

h1 {
font-size: 36px;
margin-bottom: 20px;
}

a.button {
display: inline-block;
padding: 12px 24px;
background-color: var(--primary);
color: #ffffff;
text-decoration: none;
border-radius: var(--button-border-radius);
font-size: 18px;
transition: background-color var(--transition-duration) ease, color var(--transition-duration) ease;
}

a.button:hover {
background-color: var(--primary-hover);
}

.container {
margin-right: auto;
margin-left: auto;
padding-right: 15px;
padding-left: 15px;
}

.form-control {
font-size: 16px;
display: block;
border-radius: .25rem;
width: 100%;
padding: 10px;
user-select: none;
outline: none;
border: 2px solid var(--background-third-color);
background-color: var(--background-second-color);
color: var(--text-color);
}

.form-control:focus {
border-color: var(--primary);
}

form {
max-width: 330px;
padding: 15px;
margin: 0 auto;
}

form p {
padding: 0;
}

label {
width: 1px;
height: 1px;
position: absolute;
overflow: hidden;
}

.btn {
width: 100%;
padding: .5rem 1rem;
font-size: 1.25rem;
line-height: 1.5;
border-radius: .3rem;
color: #fff;
border-style: solid;
background-color: var(--primary);
border-color: var(--primary-hover);
cursor: pointer;
transition: background-color var(--transition-duration) ease, color var(--transition-duration) ease;
}

button:hover {
background-color: var(--primary-hover);
}

.alert {
padding: .75rem 1.25rem;
margin-bottom: 1rem;
border: 1px solid transparent;
border-radius: .25rem
}

.alert-danger {
color: var(--alert-danger-text);
background-color: var(--alert-danger);
border-color: var(--alert-danger-border);
}

.alert-success {
color: var(--alert-success-text);
background-color: var(--alert-success);
border-color: var(--alert-success-border);
}
28 changes: 28 additions & 0 deletions src/main/resources/templates/login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="https://www.thymeleaf.org" lang="en">
<head>
<meta charset="UTF-8">
<title>Please sign in</title>
<link rel="icon" href="lavalink.svg" type="image/svg+xml">
<meta name="darkreader-lock">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<form class="form-signin" method="post" th:action="@{/login}">
<h2 class="form-signin-heading">Please sign in</h2>
<div th:if="${param.error}" class="alert alert-danger" role="alert">Invalid username and password.</div>
<div th:if="${param.logout}" class="alert alert-success" role="alert">You have been signed out</div>
<p>
<label for="username" class="sr-only">Username</label>
<input type="text" id="username" name="username" class="form-control" placeholder="Username" required autofocus>
</p>
<p>
<label for="password" class="sr-only">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
</p>
<button class="btn" type="submit">Sign in</button>
</form>
</div>
</body>
</html>