Compare commits
11 commits
Author | SHA1 | Date | |
---|---|---|---|
9283b9e925 | |||
e0f3d7e914 | |||
f93f21d2c6 | |||
147c8fe3af | |||
3d9cfa0207 | |||
fa187bb766 | |||
cac64864c6 | |||
7482c3cdfe | |||
0af2923ef2 | |||
af36e13307 | |||
ce267a4c66 |
9 changed files with 435 additions and 9 deletions
|
@ -29,5 +29,5 @@ jobs:
|
||||||
- name: ⬆️ Upload artifacts
|
- name: ⬆️ Upload artifacts
|
||||||
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
|
uses: https://code.forgejo.org/forgejo/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: '${{ github.event.repository.name }}-${{ github.event.repository.default_branch }}-${{ github.ref_name }}.zip'
|
name: '${{ github.event.repository.name }}-${{ github.ref_name }}.zip'
|
||||||
path: build/libs/
|
path: build/libs/
|
27
README.md
27
README.md
|
@ -7,9 +7,32 @@
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Support for other mod loaders is not planned. PRs implementing such support will not be accepted, please fork this project instead.
|
||||||
|
|
||||||
|
> [!WARNING]
|
||||||
|
> This mod does not provide support for standard permission systems, and by default only verifies permissions by operator status (i.e. commands can only be run by operators).
|
||||||
|
|
||||||
|
## Supported versions
|
||||||
|
|
||||||
|
| Version | Support level |
|
||||||
|
| ------- | ------------- |
|
||||||
|
| 1.20.1 | ✅ Fully supported |
|
||||||
|
| * | ❌ Not supported |
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
Download the latest release from the releases tab or go to the [latest release directly](https://code.lilyvex.dev/lily/oauth-fabric/releases/latest), then put it in your Fabric server's `mods` directory.
|
Download the latest release from the releases tab or go to the [latest release directly](https://code.lilyvex.dev/lily/oauth-fabric/releases/latest), you may optionally choose to build from source, then put it in your Fabric server's `mods` directory.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
On initial load, this mod will create a commented configuration file. Edit the created file to contain the correct credentials for your OAuth provider, then restart the server.
|
||||||
|
|
||||||
|
Players who are not registered will be kicked on join and given a link to the OAuth provider, where they can login to register for the server.
|
||||||
|
|
||||||
|
Each new login with create a new session which will expire after a set period of time (usually defined by your OAuth provider).
|
||||||
|
|
||||||
|
Use the `/oauth` command to see a list of all available commands.
|
||||||
|
|
||||||
## Building from source
|
## Building from source
|
||||||
|
|
||||||
|
@ -30,4 +53,4 @@ gradlew.bat build
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Fork this repository and create a branch for your changes, then create a pull request for the `main` branch with a "why", "what", and "how" to explain your changes.
|
Fork this repository and create a branch for your changes, then create a pull request for the `dev` branch with a "why", "what", and "how" to explain your changes.
|
||||||
|
|
17
build.gradle
17
build.gradle
|
@ -30,6 +30,13 @@ loom {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
include {
|
||||||
|
canBeResolved = true
|
||||||
|
canBeConsumed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// To change the versions see the gradle.properties file
|
// To change the versions see the gradle.properties file
|
||||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||||
|
@ -39,6 +46,12 @@ dependencies {
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
|
||||||
|
// OAuth2 library
|
||||||
|
implementation 'com.google.oauth-client:google-oauth-client:1.39.0'
|
||||||
|
|
||||||
|
// Configuration library
|
||||||
|
include 'com.electronwill.night-config:toml:3.6.0'
|
||||||
|
implementation 'com.electronwill.night-config:toml:3.6.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
@ -69,6 +82,10 @@ jar {
|
||||||
from("LICENSE") {
|
from("LICENSE") {
|
||||||
rename { "${it}_${inputs.properties.archivesName}"}
|
rename { "${it}_${inputs.properties.archivesName}"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
from {
|
||||||
|
configurations.include.collect { it.isDirectory() ? it : zipTree(it) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure the maven publication
|
// configure the maven publication
|
||||||
|
|
|
@ -5,6 +5,8 @@ import net.fabricmc.api.ModInitializer;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import dev.lilyvex.oauthfabric.database.Database;
|
||||||
|
|
||||||
public class OAuthFabric implements ModInitializer {
|
public class OAuthFabric implements ModInitializer {
|
||||||
public static final String MOD_ID = "oauth-fabric";
|
public static final String MOD_ID = "oauth-fabric";
|
||||||
|
|
||||||
|
@ -19,6 +21,12 @@ public class OAuthFabric implements ModInitializer {
|
||||||
// However, some things (like resources) may still be uninitialized.
|
// However, some things (like resources) may still be uninitialized.
|
||||||
// Proceed with mild caution.
|
// Proceed with mild caution.
|
||||||
|
|
||||||
LOGGER.info("Hello Fabric world!");
|
OAuthFabricConfig oAuthFabricConfig = new OAuthFabricConfig();
|
||||||
|
oAuthFabricConfig.load();
|
||||||
|
|
||||||
|
Database database = new Database();
|
||||||
|
database.setDatabase(oAuthFabricConfig.getDatabase());
|
||||||
|
|
||||||
|
LOGGER.info("oauth-fabric: Initialized");
|
||||||
}
|
}
|
||||||
}
|
}
|
131
src/main/java/dev/lilyvex/oauthfabric/OAuthFabricConfig.java
Normal file
131
src/main/java/dev/lilyvex/oauthfabric/OAuthFabricConfig.java
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
package dev.lilyvex.oauthfabric;
|
||||||
|
|
||||||
|
import com.electronwill.nightconfig.core.CommentedConfig;
|
||||||
|
import com.electronwill.nightconfig.core.io.ParsingException;
|
||||||
|
import com.electronwill.nightconfig.core.io.ParsingMode;
|
||||||
|
import com.electronwill.nightconfig.toml.TomlParser;
|
||||||
|
import com.electronwill.nightconfig.toml.TomlWriter;
|
||||||
|
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.NoSuchFileException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class OAuthFabricConfig {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger("oauth-fabric");
|
||||||
|
private static final String DEFAULT_PROVIDER = "auth.lilyvex.dev";
|
||||||
|
private static final String DEFAULT_CLIENT_ID = "minecraft";
|
||||||
|
private static final String DEFAULT_CLIENT_SECRET = "<No default secret>";
|
||||||
|
private static final String DEFAULT_REDIRECT_URI = "mc.lilyvex.dev/oauth2";
|
||||||
|
private static final String DEFAULT_DATABASE = "sqlite";
|
||||||
|
|
||||||
|
private static final Path CONFIG_FILE_PATH = FabricLoader.getInstance().getConfigDir()
|
||||||
|
.resolve("oauth-fabric.toml")
|
||||||
|
.normalize();
|
||||||
|
|
||||||
|
private final CommentedConfig config = CommentedConfig.inMemory();
|
||||||
|
|
||||||
|
// URL to the OAuth provider (e.g. accounts.google.com, discord.com/oauth2)
|
||||||
|
private String provider;
|
||||||
|
|
||||||
|
// ID of the OAuth client. This is usually defined when creating the OAuth application.
|
||||||
|
private String client_id;
|
||||||
|
|
||||||
|
// Client secret
|
||||||
|
private String client_secret;
|
||||||
|
|
||||||
|
// URI to redirect to. Ensure that this URI is listed in the allowed redirect URIs section
|
||||||
|
// of your OAuth provider.
|
||||||
|
private String redirect_uri;
|
||||||
|
|
||||||
|
// Which database to use (SQLite is currently the only supported database).
|
||||||
|
private String database;
|
||||||
|
|
||||||
|
public String getProvider() {
|
||||||
|
return provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return client_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientSecret() {
|
||||||
|
return client_secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRedirectUri() {
|
||||||
|
return redirect_uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDatabase() {
|
||||||
|
return database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load() {
|
||||||
|
this.config.setComment("provider", "URL to the OAuth provider (e.g. accounts.google.com, discord.com/oauth2)");
|
||||||
|
this.config.set("provider", DEFAULT_PROVIDER);
|
||||||
|
|
||||||
|
this.config.setComment("client_id", "ID of the OAuth client. This is usually defined when creating the OAuth application.");
|
||||||
|
this.config.set("client_id", DEFAULT_CLIENT_ID);
|
||||||
|
|
||||||
|
this.config.setComment("client_secret", "");
|
||||||
|
this.config.set("client_secret", DEFAULT_CLIENT_SECRET);
|
||||||
|
|
||||||
|
this.config.setComment("redirect_uri", "URI to redirect to. Ensure that this URI is listed in the allowed redirect URIs section of your OAuth provider.");
|
||||||
|
this.config.set("redirect_uri", DEFAULT_REDIRECT_URI);
|
||||||
|
|
||||||
|
this.config.setComment("database", "Which database to use (SQLite is currently the only supported database).");
|
||||||
|
this.config.set("database", DEFAULT_DATABASE);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.loadFromFile(true);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.info("oauth-fabric: Configuration loaded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadFromFile(boolean firstAttempt) throws IOException {
|
||||||
|
try (var reader = Files.newBufferedReader(CONFIG_FILE_PATH)) {
|
||||||
|
new TomlParser().parse(reader, this.config, ParsingMode.REPLACE);
|
||||||
|
} catch (NoSuchFileException | FileNotFoundException e) {
|
||||||
|
if (!firstAttempt) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.copyDefaultFile();
|
||||||
|
this.loadFromFile(true);
|
||||||
|
} catch (ParsingException e) {
|
||||||
|
if (!firstAttempt) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
var backupPath = CONFIG_FILE_PATH.resolveSibling("oauth-fabric.toml.old").toAbsolutePath().normalize();
|
||||||
|
|
||||||
|
LOGGER.error("oauth-fabric: Failed to parse configuration file, THIS IS BAD.", e);
|
||||||
|
LOGGER.error("oauth-fabric: Copying the corrupt file to \"{}\".", backupPath);
|
||||||
|
Files.copy(CONFIG_FILE_PATH, backupPath, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
this.copyDefaultFile();
|
||||||
|
this.loadFromFile(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void copyDefaultFile() throws IOException {
|
||||||
|
Files.createDirectories(CONFIG_FILE_PATH.getParent());
|
||||||
|
|
||||||
|
try (var writer = Files.newBufferedWriter(CONFIG_FILE_PATH, StandardCharsets.UTF_8)) {
|
||||||
|
new TomlWriter().write(this.config.unmodifiable(), writer);
|
||||||
|
} catch (NoSuchFileException | FileNotFoundException e) {
|
||||||
|
LOGGER.error("oauth-fabric: Failed to write default configuration file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
src/main/java/dev/lilyvex/oauthfabric/database/Database.java
Normal file
36
src/main/java/dev/lilyvex/oauthfabric/database/Database.java
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package dev.lilyvex.oauthfabric.database;
|
||||||
|
|
||||||
|
public class Database implements IDatabase {
|
||||||
|
private IDatabase databaseClass;
|
||||||
|
|
||||||
|
public void setDatabase(String database) {
|
||||||
|
switch (database) {
|
||||||
|
case "sqlite":
|
||||||
|
databaseClass = new SQLite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addUser(String uuid, String oauthId, String sessionToken) {
|
||||||
|
databaseClass.addUser(uuid, oauthId, sessionToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateUser(String uuid, String oauthId, String sessionToken) {
|
||||||
|
databaseClass.updateUser(uuid, oauthId, sessionToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeUser(String uuid) {
|
||||||
|
databaseClass.removeUser(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRegisteredUser(String uuid) {
|
||||||
|
return databaseClass.isRegisteredUser(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOauthId(String uuid) {
|
||||||
|
return databaseClass.getOauthId(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionToken(String uuid) {
|
||||||
|
return databaseClass.getSessionToken(uuid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package dev.lilyvex.oauthfabric.database;
|
||||||
|
|
||||||
|
public interface IDatabase {
|
||||||
|
public void addUser(String uuid, String oauthId, String sessionToken);
|
||||||
|
public void updateUser(String uuid, String oauthId, String sessionToken);
|
||||||
|
public void removeUser(String uuid);
|
||||||
|
public boolean isRegisteredUser(String uuid);
|
||||||
|
|
||||||
|
public String getOauthId(String uuid);
|
||||||
|
public String getSessionToken(String uuid);
|
||||||
|
}
|
200
src/main/java/dev/lilyvex/oauthfabric/database/SQLite.java
Normal file
200
src/main/java/dev/lilyvex/oauthfabric/database/SQLite.java
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
package dev.lilyvex.oauthfabric.database;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
|
public class SQLite implements IDatabase {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger("oauth-fabric");
|
||||||
|
private static final Path DATABASE_PATH = FabricLoader.getInstance().getConfigDir()
|
||||||
|
.resolve("oauth-fabric.db")
|
||||||
|
.normalize();
|
||||||
|
|
||||||
|
private static final String databaseUrl = "jdbc:sqlite:" + DATABASE_PATH;
|
||||||
|
private Connection connection = null;
|
||||||
|
|
||||||
|
private void createDatabase() throws SQLException {
|
||||||
|
try {
|
||||||
|
connection = DriverManager.getConnection(databaseUrl);
|
||||||
|
|
||||||
|
Statement statement = connection.createStatement();
|
||||||
|
statement.executeUpdate("""
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
uuid TEXT UNIQUE,
|
||||||
|
oauth_id TEXT UNIQUE,
|
||||||
|
session_token TEXT UNIQUE
|
||||||
|
)
|
||||||
|
""");
|
||||||
|
} catch (SQLException e) {
|
||||||
|
LOGGER.error("oauth-fabric: Unable to create SQLite database");
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (connection != null) {
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
LOGGER.error("oauth-fabric: Could not close SQLite connection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addUser(String uuid, String oauthId, String sessionToken) {
|
||||||
|
try {
|
||||||
|
createDatabase();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection = DriverManager.getConnection(databaseUrl);
|
||||||
|
|
||||||
|
PreparedStatement statement = connection.prepareStatement("""
|
||||||
|
INSERT INTO users (
|
||||||
|
uuid,
|
||||||
|
oauth_id,
|
||||||
|
session_token
|
||||||
|
) VALUES (
|
||||||
|
?,
|
||||||
|
?,
|
||||||
|
?
|
||||||
|
)
|
||||||
|
""");
|
||||||
|
|
||||||
|
statement.setString(1, uuid);
|
||||||
|
statement.setString(2, oauthId);
|
||||||
|
statement.setString(3, sessionToken);
|
||||||
|
statement.executeQuery();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateUser(String uuid, String oauthId, String sessionToken) {
|
||||||
|
try {
|
||||||
|
createDatabase();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection = DriverManager.getConnection(databaseUrl);
|
||||||
|
|
||||||
|
PreparedStatement statement = connection.prepareStatement("UPDATE users SET oauth_id = ?, session_token = ? WHERE uuid = ?");
|
||||||
|
statement.setString(1, oauthId);
|
||||||
|
statement.setString(2, sessionToken);
|
||||||
|
statement.setString(3, uuid);
|
||||||
|
statement.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeUser(String uuid) {
|
||||||
|
try {
|
||||||
|
createDatabase();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection = DriverManager.getConnection(databaseUrl);
|
||||||
|
|
||||||
|
PreparedStatement statement = connection.prepareStatement("DELETE FROM users WHERE uuid = ?");
|
||||||
|
statement.setString(1, uuid);
|
||||||
|
statement.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRegisteredUser(String uuid) {
|
||||||
|
try {
|
||||||
|
createDatabase();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection = DriverManager.getConnection(databaseUrl);
|
||||||
|
|
||||||
|
PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE uuid = ?");
|
||||||
|
statement.setString(1, uuid);
|
||||||
|
ResultSet resultSet = statement.executeQuery();
|
||||||
|
|
||||||
|
int results = 0;
|
||||||
|
while (resultSet.next()) {
|
||||||
|
results++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results > 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOauthId(String uuid) {
|
||||||
|
try {
|
||||||
|
createDatabase();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection = DriverManager.getConnection(databaseUrl);
|
||||||
|
|
||||||
|
PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE uuid = ?");
|
||||||
|
statement.setString(1, uuid);
|
||||||
|
ResultSet resultSet = statement.executeQuery();
|
||||||
|
|
||||||
|
String userOauthId = "";
|
||||||
|
|
||||||
|
while (resultSet.next()) {
|
||||||
|
userOauthId = resultSet.getString("oauth_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
return userOauthId;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionToken(String uuid) {
|
||||||
|
try {
|
||||||
|
createDatabase();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
connection = DriverManager.getConnection(databaseUrl);
|
||||||
|
|
||||||
|
PreparedStatement statement = connection.prepareStatement("SELECT * FROM users WHERE uuid = ?");
|
||||||
|
statement.setString(1, uuid);
|
||||||
|
ResultSet resultSet = statement.executeQuery();
|
||||||
|
|
||||||
|
String userSessionToken = "";
|
||||||
|
|
||||||
|
while (resultSet.next()) {
|
||||||
|
userSessionToken = resultSet.getString("session_token");
|
||||||
|
}
|
||||||
|
|
||||||
|
return userSessionToken;
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,15 +3,15 @@
|
||||||
"id": "oauth-fabric",
|
"id": "oauth-fabric",
|
||||||
"version": "${version}",
|
"version": "${version}",
|
||||||
"name": "OAuth Fabric",
|
"name": "OAuth Fabric",
|
||||||
"description": "This is an example description! Tell everyone what your mod is about!",
|
"description": "OAuth2 authentication for Fabric Minecraft servers",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Me!"
|
"Lily Vex"
|
||||||
],
|
],
|
||||||
"contact": {
|
"contact": {
|
||||||
"homepage": "https://fabricmc.net/",
|
"homepage": "https://code.lilyvex.dev/lily/oauth-fabric",
|
||||||
"sources": "https://github.com/FabricMC/fabric-example-mod"
|
"sources": "https://code.lilyvex.dev/lily/oauth-fabric"
|
||||||
},
|
},
|
||||||
"license": "CC0-1.0",
|
"license": "MIT",
|
||||||
"icon": "assets/oauth-fabric/icon.png",
|
"icon": "assets/oauth-fabric/icon.png",
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue