Skip to content

User Manual v6.2.0

SzymeX edited this page Aug 26, 2026 · 1 revision

PureAuth 6.2.0

PureAuth is an authentication plugin for Minecraft servers running Paper or compatible Purpur builds. It provides password and PIN login, registration, sessions, CAPTCHA, two-factor authentication, recovery questions, Premium Auto-Login, administrative tools, backups, Discord webhooks and optional PlaceholderAPI integration.

PureAuth 6.2.0 adds a persistent progressive login-lock system. It works alongside passwords, PIN, 2FA and recovery, and retains the existing permanent account lock.

This manual covers:

  • Paper/Purpur backend;
  • BungeeCord proxy;
  • Velocity proxy.

The Paper/Purpur module performs player authentication and supplies commands, the PIN GUI and lock displays. BungeeCord and Velocity only synchronize an already authenticated player after a backend switch. A proxy JAR does not replace the Paper JAR.


Contents

  1. Requirements and compatibility
  2. Files and installation
  3. Updating from 6.1.0
  4. Authentication flow
  5. Progressive login lock — new in 6.2.0
  6. PIN authentication
  7. Commands, 2FA and recovery
  8. Administration and permissions
  9. Paper/Purpur configuration
  10. BungeeCord and Velocity configuration
  11. Network synchronization and placeholders
  12. Recommended configurations
  13. Troubleshooting and security
  14. Quick reference

1. Requirements and compatibility

Paper/Purpur backend

Component PureAuth 6.2.0 requirement
Minecraft server line 26.2
API used by the plugin Paper API 26.2.build.117-stable
plugin.yml api-version 26.2
Recommended software Paper 26.2 or compatible Purpur
Plugin bytecode target Java 21
Effective backend requirement Java 25 or newer, required by Paper 26.2
server.properties online-mode=false

The Paper module uses Paper APIs. Spigot, Bukkit and Folia are not supported targets.

PureAuth rejects a player when a protected backend has online-mode=true. The backend must operate in offline mode because PureAuth supplies its own authentication flow.

BungeeCord proxy

Component Requirement
Build API BungeeCord API 1.21-R0.4
Plugin bytecode target Java 21
Recommended network Java Java 25 or newer

Velocity proxy

Component Requirement
Build API Velocity API 3.5.1
Plugin bytecode target Java 21
Recommended network Java Java 25 or newer

Online-mode layout

Standalone Paper/Purpur:

online-mode=false

For a proxy network, the proxy is public while every protected Paper/Purpur backend is offline mode. Firewall backend ports so players cannot bypass the proxy or PureAuth.


2. Files and installation

PureAuth 6.2.0 files:

pureauth-paper-6.2.0-R.jar
pureauth-bungee-6.2.0-R.jar
pureauth-velocity-6.2.0-R.jar
Setup Required JARs
Single Paper/Purpur server Paper JAR only
BungeeCord network Paper JAR on every backend + BungeeCord JAR on proxy
Velocity network Paper JAR on every backend + Velocity JAR on proxy

Do not install both proxy JARs on one proxy.

Standalone Paper/Purpur

  1. Stop the server.
  2. Put the Paper 6.2.0 JAR in plugins.
  3. Set online-mode=false in server.properties.
  4. Start once to generate plugins/PureAuth/config.yml.
  5. Stop, review the config and start again.
  6. Confirm the console reports “PureAuth Paper Module Enabled!”.

SQLite is appropriate for one server:

database:
  type: "SQLITE"

Proxy network

  1. Stop proxy and backends.
  2. Install the matching proxy JAR and Paper JAR on every protected backend.
  3. Set every backend to online-mode=false.
  4. Configure all PureAuth modules with one shared MySQL/MariaDB database and matching table prefix.
  5. Configure proxy forwarding and firewall backend ports.
  6. Start the network and verify backend switching after a successful login.

SQLite must not be shared across servers. MySQL/MariaDB is required for a proxy network.


3. Updating from 6.1.0

  1. Stop every PureAuth backend and proxy.
  2. Back up the database and existing configuration files.
  3. Replace each 6.1.0 JAR with its matching 6.2.0 JAR.
  4. Do not mix 6.1.0 and 6.2.0 modules on one network.
  5. Start a Paper/Purpur backend once to apply the automatic database migration.
  6. Compare custom config with the 6.2.0 default, especially the progressive_lock section and new messages.
  7. Restart the network.
  8. Test password, PIN, 2FA, recovery and controlled failed-login scenarios.

Automatic migration

6.2.0 adds this account column:

temporary_lock_until BIGINT DEFAULT 0

Existing UUIDs, usernames, password hashes, PIN hashes, PIN lengths, 2FA data, recovery data and kick history remain intact. The new field is added automatically for SQLite and MySQL/MariaDB.

Changes added in 6.2.0

  • Three-stage progressive login locks.
  • Default first temporary lock: 30 minutes.
  • Default second temporary lock: 24 hours.
  • Third max-attempt kick: permanent account lock.
  • Persistent timed-lock timestamp that survives restart.
  • Timed lock title, subtitle, actionbar and chat countdown.
  • Automatic restart of normal login/PIN flow after timer expiry.
  • All player commands blocked during temporary and permanent lock.
  • Atomic database write for a max-attempt kick and new lock state.
  • Admin unlock clears permanent flag, temporary timestamp and history.
  • New Polish and English message keys.
  • Correct semantic version comparison in updater.
  • Five-second updater connection timeout and ten-second request timeout.
  • Stable Paper API 26.2.build.117-stable and Velocity API 3.5.1 build dependencies.

4. Authentication flow

Password account

Join -> /register or /login -> optional 2FA -> authenticated

PIN account

Join -> PIN GUI -> optional 2FA -> authenticated

Temporarily locked account

Join -> lock countdown -> timer expires -> normal password/PIN flow

Permanently locked account

Join -> permanent-lock information -> admin unlock required

PIN is the primary credential for a PIN-enabled account. It does not bypass or replace 2FA. Sessions and Premium Auto-Login cannot bypass active PIN verification.

Before authentication, PureAuth blocks movement, interaction, item actions, inventory manipulation and ordinary chat. During a temporary or permanent login lock, all player commands are also cancelled, including login, register and recovery commands.


5. Progressive login lock — new in 6.2.0

5.1 Failed attempts

One strike is added for:

  • wrong password entered through /login;
  • wrong PIN submitted in the PIN GUI;
  • wrong 2FA login code;
  • wrong backup code used during the login 2FA stage.

The connection-level limit is controlled by settings.max_attempts and defaults to 3. Reaching the limit produces one kick and records one persistent kick stage.

5.2 Default stages

Max-attempt kick count Default action Behaviour on later join
1 kick + 30-minute timed login lock player may join but cannot authenticate
2 kick + 24-hour timed login lock player may join but cannot authenticate
3 kick + permanent account lock admin unlock is required

The stage uses persistent kick_count, not the temporary current-connection strike counter. Restarting a server never resets the stage.

5.3 First and second temporary lock

After the final failed attempt, PureAuth cancels normal prompts, saves the penalty first and then kicks the player. It uses the temporary_lock_kick message.

When the player reconnects before expiry:

  1. the connection is allowed;
  2. the player stays in PureAuth’s protected unauthenticated state;
  3. title/subtitle, actionbar and optional chat show remaining time;
  4. every player command is cancelled;
  5. the usual login timeout is not running;
  6. the timer checks the expiry every second;
  7. on expiry, temporary_lock_until is cleared and normal login begins automatically.

The title and actionbar refresh every second. Chat is sent immediately and then every reminder_interval_seconds.

5.4 Permanent lock

The permanent threshold is settings.security.kicks_before_lock, default 3. At that count PureAuth writes locked=true and clears a temporary timestamp.

Permanent lock has no automatic expiry. It uses title_locked, subtitle_locked and error_locked_chat after join, plus permanent_lock_kick for the kick that creates the permanent lock.

5.5 Successful login and history

Default:

reset_history_after_successful_login: false

This preserves the intended escalation:

first temporary lock -> successful login -> next max-attempt kick is second temporary lock

Set reset_history_after_successful_login to true only if a correct login should erase the history. With true, successful authentication resets kick_count and temporary_lock_until for an account that is not permanently locked.

5.6 Disabling or changing the policy

Setting Behaviour
account_lock_enabled: false max-attempt kicks remain, but no timed or permanent database lock is applied
progressive_lock.enabled: false disables the first/second timed stages; permanent locking still follows kicks_before_lock
kicks_before_lock permanent threshold; values below 1 are safely treated as 1
first_lock_seconds / second_lock_seconds timed stage duration; values below 0 are safely treated as 0

Setting a temporary duration to 0 means the kick does not leave an active timed lock.

5.7 Administrator unlock

/pureauth unlock <player>
/pa unlock <player>

Unlock clears:

  • locked;
  • temporary_lock_until;
  • kick_count.

The runtime lock state is cleared too. An online unauthenticated target is safely disconnected so a clean join starts the normal flow.


6. PIN authentication

Setting a PIN

After normal login:

/setpin

The user clicks player-head number buttons 0–9, enters a new PIN and repeats it. Default length is six digits; 1–9 is supported. PIN is stored only as a BCrypt hash.

PIN login

A PIN-enabled account automatically receives the GUI:

Join -> PIN GUI -> optional 2FA -> authenticated

For such account, /login is blocked while PIN support is enabled.

Change or remove

/changepass       # PIN account: current PIN -> new PIN -> confirmation
/rempin           # removes PIN and restores password login

Closing PIN GUI

Closing the PIN login window halts normal login for that connection and tells the player to reconnect. Recovery instructions are shown only if recovery is enabled and configured. Closing PIN setup or PIN change cancels only that operation.

Closing a GUI does not create a strike or progressive lock.


7. Commands, 2FA and recovery

Player commands

Command Description
/register [captcha] creates password account
/login password login; unavailable for active PIN/locked accounts
/changepass password change
/changepass PIN change GUI for PIN accounts
/setpin PIN setup GUI
/rempin restores password login
/premium enables IP-trust Premium Auto-Login
/cracked disables Premium Auto-Login
/2fa setup starts 2FA setup
/2fa remove removes 2FA after code confirmation
/2fa recovery uses backup code where permitted
/recovery setup/remove/start/pass recovery management and recovery

All entries above are blocked while a temporary or permanent login lock is active.

2FA

Password -> 2FA -> authenticated
PIN GUI -> 2FA -> authenticated

Set up 2FA with /2fa setup after login. A player adds the generated secret to an authenticator app and enters the current six-digit code. Backup codes are created after setup.

Wrong 2FA login codes participate in max-attempt strike counting. Correct 2FA does not reset persistent escalation history unless reset_history_after_successful_login is true.

Recovery

Enable:

settings:
  recovery:
    enabled: true

Commands:

/recovery setup
/recovery remove
/recovery start
/recovery pass <new_password> <new_password>

For a PIN account, successful password recovery atomically saves the new password and removes the forgotten PIN. Recovery cannot run while a progressive temporary/permanent lock is active, because every player command is intentionally blocked during that state.


8. Administration and permissions

Administrative entry points:

/pureauth
/pa
Command Permission Notes
/pureauth reload pureauth.admin.reload reloads config and cached PIN GUI elements
/pureauth stats pureauth.admin.stats statistics
/pureauth info pureauth.admin.info displays account and lock information
/pureauth unlock pureauth.admin.unlock clears all lock state/history
/pureauth unregister pureauth.admin.unregister deletes account
/pureauth register pureauth.admin.register registers account
/pureauth forcelogin pureauth.admin.forcelogin completes online login
/pureauth setpassword pureauth.admin.setpassword replaces password
/pureauth setpin pureauth.admin.pin sets absent PIN
/pureauth changepin pureauth.admin.pin replaces PIN
/pureauth rempin pureauth.admin.pin removes PIN
/pureauth accounts pureauth.admin.accounts lists IP accounts
/pureauth location <login register> pureauth.admin.location

Info output includes:

  • Locked;
  • Temporary Lock Until;
  • Failed Login Kicks;
  • PIN Enabled;
  • Recovery and 2FA state.

If settings.safe_mode is true, sensitive account commands are console-only. PINs and passwords are redacted from administration audit logs.

Declared permissions:

pureauth.admin
pureauth.admin.reload
pureauth.admin.stats
pureauth.admin.unlock
pureauth.admin.unregister
pureauth.admin.register
pureauth.admin.forcelogin
pureauth.admin.info
pureauth.admin.setpassword
pureauth.admin.accounts
pureauth.admin.location
pureauth.admin.pin
pureauth.admin.guard

9. Paper/Purpur configuration

File:

plugins/PureAuth/config.yml

Database

database:
  type: "SQLITE" # SQLITE or MYSQL
  pool:
    maximum_pool_size: -1
    minimum_idle: -1
    connection_timeout_ms: 10000
    idle_timeout_ms: 600000
    max_lifetime_ms: 1800000
  mysql:
    host: "localhost"
    port: 3306
    database: "minecraft"
    username: "root"
    password: "password"
    table_prefix: "pureauth_"

SQLite data is stored locally at plugins/PureAuth/database.db. Use a dedicated MySQL/MariaDB user for production networks.

Complete progressive lock section

settings:
  security:
    account_lock_enabled: true
    kicks_before_lock: 3
    progressive_lock:
      enabled: true
      first_lock_seconds: 1800
      second_lock_seconds: 86400
      reset_history_after_successful_login: false
      reminder_interval_seconds: 10
      display:
        title: true
        chat: true
        actionbar: true

  login_timeout: 60
  max_attempts: 3
Key Default Exact effect
max_attempts 3 wrong attempts in one connection before kick
account_lock_enabled true stores persistent timed/permanent penalties
kicks_before_lock 3 kick count that becomes permanent
progressive_lock.enabled true enables stage one and stage two
first_lock_seconds 1800 first stage, 30 minutes
second_lock_seconds 86400 second stage, 24 hours
reset_history_after_successful_login false clears or preserves history after successful login
reminder_interval_seconds 10 interval between chat reminders
display.title true title/subtitle countdown
display.chat true lock chat notices
display.actionbar true actionbar countdown

A reminder interval below 1 is safely treated as 1 second.

New messages

Add/retain these keys in messages.en and messages.pl:

temporary_lock_title
temporary_lock_subtitle
temporary_lock_chat
temporary_lock_actionbar
temporary_lock_kick
temporary_lock_expired
permanent_lock_kick
lock_database_error_kick

Time placeholders:

Placeholder Meaning
%time% formatted remaining duration, such as 30m 0s or 24h 0m 0s
%seconds% remaining whole seconds

The existing title_locked, subtitle_locked and error_locked_chat keys remain the permanent-lock join display.

PIN, sessions and other settings

settings:
  pin:
    enabled: true
    length: 6
  sessions:
    enabled: true
    time_minutes: 1
  premium_login:
    enabled: true
    require_same_ip: true
  recovery:
    enabled: true
  admin_guard:
    enabled: true
  update_checker: true

The full PIN GUI configuration, player-head textures, digit item names/lore, input indicators, controls and sounds stay under settings.pin.gui. PIN supports 1–9 digits and uses six safely for invalid values.

The update checker now has a five-second connection timeout and a ten-second request timeout. It compares semantic versions and will not announce an older Modrinth version as an update.

Discord

settings:
  discord:
    enabled: false
    events:
      failed_attempts: true
      account_locked: true

One max-attempt kick triggers failed_attempts. A temporary or permanent stage also triggers account_locked.


10. BungeeCord and Velocity configuration

BungeeCord

File:

plugins/PureAuth/config.yml
database:
  type: MYSQL
  mysql:
    host: "localhost"
    port: 3306
    database: "pureauth"
    username: "root"
    password: ""
    table_prefix: "pureauth_"
network:
  mode: "LOCAL"

Use the same database and prefix as Paper. The Bungee module holds authenticated UUIDs for active connections and forwards their success after backend change. It has no PIN GUI, timed lock display or player commands.

Velocity

File:

plugins/pureauth/config.yml
database:
  driver: "MYSQL"
  host: "localhost"
  port: "3306"
  database: "pureauth"
  username: "root"
  password: ""
  prefix: "pureauth_"
network:
  mode: "LOCAL"

Velocity uses driver and prefix rather than the Paper/Bungee type and mysql.table_prefix keys. It registers the same synchronization channel but does not provide GUI/commands.


11. Network synchronization and placeholders

Paper sends this after successful backend authentication:

PLAYER_LOGIN:<uuid>

The proxy sends this after a backend switch:

AUTH_SUCCESS:<uuid>

Reliable synchronization requires matching PureAuth 6.2.0 modules, one correct proxy JAR, Paper on every protected backend, shared MySQL/MariaDB, matching prefix, working plugin messaging, consistent forwarding and protected backend ports.

LOCAL mode keeps authenticated UUIDs in one proxy’s memory until disconnect. It is not a multi-proxy Redis implementation.

PlaceholderAPI is optional on Paper:

%pureauth_logged%   -> true / false
%pureauth_has_2fa%  -> true / false

12. Recommended configurations

Production standalone server

database:
  type: "SQLITE"
  pool:
    maximum_pool_size: 1
    minimum_idle: 1

settings:
  security:
    account_lock_enabled: true
    kicks_before_lock: 3
    progressive_lock:
      enabled: true
      first_lock_seconds: 1800
      second_lock_seconds: 86400
      reset_history_after_successful_login: false
      reminder_interval_seconds: 10
      display:
        title: true
        chat: true
        actionbar: true
  pin:
    enabled: true
    length: 6

Short test durations only

Use only in a private test environment:

settings:
  security:
    progressive_lock:
      first_lock_seconds: 5
      second_lock_seconds: 10

Restore production durations after testing.

Proxy network

Use MySQL/MariaDB for every module. Keep the account-lock policy consistent on all Paper backends, otherwise a player may receive a different lock policy after a switch.


13. Troubleshooting and security

“Login blocked” after a kick

Expected in 6.2.0. Rejoin to see the countdown or wait until it expires. The player can stay connected while the temporary block counts down.

No commands work during countdown

Expected. Every player command, including login/register/recovery, is blocked while the lock is active.

Player was kicked but can join again

Expected for first and second stage. The kick ends the failed attempt. A later connection is allowed only so the player can see the remaining lock time.

Player cannot authenticate at all

Check:

/pureauth info <player>
/pureauth unlock <player>

Permanent lock requires administrator action. The unlock command also clears escalation history.

Temporary lock survived restart

Expected when its timestamp is still future. This persistence is intentional. The next join or online timer clears it after expiry.

Escalation does not continue after successful login

Inspect reset_history_after_successful_login. Default false preserves escalation. True resets history after successful authentication.

No title, chat or actionbar

Check:

settings.security.progressive_lock.display.title
settings.security.progressive_lock.display.chat
settings.security.progressive_lock.display.actionbar

Then confirm the matching language block contains every temporary_lock message key.

Database penalty error

PureAuth fails closed: it kicks rather than allowing an unrecorded max-attempt penalty. Check database connection, credentials, table prefix, firewall and pool timeout.

PIN GUI does not open

Check settings.pin.enabled, account PIN state and the Paper JAR. A proxy JAR alone never opens a GUI.

Security checklist

  • Keep account_lock_enabled and progressive_lock.enabled enabled in production.
  • Keep default 3 attempts, 30 minutes and 24 hours unless policy requires different values.
  • Keep reset_history_after_successful_login false when repeated abuse should escalate.
  • Use strong passwords even with PIN.
  • Enable 2FA for staff and Admin Guard.
  • Enable safe mode for sensitive commands.
  • Use a dedicated MySQL/MariaDB user for networks.
  • Protect backend ports and forwarding secrets.
  • Encourage recovery setup and offline 2FA backup-code storage.
  • Back up the database before updates and test restoration.
  • Never publish database passwords or Discord webhooks.

14. Quick reference

Lock defaults

3 wrong attempts -> kick
1st max-attempt kick -> 30-minute login lock
2nd max-attempt kick -> 24-hour login lock
3rd max-attempt kick -> permanent account lock

Essential lock configuration

settings:
  max_attempts: 3
  security:
    account_lock_enabled: true
    kicks_before_lock: 3
    progressive_lock:
      enabled: true
      first_lock_seconds: 1800
      second_lock_seconds: 86400
      reset_history_after_successful_login: false

Lock administration

/pureauth info <player>
/pureauth unlock <player>
/pa info <player>
/pa unlock <player>

Module placement

Standalone: Paper JAR on Paper/Purpur
Bungee:     Paper JAR on every backend + BungeeCord JAR on proxy
Velocity:   Paper JAR on every backend + Velocity JAR on proxy

PureAuth 6.2.0 is developed by SzymeX Dev Studio.

Clone this wiki locally