Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
6922038
update default gradleJvm version
Navio1430 Jun 20, 2026
6b37355
common: move CredentialsHasher interface from infra to domain
Navio1430 Jun 20, 2026
5a5e93e
velocity: fix register command always using BCrypt instead of the sel…
Navio1430 Jun 20, 2026
82ba3bb
common & velocity: add encryption queue & integrate with password ver…
Navio1430 Jun 20, 2026
5df997a
remove unused vars and statements
Navio1430 Jun 20, 2026
792aa8e
update changelog
Navio1430 Jun 20, 2026
3f60b05
add Argon2 settings
Navio1430 Jun 20, 2026
713a98e
add more Argon2 tests
Navio1430 Jun 20, 2026
c3a5c38
add mojang profile API order (fallback), add minetools as preferred f…
Navio1430 Jun 20, 2026
13b0909
update changelog
Navio1430 Jun 20, 2026
1b343da
fix: bind subconfigs recursively in TestsConfigModule
Navio1430 Jun 20, 2026
25dd31b
integrate password hashing with encryption queue; improve queue with …
Navio1430 Jun 26, 2026
e278510
add logging-in message
Navio1430 Jun 26, 2026
687b047
update /register cmd - send registeringInfo message only if there's n…
Navio1430 Jun 26, 2026
b4931f9
update messages config - move loggingInInfo property
Navio1430 Jun 26, 2026
c0baeda
bump version to 0.2.0
Navio1430 Jul 8, 2026
011af0c
add navauth-shadow convention plugin; init ajqueue integration plugin
Navio1430 Jul 11, 2026
df46001
do not authenticate if player not online
Navio1430 Jul 11, 2026
8f0a808
add NavAuthAPI#isAuthenticated(UUID); impl cancelQueueJoinEventIfNotA…
Navio1430 Jul 11, 2026
babb4fd
update CHANGELOG.md
Navio1430 Jul 11, 2026
7e4166b
migrate to new blossom plugin version
Navio1430 Jul 11, 2026
071701a
fix: use MojangProfileService instead of ProfileService in CompositeP…
Navio1430 Jul 11, 2026
25fc1de
fix: don't self register velocity main class (already registered)
Navio1430 Jul 12, 2026
9b9bf48
fix same letter case username migration
Navio1430 Jul 13, 2026
64d1174
add UsernameResolutionServiceIntegrationTests
Navio1430 Jul 13, 2026
6ab7ea1
changelog typo
Navio1430 Jul 22, 2026
909fb38
fix: re-fetch user for handshake session after username resolution ch…
Navio1430 Jul 22, 2026
1ee363f
update readme
Navio1430 Jul 22, 2026
fb4fb0e
ajqueue: add navauth version check
Navio1430 Jul 23, 2026
47437ad
docs: add AjQueue integration info
Navio1430 Jul 23, 2026
9afd76d
update changelog
Navio1430 Jul 23, 2026
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
16 changes: 15 additions & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

## 0.2.0

### Changes
```diff
+ Encryption queue (backpressure especially for Argon2 and BCrypt hashing methods which can lead to OOM killer)
+ Argon2 configuration settings
+ Mojang profile API order (API fallback)
+ MineTools profile API support (preferred one by default)
+ NavAuthAPI.isAuthenticated(UUID) method for checking player auth state
+ AjQueue integration plugin
```

### Fixes
- fix register command always using BCrypt instead of the selected algo
- fix different letter case same username migration

### API
```diff
+ NavAuthAPI#isAuthenticated(UUID)
```

### Config
**General** config:
```diff
+ encryptionQueueConfig
+ mojangAPIConfig
+ Argon2 settings
```

**Messages** config:
```diff
+ unexpectedErrorOccurred
+ processAlreadyInProgressError
+ alreadyTryingToLoginError
+ registeringInfo
+ loggingInInfo
```

### New integration for AjQueue (as a separate plugin)
- Automatically adds authenticated players to a configurable AjQueue queue
- Optionally cancel AjQueue `PreQueueEvent` for unauthenticated players

### Docs
- AjQueue integration info
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ We are working on additional configuration options and other improvements to pre
- **[Multification](https://navio1430.github.io/NavAuth/docs/configuration/multification.html)**
- [Migration from other plugins](https://navio1430.github.io/NavAuth/docs/migration/migration.html)
- [Database type migrations](https://navio1430.github.io/NavAuth/docs/migration/database-type-migration.html)
- Configurable encryption queue
- Configurable external Mojang profile API usage

### 🧩 Integrations
- AjQueue integration

### 🔒 In NavAuth password cracking takes more than TWELVE TRILLION (1.2 × 10^13) times longer than in the worst login plugins.
Cracking the whole database of a bad plugin takes less than a **FEW MINUTES**.
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repositories {

allprojects {
group = "pl.spcode.navauth"
version = "0.1.6-SNAPSHOT"
version = "0.2.0-SNAPSHOT"
}

tasks.register("formatAll") {
Expand Down
13 changes: 13 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
`kotlin-dsl`
`java-library`
}

repositories {
gradlePluginPortal()
mavenCentral()
}

dependencies {
implementation("com.gradleup.shadow:shadow-gradle-plugin:9.2.0")
}
50 changes: 50 additions & 0 deletions buildSrc/src/main/kotlin/navauth-shadow.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package buildsrc

import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar

plugins {
id("com.gradleup.shadow")
}

val relocatePrefix = "pl.spcode.navauth.lib"

tasks.named<ShadowJar>("shadowJar") {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE

fun relocatePrefixed(pkg: String) {
relocate(pkg, "$relocatePrefix.$pkg")
}

relocate("com.google", "$relocatePrefix.com.google") {
exclude("com/google/inject/**")
exclude("com/google/gson/**")
}

exclude("com/google/inject/**")
exclude("com/google/gson/**")

exclude("org/slf4j/**")

relocatePrefixed("kotlin")
relocatePrefixed("org.bstats")
relocatePrefixed("at.favre")
relocatePrefixed("com.eternalcode")
relocatePrefixed("com.j256")
relocatePrefixed("com.mysql")
relocatePrefixed("com.zaxxer")
relocatePrefixed("dev.rollczi")
relocatePrefixed("eu.okaeri")
relocatePrefixed("google.protobuf")
relocatePrefixed("jakarta.inject")
relocatePrefixed("javax.annotation")
relocatePrefixed("org.aopalliance")
relocatePrefixed("org.bouncycastle")
relocatePrefixed("org.checkerframework")
relocatePrefixed("org.h2")
relocatePrefixed("org.intellij")
relocatePrefixed("org.jetbrains")
relocatePrefixed("org.postgresql")
// todo make sure we relocate this or something
// relocatePrefixed("org.sqlite")
relocatePrefixed("org.yaml")
}
25 changes: 25 additions & 0 deletions docs/docs/integrations/ajqueue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# AjQueue Integration

NavAuth provides a separate plugin that integrates with [AjQueue](https://www.spigotmc.org/resources/ajqueue.99086/), a popular queue management system for Velocity proxy.

## How it Works

The integration plugin listens for NavAuth's `UserAuthenticatedEvent`. When a player successfully authenticates, the plugin automatically adds them to a configurable AjQueue queue.

Additionally, it can optionally cancel AjQueue's `PreQueueEvent` for players who are **not yet authenticated**, preventing unauthenticated players from joining a server through the queue.

## Features

- Automatically adds authenticated players to a specified AjQueue queue
- Optionally block queue join for unauthenticated players
- Configurable failure handling (message + optional kick)

## Download

The integration plugin jar is available on the [GitHub releases page](https://github.com/Navio1430/NavAuth).

## Installation

1. Place the `navauth-ajqueue-integration-XXX.jar` in your Velocity server's `plugins/` directory
2. Ensure both **NavAuth** and **AjQueue** are installed
3. Restart your proxy
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
velocity-api = "3.4.0-SNAPSHOT"
# plugins
shadow = "9.2.0"
blossom = "1.2.0"
blossom = "2.2.0"
spotless = "8.0.0"
litecommands = "3.10.6"

Expand Down
47 changes: 47 additions & 0 deletions integration/ajqueue/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
plugins {
id("buildsrc.navauth-shadow")
id("net.kyori.blossom") version "2.2.0"
kotlin("jvm")
kotlin("kapt")
}

val projectName = "navauth-ajqueue-integration"

group = "pl.spcode.navauth"
version = "1.0.0-SNAPSHOT"

val requiredMinNavAuthVersion = "0.2.0" // always X.Y.Z format

sourceSets {
main {
blossom {
kotlinSources {
property("version", project.version.toString())
property("requiredMinNavAuthVersion", requiredMinNavAuthVersion)
}
}
}
}

tasks.shadowJar {
destinationDirectory.set(file("../../target"))

archiveBaseName.set(projectName)
archiveClassifier = null

exclude("kotlin/**")
exclude("META-INF/**")
exclude("org/jetbrains/**")
exclude("org/intellij/**")
}

repositories {
maven { url = uri("https://repo.ajg0702.us/releases") }
}

dependencies {
compileOnly(project(":navauth-common"))
compileOnly(libs.velocitypowered.velocity.api)
kapt(libs.velocitypowered.velocity.api)
compileOnly("us.ajg0702.queue.api:api:2.9.1")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package pl.spcode.navauth.integration.ajqueue

class BuildParameters {
companion object {
const val VERSION = "{{ version }}"
const val REQUIRED_MIN_NAVAUTH_VERSION = "{{ requiredMinNavAuthVersion }}"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/*
* NavAuth
* Copyright © 2026 Oliwier Fijas (Navio1430)
*
* NavAuth is free software; You can redistribute it and/or modify it under the terms of:
* the GNU Affero General Public License version 3 as published by the Free Software Foundation.
*
* NavAuth is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with NavAuth. If not, see <https://www.gnu.org/licenses/>
* and navigate to version 3 of the GNU Affero General Public License.
*
*/

package pl.spcode.navauth.integration.ajqueue

import com.google.inject.Inject
import com.google.inject.Injector
import com.velocitypowered.api.event.Subscribe
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent
import com.velocitypowered.api.plugin.Dependency
import com.velocitypowered.api.plugin.Plugin
import com.velocitypowered.api.plugin.annotation.DataDirectory
import com.velocitypowered.api.proxy.ProxyServer
import java.nio.file.Path
import net.kyori.adventure.text.Component
import org.slf4j.Logger
import pl.spcode.navauth.api.NavAuthAPI
import pl.spcode.navauth.common.module.YamlConfigModule
import pl.spcode.navauth.common.shared.utils.VersionUtils
import pl.spcode.navauth.integration.ajqueue.config.GeneralConfig
import pl.spcode.navauth.integration.ajqueue.listener.AjQueueListeners
import pl.spcode.navauth.integration.ajqueue.listener.NavAuthListeners

@Plugin(
id = "navauth-ajqueue",
name = "NavAuth AJQueue Integration",
version = BuildParameters.VERSION,
dependencies = [Dependency(id = "navauth"), Dependency(id = "ajqueue")],
authors = ["Navio1430"],
)
class AjQueueIntegrationPlugin
@Inject
constructor(
val parentInjector: Injector,
@param:DataDirectory val dataDirectory: Path,
val logger: Logger,
val proxyServer: ProxyServer,
) {

@Subscribe
fun onProxyInitializeEvent(event: ProxyInitializeEvent) {
try {
logger.info("Initializing NavAuth AJQueue integration...")

val navAuthVersion =
VersionUtils.parseVersion(
proxyServer.pluginManager
.getPlugin("navauth")
.orElseThrow { RuntimeException("NavAuth plugin not found") }
.description
.version
.get()
)
val requiredVersion = VersionUtils.parseVersion(BuildParameters.REQUIRED_MIN_NAVAUTH_VERSION)

if (VersionUtils.isVersionOlderThan(navAuthVersion, requiredVersion)) {
logger.error(
"""
|NavAuth version {} is too old. Required minimum version is {}.
|Please update NavAuth to at least version {}.
|Download the latest version from: https://github.com/Navio1430/NavAuth"""
.trimMargin(),
navAuthVersion,
requiredVersion,
requiredVersion,
)
return
}

val configModule =
YamlConfigModule(GeneralConfig::class, dataDirectory.resolve("config.yml").toFile())

val childInjector = parentInjector.createChildInjector(configModule)

val eventBus = NavAuthAPI.getInstance().eventBus
eventBus.register(childInjector.getInstance(NavAuthListeners::class.java))

val ajQueueListeners = childInjector.getInstance(AjQueueListeners::class.java)
ajQueueListeners.registerAll()

logger.info("NavAuth AJQueue integration initialized successfully")
} catch (ex: Exception) {
logger.error("Failed to initialize NavAuth AJQueue integration", ex)
proxyServer.shutdown(Component.text("Failed to initialize NavAuth AJQueue integration"))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* NavAuth
* Copyright © 2026 Oliwier Fijas (Navio1430)
*
* NavAuth is free software; You can redistribute it and/or modify it under the terms of:
* the GNU Affero General Public License version 3 as published by the Free Software Foundation.
*
* NavAuth is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with NavAuth. If not, see <https://www.gnu.org/licenses/>
* and navigate to version 3 of the GNU Affero General Public License.
*
*/

package pl.spcode.navauth.integration.ajqueue.config

import eu.okaeri.configs.OkaeriConfig
import eu.okaeri.configs.annotation.Comment
import pl.spcode.navauth.common.component.TextComponent

class GeneralConfig : OkaeriConfig() {

@Comment("Name of the ajQueue queue to send authenticated players to")
var queueName: String = "lobby"

@Comment("Message sent when adding player to queue fails")
var queueAddFailMessage: TextComponent = TextComponent("<red>Failed to add you to the queue!")

@Comment("Whether to kick the player if adding them to the queue fails")
var kickOnQueueAddFail: Boolean = false

@Comment("Whether to cancel the AjQueue PreQueueEvent if the player is not authenticated yet")
var cancelQueueJoinEventIfNotAuth: Boolean = false
}
Loading
Loading