Skip to content

Commit

Permalink
feat: Allow setting custom mojang authentication server (#264)
Browse files Browse the repository at this point in the history
  • Loading branch information
robinbraemer authored Dec 1, 2023
1 parent e6db8d3 commit 91e3d7e
Show file tree
Hide file tree
Showing 10 changed files with 316 additions and 67 deletions.
12 changes: 8 additions & 4 deletions .web/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const ogDescription = 'Next Generation Minecraft Proxy'
export default defineConfig({
title: `Gate Proxy${additionalTitle}`,
description: ogDescription,
appearance: 'dark',

head: [
['link', {rel: 'icon', type: 'image/png', href: '/favicon.png'}],
Expand Down Expand Up @@ -50,10 +51,13 @@ export default defineConfig({
{icon: 'github', link: `${gitHubLink}/gate`}
],

algolia: {
appId: 'CUJMPRQVZJ',
apiKey: 'f3a1d3d48a15f78e39d6401b86318ed7',
indexName: 'gate-minekube',
search: {
provider: 'algolia',
options: {
appId: 'CUJMPRQVZJ',
apiKey: 'f3a1d3d48a15f78e39d6401b86318ed7',
indexName: 'gate-minekube',
}
},

// carbonAds: {
Expand Down
136 changes: 79 additions & 57 deletions .web/docs/.vitepress/theme/styles/vars.css
Original file line number Diff line number Diff line change
@@ -1,31 +1,89 @@
/**
* Customize default theme styling by overriding CSS variables:
* https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
*/

/**
* Colors
*
* Each colors have exact same color scale system with 3 levels of solid
* colors with different brightness, and 1 soft color.
*
* - `XXX-1`: The most solid color used mainly for colored text. It must
* satisfy the contrast ratio against when used on top of `XXX-soft`.
*
* - `XXX-2`: The color used mainly for hover state of the button.
*
* - `XXX-3`: The color for solid background, such as bg color of the button.
* It must satisfy the contrast ratio with pure white (#ffffff) text on
* top of it.
*
* - `XXX-soft`: The color used for subtle background such as custom container
* or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
* on top of it.
*
* The soft color must be semi transparent alpha channel. This is crucial
* because it allows adding multiple "soft" colors on top of each other
* to create a accent, such as when having inline code block inside
* custom containers.
*
* - `default`: The color used purely for subtle indication without any
* special meanings attched to it such as bg color for menu hover state.
*
* - `brand`: Used for primary brand colors, such as link text, button with
* brand theme, etc.
*
* - `tip`: Used to indicate useful information. The default theme uses the
* brand color for this by default.
*
* - `warning`: Used to indicate warning to the users. Used in custom
* container, badges, etc.
*
* - `danger`: Used to show error, or dangerous message to the users. Used
* in custom container, badges, etc.
* -------------------------------------------------------------------------- */

:root {
--vp-c-brand: #646cff;
--vp-c-brand-light: #747bff;
--vp-c-brand-lighter: #9499ff;
--vp-c-brand-lightest: #bcc0ff;
--vp-c-brand-dark: #535bf2;
--vp-c-brand-darker: #454ce1;
--vp-c-brand-dimm: rgba(100, 108, 255, 0.08);
:root {
--vp-c-default-1: var(--vp-c-gray-1);
--vp-c-default-2: var(--vp-c-gray-2);
--vp-c-default-3: var(--vp-c-gray-3);
--vp-c-default-soft: var(--vp-c-gray-soft);

--vp-c-brand-1: var(--vp-c-indigo-1);
--vp-c-brand-2: var(--vp-c-indigo-2);
--vp-c-brand-3: var(--vp-c-indigo-3);
--vp-c-brand-soft: var(--vp-c-indigo-soft);

--vp-c-tip-1: var(--vp-c-brand-1);
--vp-c-tip-2: var(--vp-c-brand-2);
--vp-c-tip-3: var(--vp-c-brand-3);
--vp-c-tip-soft: var(--vp-c-brand-soft);

--vp-c-warning-1: var(--vp-c-yellow-1);
--vp-c-warning-2: var(--vp-c-yellow-2);
--vp-c-warning-3: var(--vp-c-yellow-3);
--vp-c-warning-soft: var(--vp-c-yellow-soft);

--vp-c-danger-1: var(--vp-c-red-1);
--vp-c-danger-2: var(--vp-c-red-2);
--vp-c-danger-3: var(--vp-c-red-3);
--vp-c-danger-soft: var(--vp-c-red-soft);
}

/**
* Component: Button
* -------------------------------------------------------------------------- */

:root {
--vp-button-brand-border: var(--vp-c-brand-light);
--vp-button-brand-border: transparent;
--vp-button-brand-text: var(--vp-c-white);
--vp-button-brand-bg: var(--vp-c-brand);
--vp-button-brand-hover-border: var(--vp-c-brand-light);
--vp-button-brand-bg: var(--vp-c-brand-3);
--vp-button-brand-hover-border: transparent;
--vp-button-brand-hover-text: var(--vp-c-white);
--vp-button-brand-hover-bg: var(--vp-c-brand-light);
--vp-button-brand-active-border: var(--vp-c-brand-light);
--vp-button-brand-hover-bg: var(--vp-c-brand-2);
--vp-button-brand-active-border: transparent;
--vp-button-brand-active-text: var(--vp-c-white);
--vp-button-brand-active-bg: var(--vp-button-brand-bg);
--vp-button-brand-active-bg: var(--vp-c-brand-1);
}

/**
Expand All @@ -45,7 +103,7 @@
#bd34fe 50%,
#47caff 50%
);
--vp-home-hero-image-filter: blur(40px);
--vp-home-hero-image-filter: blur(44px);
}

@media (min-width: 640px) {
Expand All @@ -56,7 +114,7 @@

@media (min-width: 960px) {
:root {
--vp-home-hero-image-filter: blur(72px);
--vp-home-hero-image-filter: blur(68px);
}
}

Expand All @@ -65,52 +123,16 @@
* -------------------------------------------------------------------------- */

:root {
--vp-custom-block-tip-border: var(--vp-c-brand);
--vp-custom-block-tip-text: var(--vp-c-brand-darker);
--vp-custom-block-tip-bg: var(--vp-c-brand-dimm);
}

.dark {
--vp-custom-block-tip-border: var(--vp-c-brand);
--vp-custom-block-tip-text: var(--vp-c-brand-lightest);
--vp-custom-block-tip-bg: var(--vp-c-brand-dimm);
--vp-custom-block-tip-border: transparent;
--vp-custom-block-tip-text: var(--vp-c-text-1);
--vp-custom-block-tip-bg: var(--vp-c-brand-soft);
--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
}

/**
* Component: Algolia
* -------------------------------------------------------------------------- */

.DocSearch {
--docsearch-primary-color: var(--vp-c-brand) !important;
}

/**
* VitePress: Custom fix
* -------------------------------------------------------------------------- */

/*
Use lighter colors for links in dark mode for a11y.
Also specify some classes twice to have higher specificity
over scoped class data attribute.
*/
.dark .vp-doc a,
.dark .vp-doc a > code,
.dark .VPNavBarMenuLink.VPNavBarMenuLink:hover,
.dark .VPNavBarMenuLink.VPNavBarMenuLink.active,
.dark .link.link:hover,
.dark .link.link.active,
.dark .edit-link-button.edit-link-button,
.dark .pager-link .title {
color: var(--vp-c-brand-lighter);
}

.dark .vp-doc a:hover,
.dark .vp-doc a > code:hover {
color: var(--vp-c-brand-lightest);
opacity: 1;
}

/* Transition by color instead of opacity */
.dark .vp-doc .custom-block a {
transition: color 0.25s;
--docsearch-primary-color: var(--vp-c-brand-1) !important;
}
12 changes: 12 additions & 0 deletions .web/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,33 @@ features:
- icon: 📦
title: Fewer moving parts
details: Run Gate's tiny executable practically anywhere or in a container - No Java runtime needed!
link: /guide/install/
linkText: Install
- icon: 💻
title: Developer Friendly
details: Gate is written in Go, a modern programming language that is easy to learn and
has a great ecosystem of tools and libraries.
link: /developers/
linkText: Developers
- icon: 🖧
title: Supports Connect out of the box
details: Get your public or local host proxy network in front of players with organic traffic.
link: /guide/connect
linkText: Enable Connect
- icon: ✨️
title: Multi-Version Support
details: Gate supports Minecraft server versions 1.8 to latest and is constantly updated to support
new versions.
link: /guide/compatibility
linkText: Compatibility
- icon: 🪄
title: Lite Mode
details: Gate Lite is an ultra-thin lightweight Minecraft reverse proxy for host based connection routing.
link: /guide/lite
linkText: Lite Mode
- icon: ⚡️
title: High Performance
details: Gate is designed to be fast and efficient. A proxy that can handle thousands of players with ease.
link: /guide/why
linkText: Why Gate?
---
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2023 Minekube

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
5 changes: 5 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ config:
enabled: false
port: 25577
showPlugins: false
auth:
# Customize the base URL for the Mojang session server to authenticate online mode players using different authentication servers.
# Defaults to https://sessionserver.mojang.com/session/minecraft/hasJoined
#sessionServerUrl: https://example.com/mitm/session/minecraft/hasJoined

# Lite mode is a lightweight reverse proxy mode that acts as thin layer between the client and the backend server.
# See https://gate.minekube.com/guide/lite
#
Expand Down
31 changes: 28 additions & 3 deletions pkg/edition/java/auth/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type Authenticator interface {
GenerateServerID(decryptedSharedSecret []byte) (serverID string, err error)
// AuthenticateJoin Authenticates a joining user. The ip is optional.
AuthenticateJoin(ctx context.Context, serverID, username, ip string) (Response, error)
// SetHasJoinedURLFn sets the HasJoinedURLFn.
// If not set, DefaultHasJoinedURL is used.
SetHasJoinedURLFn(fn HasJoinedURLFn)
}

// Response is the authentication response.
Expand All @@ -54,13 +57,28 @@ var defaultHasJoinedBaseURL, _ = url.Parse(defaultHasJoinedEndpoint)
// DefaultHasJoinedURL returns the default hasJoined URL for the given serverID and username.
// The userIP is optional.
func DefaultHasJoinedURL(serverID, username, userIP string) string {
return buildHasJoinedURL(defaultHasJoinedBaseURL, serverID, username, userIP)
}

// CustomHasJoinedURL returns a HasJoinedURLFn that uses the given baseURL instead of the default official Mojang API.
func CustomHasJoinedURL(baseURL *url.URL) HasJoinedURLFn {
if baseURL == nil {
baseURL = defaultHasJoinedBaseURL
}
return func(serverID, username, userIP string) string {
return buildHasJoinedURL(baseURL, serverID, username, userIP)
}
}

// buildHasJoinedURL builds the hasJoined URL for the given baseURL.
func buildHasJoinedURL(baseURL *url.URL, serverID, username, userIP string) string {
query := url.Values{}
query.Set("serverId", serverID)
query.Set("username", username)
if userIP != "" {
query.Set("ip", userIP)
}
return defaultHasJoinedBaseURL.ResolveReference(&url.URL{RawQuery: query.Encode()}).String()
return baseURL.ResolveReference(&url.URL{RawQuery: query.Encode()}).String()
}

// HasJoinedURLFn returns the url to authenticate a
Expand Down Expand Up @@ -138,12 +156,19 @@ type authenticator struct {
hasJoinedURLFn HasJoinedURLFn
}

var _ Authenticator = (*authenticator)(nil)

func (a *authenticator) SetHasJoinedURLFn(fn HasJoinedURLFn) {
if fn == nil {
fn = DefaultHasJoinedURL
}
a.hasJoinedURLFn = fn
}

func (a *authenticator) PublicKey() []byte {
return a.public
}

var _ Authenticator = (*authenticator)(nil)

func (a *authenticator) Verify(encryptedVerifyToken, actualVerifyToken []byte) (bool, error) {
decryptedVerifyToken, err := rsa.DecryptPKCS1v15(rand.Reader, a.private, encryptedVerifyToken)
if err != nil {
Expand Down
9 changes: 8 additions & 1 deletion pkg/edition/java/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package config

import (
"fmt"

liteconfig "go.minekube.com/gate/pkg/edition/java/lite/config"
"go.minekube.com/gate/pkg/edition/java/proto/version"
"go.minekube.com/gate/pkg/util/componentutil"
Expand All @@ -15,6 +14,7 @@ import (
var DefaultConfig = Config{
Bind: "0.0.0.0:25565",
OnlineMode: true,
Auth: Auth{},
OnlineModeKickExistingPlayers: false,
Forwarding: Forwarding{
Mode: LegacyForwardingMode,
Expand Down Expand Up @@ -82,6 +82,7 @@ type Config struct { // TODO use https://github.com/projectdiscovery/yamldoc-go
Bind string `yaml:"bind"` // The address to listen for connections.

OnlineMode bool `yaml:"onlineMode"`
Auth Auth `yaml:"auth"`
OnlineModeKickExistingPlayers bool `yaml:"onlineModeKickExistingPlayers"` // Kicks existing players when a premium player with the same name joins.

Forwarding Forwarding `yaml:"forwarding"`
Expand Down Expand Up @@ -151,6 +152,12 @@ type (
Burst int `yaml:"burst"` // The maximum events per second, per block; the size of the token bucket
MaxEntries int `yaml:"maxEntries"` // Maximum number of IP blocks to keep track of in cache
}
// Auth is the config for authentication.
Auth struct {
// SessionServerURL is the base URL for the Mojang session server to authenticate online mode players.
// Defaults to https://sessionserver.mojang.com/session/minecraft/hasJoined
SessionServerURL *configutil.URL `yaml:"sessionServerUrl"` // TODO support multiple urls configutil.SingleOrMulti[string]
}
)

// ForwardingMode is a player info forwarding mode.
Expand Down
Loading

0 comments on commit 91e3d7e

Please sign in to comment.