fix: clearer errors for custom server addresses
This commit is contained in:
1 parent
da8048a2d4
commit
e2c72bcff8
2 files changed
+73
-36
No files matched your search
@@ -25,7 +25,7 @@ sits in the refresh token column in front of the client token, and the
|
|||||||
account list shows which server an account is on.
|
account list shows which server an account is on.
|
||||||
---
|
---
|
||||||
.../src/components/ui/AccountsCard.vue | 112 +++--
|
.../src/components/ui/AccountsCard.vue | 112 +++--
|
||||||
.../src/components/ui/AuthlibAccountModal.vue | 307 +++++++++++++
|
.../src/components/ui/AuthlibAccountModal.vue | 334 ++++++++++++++
|
||||||
.../src/components/ui/MicrosoftLogo.vue | 8 +
|
.../src/components/ui/MicrosoftLogo.vue | 8 +
|
||||||
.../components/ui/TitleBarAccountSwitcher.vue | 63 ++-
|
.../components/ui/TitleBarAccountSwitcher.vue | 63 ++-
|
||||||
.../MinecraftRequiredModal.vue | 23 +-
|
.../MinecraftRequiredModal.vue | 23 +-
|
||||||
@@ -35,8 +35,8 @@ account list shows which server an account is on.
|
|||||||
packages/app-lib/src/api/minecraft_auth.rs | 77 +++-
|
packages/app-lib/src/api/minecraft_auth.rs | 77 +++-
|
||||||
packages/app-lib/src/launcher/mod.rs | 11 +-
|
packages/app-lib/src/launcher/mod.rs | 11 +-
|
||||||
packages/app-lib/src/state/minecraft_auth.rs | 422 ++++++++++++------
|
packages/app-lib/src/state/minecraft_auth.rs | 422 ++++++++++++------
|
||||||
packages/app-lib/src/util/authlib_injector.rs | 134 +++++-
|
packages/app-lib/src/util/authlib_injector.rs | 138 +++++-
|
||||||
12 files changed, 1001 insertions(+), 211 deletions(-)
|
12 files changed, 1032 insertions(+), 211 deletions(-)
|
||||||
create mode 100644 apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
create mode 100644 apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
||||||
create mode 100644 apps/app-frontend/src/components/ui/MicrosoftLogo.vue
|
create mode 100644 apps/app-frontend/src/components/ui/MicrosoftLogo.vue
|
||||||
|
|
||||||
@@ -260,10 +260,10 @@ index 632483e..03a61f2 100644
|
|||||||
id: 'minecraft-account.remove-account',
|
id: 'minecraft-account.remove-account',
|
||||||
diff --git a/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue b/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
diff --git a/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue b/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000..4aab3f9
|
index 0000000..a2873fe
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
+++ b/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
||||||
@@ -0,0 +1,307 @@
|
@@ -0,0 +1,334 @@
|
||||||
+<template>
|
+<template>
|
||||||
+ <NewModal ref="modal" :header="formatMessage(messages.header)" max-width="480px" width="100%">
|
+ <NewModal ref="modal" :header="formatMessage(messages.header)" max-width="480px" width="100%">
|
||||||
+ <div class="flex flex-col gap-4">
|
+ <div class="flex flex-col gap-4">
|
||||||
@@ -301,6 +301,13 @@ index 0000000..4aab3f9
|
|||||||
+ {{ formatMessage(messages.register) }}
|
+ {{ formatMessage(messages.register) }}
|
||||||
+ </a>
|
+ </a>
|
||||||
+ </p>
|
+ </p>
|
||||||
|
+ <p
|
||||||
|
+ v-else-if="lookingUp"
|
||||||
|
+ class="m-0 flex items-center gap-2 text-sm leading-tight text-secondary"
|
||||||
|
+ >
|
||||||
|
+ <SpinnerIcon aria-hidden="true" class="animate-spin" />
|
||||||
|
+ {{ formatMessage(messages.lookingUp) }}
|
||||||
|
+ </p>
|
||||||
+ <p v-else class="m-0 text-sm leading-tight text-secondary">
|
+ <p v-else class="m-0 text-sm leading-tight text-secondary">
|
||||||
+ {{ formatMessage(messages.serverHint) }}
|
+ {{ formatMessage(messages.serverHint) }}
|
||||||
+ </p>
|
+ </p>
|
||||||
@@ -437,10 +444,14 @@ index 0000000..4aab3f9
|
|||||||
+const profile = ref<Profile | null>(null)
|
+const profile = ref<Profile | null>(null)
|
||||||
+const error = ref('')
|
+const error = ref('')
|
||||||
+const submitting = ref(false)
|
+const submitting = ref(false)
|
||||||
|
+const lookingUp = ref(false)
|
||||||
+let lookup = 0
|
+let lookup = 0
|
||||||
+
|
+
|
||||||
+function message(e: unknown) {
|
+function message(e: unknown) {
|
||||||
+ return typeof e === 'string' ? e : ((e as Error)?.message ?? formatMessage(messages.genericError))
|
+ const text =
|
||||||
|
+ typeof e === 'string' ? e : ((e as Error)?.message ?? formatMessage(messages.genericError))
|
||||||
|
+ // The launcher's own label for the kind of error says nothing here.
|
||||||
|
+ return text.replace(/^(Error|Invalid input): /, '')
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
+// The players belong to the account they were listed for.
|
+// The players belong to the account they were listed for.
|
||||||
@@ -451,6 +462,7 @@ index 0000000..4aab3f9
|
|||||||
+
|
+
|
||||||
+watch(address, () => {
|
+watch(address, () => {
|
||||||
+ lookup++
|
+ lookup++
|
||||||
|
+ lookingUp.value = false
|
||||||
+ server.value = null
|
+ server.value = null
|
||||||
+ serverError.value = ''
|
+ serverError.value = ''
|
||||||
+})
|
+})
|
||||||
@@ -477,11 +489,15 @@ index 0000000..4aab3f9
|
|||||||
+ if (!value || server.value) return
|
+ if (!value || server.value) return
|
||||||
+
|
+
|
||||||
+ const request = ++lookup
|
+ const request = ++lookup
|
||||||
|
+ lookingUp.value = true
|
||||||
|
+ serverError.value = ''
|
||||||
+ try {
|
+ try {
|
||||||
+ const found = await authlib_server(value)
|
+ const found = await authlib_server(value)
|
||||||
+ if (request === lookup) server.value = found
|
+ if (request === lookup) server.value = found
|
||||||
+ } catch (e) {
|
+ } catch (e) {
|
||||||
+ if (request === lookup) serverError.value = message(e)
|
+ if (request === lookup) serverError.value = message(e)
|
||||||
|
+ } finally {
|
||||||
|
+ if (request === lookup) lookingUp.value = false
|
||||||
+ }
|
+ }
|
||||||
+}
|
+}
|
||||||
+
|
+
|
||||||
@@ -495,6 +511,13 @@ index 0000000..4aab3f9
|
|||||||
+ submitting.value = true
|
+ submitting.value = true
|
||||||
+ error.value = ''
|
+ error.value = ''
|
||||||
+
|
+
|
||||||
|
+ // A server that cannot be found is the address's fault, not the password's.
|
||||||
|
+ await lookUpServer()
|
||||||
|
+ if (!server.value) {
|
||||||
|
+ submitting.value = false
|
||||||
|
+ return
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ try {
|
+ try {
|
||||||
+ const result = await login_authlib(
|
+ const result = await login_authlib(
|
||||||
+ address.value.trim(),
|
+ address.value.trim(),
|
||||||
@@ -536,6 +559,10 @@ index 0000000..4aab3f9
|
|||||||
+ id: 'app.authlib-account.server-hint',
|
+ id: 'app.authlib-account.server-hint',
|
||||||
+ defaultMessage: "The address of the server's website.",
|
+ defaultMessage: "The address of the server's website.",
|
||||||
+ },
|
+ },
|
||||||
|
+ lookingUp: {
|
||||||
|
+ id: 'app.authlib-account.looking-up',
|
||||||
|
+ defaultMessage: 'Looking for the server…',
|
||||||
|
+ },
|
||||||
+ register: {
|
+ register: {
|
||||||
+ id: 'app.authlib-account.register',
|
+ id: 'app.authlib-account.register',
|
||||||
+ defaultMessage: 'Create an account',
|
+ defaultMessage: 'Create an account',
|
||||||
@@ -1540,10 +1567,10 @@ index 2514d8e..0245152 100644
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/packages/app-lib/src/util/authlib_injector.rs b/packages/app-lib/src/util/authlib_injector.rs
|
diff --git a/packages/app-lib/src/util/authlib_injector.rs b/packages/app-lib/src/util/authlib_injector.rs
|
||||||
index dc099f9..709e6d0 100644
|
index dc099f9..13591ef 100644
|
||||||
--- a/packages/app-lib/src/util/authlib_injector.rs
|
--- a/packages/app-lib/src/util/authlib_injector.rs
|
||||||
+++ b/packages/app-lib/src/util/authlib_injector.rs
|
+++ b/packages/app-lib/src/util/authlib_injector.rs
|
||||||
@@ -1,16 +1,133 @@
|
@@ -1,16 +1,137 @@
|
||||||
-//! Downloads and caches the authlib-injector Java agent.
|
-//! Downloads and caches the authlib-injector Java agent.
|
||||||
+//! The authlib-injector Java agent, and the servers it works with.
|
+//! The authlib-injector Java agent, and the servers it works with.
|
||||||
//!
|
//!
|
||||||
@@ -1630,16 +1657,20 @@ index dc099f9..709e6d0 100644
|
|||||||
+ ))
|
+ ))
|
||||||
+ })?;
|
+ })?;
|
||||||
+
|
+
|
||||||
|
+ // What went wrong in detail is for the log: to the player, a mistyped
|
||||||
|
+ // address and a server that is down look the same.
|
||||||
+ async fn get(url: &Url) -> crate::Result<Response> {
|
+ async fn get(url: &Url) -> crate::Result<Response> {
|
||||||
|
+ let host = url.host_str().unwrap_or_default();
|
||||||
+ INSECURE_REQWEST_CLIENT
|
+ INSECURE_REQWEST_CLIENT
|
||||||
+ .get(url.clone())
|
+ .get(url.clone())
|
||||||
+ .header(ACCEPT, "application/json")
|
+ .header(ACCEPT, "application/json")
|
||||||
|
+ .timeout(std::time::Duration::from_secs(10))
|
||||||
+ .send()
|
+ .send()
|
||||||
+ .await
|
+ .await
|
||||||
+ .map_err(|error| {
|
+ .map_err(|error| {
|
||||||
|
+ tracing::warn!("Could not reach {host}: {error:?}");
|
||||||
+ crate::ErrorKind::OtherError(format!(
|
+ crate::ErrorKind::OtherError(format!(
|
||||||
+ "Could not reach {}: {error}",
|
+ "Could not reach {host}. Check the address and your connection."
|
||||||
+ url.host_str().unwrap_or_default()
|
|
||||||
+ ))
|
+ ))
|
||||||
+ .as_error()
|
+ .as_error()
|
||||||
+ })
|
+ })
|
||||||
@@ -1683,7 +1714,7 @@ index dc099f9..709e6d0 100644
|
|||||||
/// The agent's own distribution metadata.
|
/// The agent's own distribution metadata.
|
||||||
const LATEST_URL: &str = "https://authlib-injector.yushi.moe/artifact/latest.json";
|
const LATEST_URL: &str = "https://authlib-injector.yushi.moe/artifact/latest.json";
|
||||||
|
|
||||||
@@ -22,8 +139,7 @@ struct LatestArtifact {
|
@@ -22,8 +143,7 @@ struct LatestArtifact {
|
||||||
/// Returns the path to the agent jar, downloading it once if it is not cached.
|
/// Returns the path to the agent jar, downloading it once if it is not cached.
|
||||||
///
|
///
|
||||||
/// The cached copy is reused as it is. The agent is not tied to a game or
|
/// The cached copy is reused as it is. The agent is not tied to a game or
|
||||||
@@ -1693,7 +1724,7 @@ index dc099f9..709e6d0 100644
|
|||||||
pub async fn get_authlib_injector(
|
pub async fn get_authlib_injector(
|
||||||
directories: &DirectoryInfo,
|
directories: &DirectoryInfo,
|
||||||
) -> crate::Result<PathBuf> {
|
) -> crate::Result<PathBuf> {
|
||||||
@@ -35,7 +151,7 @@ pub async fn get_authlib_injector(
|
@@ -35,7 +155,7 @@ pub async fn get_authlib_injector(
|
||||||
return Ok(jar);
|
return Ok(jar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,11 @@ session in the refresh token column as JSON behind a marker.
|
|||||||
apps/app/src/api/auth.rs | 49 +++
|
apps/app/src/api/auth.rs | 49 +++
|
||||||
packages/app-lib/src/api/minecraft_auth.rs | 47 +-
|
packages/app-lib/src/api/minecraft_auth.rs | 47 +-
|
||||||
packages/app-lib/src/state/minecraft_auth.rs | 402 +++++++++++++++++-
|
packages/app-lib/src/state/minecraft_auth.rs | 402 +++++++++++++++++-
|
||||||
packages/app-lib/src/util/authlib_injector.rs | 94 ++++
|
packages/app-lib/src/util/authlib_injector.rs | 100 +++++
|
||||||
7 files changed, 782 insertions(+), 14 deletions(-)
|
7 files changed, 788 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
diff --git a/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue b/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
diff --git a/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue b/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
||||||
index 4aab3f9..b67b2c7 100644
|
index a2873fe..0e1f9a7 100644
|
||||||
--- a/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
--- a/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
||||||
+++ b/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
+++ b/apps/app-frontend/src/components/ui/AuthlibAccountModal.vue
|
||||||
@@ -1,5 +1,11 @@
|
@@ -1,5 +1,11 @@
|
||||||
@@ -49,7 +49,7 @@ index 4aab3f9..b67b2c7 100644
|
|||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<p class="m-0 leading-tight text-secondary">
|
<p class="m-0 leading-tight text-secondary">
|
||||||
{{ formatMessage(messages.description) }}
|
{{ formatMessage(messages.description) }}
|
||||||
@@ -40,6 +46,52 @@
|
@@ -47,6 +53,52 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ index 4aab3f9..b67b2c7 100644
|
|||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<label class="font-semibold text-contrast" for="authlib-account-username">
|
<label class="font-semibold text-contrast" for="authlib-account-username">
|
||||||
{{ formatMessage(messages.usernameLabel) }}
|
{{ formatMessage(messages.usernameLabel) }}
|
||||||
@@ -126,6 +178,8 @@
|
@@ -133,6 +185,8 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {
|
import {
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
@@ -111,7 +111,7 @@ index 4aab3f9..b67b2c7 100644
|
|||||||
GlobeIcon,
|
GlobeIcon,
|
||||||
KeyIcon,
|
KeyIcon,
|
||||||
LogInIcon,
|
LogInIcon,
|
||||||
@@ -138,13 +192,20 @@ import {
|
@@ -145,13 +199,20 @@ import {
|
||||||
Chips,
|
Chips,
|
||||||
commonMessages,
|
commonMessages,
|
||||||
defineMessages,
|
defineMessages,
|
||||||
@@ -133,7 +133,7 @@ index 4aab3f9..b67b2c7 100644
|
|||||||
|
|
||||||
type Server = {
|
type Server = {
|
||||||
api_root: string
|
api_root: string
|
||||||
@@ -152,8 +213,16 @@ type Server = {
|
@@ -159,8 +220,16 @@ type Server = {
|
||||||
implementation?: string
|
implementation?: string
|
||||||
homepage?: string
|
homepage?: string
|
||||||
register?: string
|
register?: string
|
||||||
@@ -150,10 +150,10 @@ index 4aab3f9..b67b2c7 100644
|
|||||||
|
|
||||||
const { formatMessage } = useVIntl()
|
const { formatMessage } = useVIntl()
|
||||||
|
|
||||||
@@ -171,7 +240,15 @@ const profiles = ref<Profile[]>([])
|
@@ -179,7 +248,15 @@ const profile = ref<Profile | null>(null)
|
||||||
const profile = ref<Profile | null>(null)
|
|
||||||
const error = ref('')
|
const error = ref('')
|
||||||
const submitting = ref(false)
|
const submitting = ref(false)
|
||||||
|
const lookingUp = ref(false)
|
||||||
+const browser = ref<DeviceCode | null>(null)
|
+const browser = ref<DeviceCode | null>(null)
|
||||||
+const browserStarting = ref(false)
|
+const browserStarting = ref(false)
|
||||||
+const browserError = ref('')
|
+const browserError = ref('')
|
||||||
@@ -165,9 +165,9 @@ index 4aab3f9..b67b2c7 100644
|
|||||||
+let pollTimeout: ReturnType<typeof setTimeout> | undefined
|
+let pollTimeout: ReturnType<typeof setTimeout> | undefined
|
||||||
|
|
||||||
function message(e: unknown) {
|
function message(e: unknown) {
|
||||||
return typeof e === 'string' ? e : ((e as Error)?.message ?? formatMessage(messages.genericError))
|
const text =
|
||||||
@@ -187,6 +264,8 @@ watch(address, () => {
|
@@ -199,6 +276,8 @@ watch(address, () => {
|
||||||
lookup++
|
lookingUp.value = false
|
||||||
server.value = null
|
server.value = null
|
||||||
serverError.value = ''
|
serverError.value = ''
|
||||||
+ stopBrowser()
|
+ stopBrowser()
|
||||||
@@ -175,7 +175,7 @@ index 4aab3f9..b67b2c7 100644
|
|||||||
})
|
})
|
||||||
|
|
||||||
function show(event?: MouseEvent) {
|
function show(event?: MouseEvent) {
|
||||||
@@ -199,6 +278,8 @@ function show(event?: MouseEvent) {
|
@@ -211,6 +290,8 @@ function show(event?: MouseEvent) {
|
||||||
profile.value = null
|
profile.value = null
|
||||||
error.value = ''
|
error.value = ''
|
||||||
submitting.value = false
|
submitting.value = false
|
||||||
@@ -184,7 +184,7 @@ index 4aab3f9..b67b2c7 100644
|
|||||||
modal.value?.show(event)
|
modal.value?.show(event)
|
||||||
void nextTick(() => {
|
void nextTick(() => {
|
||||||
document.getElementById('authlib-account-server')?.focus()
|
document.getElementById('authlib-account-server')?.focus()
|
||||||
@@ -219,6 +300,72 @@ async function lookUpServer() {
|
@@ -235,6 +316,72 @@ async function lookUpServer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +257,7 @@ index 4aab3f9..b67b2c7 100644
|
|||||||
async function submit() {
|
async function submit() {
|
||||||
if (submitting.value) return
|
if (submitting.value) return
|
||||||
|
|
||||||
@@ -282,6 +429,34 @@ const messages = defineMessages({
|
@@ -309,6 +456,34 @@ const messages = defineMessages({
|
||||||
id: 'app.authlib-account.password-label',
|
id: 'app.authlib-account.password-label',
|
||||||
defaultMessage: 'Password',
|
defaultMessage: 'Password',
|
||||||
},
|
},
|
||||||
@@ -935,10 +935,10 @@ index b916a6d..e9fa853 100644
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
diff --git a/packages/app-lib/src/util/authlib_injector.rs b/packages/app-lib/src/util/authlib_injector.rs
|
diff --git a/packages/app-lib/src/util/authlib_injector.rs b/packages/app-lib/src/util/authlib_injector.rs
|
||||||
index 709e6d0..8788563 100644
|
index 13591ef..487b0ae 100644
|
||||||
--- a/packages/app-lib/src/util/authlib_injector.rs
|
--- a/packages/app-lib/src/util/authlib_injector.rs
|
||||||
+++ b/packages/app-lib/src/util/authlib_injector.rs
|
+++ b/packages/app-lib/src/util/authlib_injector.rs
|
||||||
@@ -17,6 +17,90 @@ use crate::state::DirectoryInfo;
|
@@ -17,6 +17,96 @@ use crate::state::DirectoryInfo;
|
||||||
use crate::util::fetch::{INSECURE_REQWEST_CLIENT, REQWEST_CLIENT};
|
use crate::util::fetch::{INSECURE_REQWEST_CLIENT, REQWEST_CLIENT};
|
||||||
use crate::util::io;
|
use crate::util::io;
|
||||||
|
|
||||||
@@ -951,8 +951,11 @@ index 709e6d0..8788563 100644
|
|||||||
+const CONNECT_CLIENT_IDS: &[(&str, &str)] = &[];
|
+const CONNECT_CLIENT_IDS: &[(&str, &str)] = &[];
|
||||||
+
|
+
|
||||||
+/// The scopes a Yggdrasil Connect sign-in for playing needs.
|
+/// The scopes a Yggdrasil Connect sign-in for playing needs.
|
||||||
+const CONNECT_SCOPES: [&str; 3] =
|
+const CONNECT_SCOPES: [&str; 3] = [
|
||||||
+ ["openid", "Yggdrasil.PlayerProfiles.Select", "Yggdrasil.Server.Join"];
|
+ "openid",
|
||||||
|
+ "Yggdrasil.PlayerProfiles.Select",
|
||||||
|
+ "Yggdrasil.Server.Join",
|
||||||
|
+];
|
||||||
+
|
+
|
||||||
+/// How to sign in to a server with Yggdrasil Connect, OAuth's device flow on
|
+/// How to sign in to a server with Yggdrasil Connect, OAuth's device flow on
|
||||||
+/// the server's own page.
|
+/// the server's own page.
|
||||||
@@ -998,7 +1001,10 @@ index 709e6d0..8788563 100644
|
|||||||
+ .iter()
|
+ .iter()
|
||||||
+ .all(|endpoint| endpoint.starts_with("https://"));
|
+ .all(|endpoint| endpoint.starts_with("https://"));
|
||||||
+ let supported = |scope: &str| {
|
+ let supported = |scope: &str| {
|
||||||
+ config.scopes_supported.iter().any(|supported| supported == scope)
|
+ config
|
||||||
|
+ .scopes_supported
|
||||||
|
+ .iter()
|
||||||
|
+ .any(|supported| supported == scope)
|
||||||
+ };
|
+ };
|
||||||
+ if !https || !CONNECT_SCOPES.iter().all(|scope| supported(scope)) {
|
+ if !https || !CONNECT_SCOPES.iter().all(|scope| supported(scope)) {
|
||||||
+ return None;
|
+ return None;
|
||||||
@@ -1029,7 +1035,7 @@ index 709e6d0..8788563 100644
|
|||||||
/// An authlib-injector server, as its own metadata describes it.
|
/// An authlib-injector server, as its own metadata describes it.
|
||||||
#[derive(Serialize, Debug, Clone)]
|
#[derive(Serialize, Debug, Clone)]
|
||||||
pub struct AuthlibServer {
|
pub struct AuthlibServer {
|
||||||
@@ -27,6 +111,8 @@ pub struct AuthlibServer {
|
@@ -27,6 +117,8 @@ pub struct AuthlibServer {
|
||||||
pub implementation: Option<String>,
|
pub implementation: Option<String>,
|
||||||
pub homepage: Option<String>,
|
pub homepage: Option<String>,
|
||||||
pub register: Option<String>,
|
pub register: Option<String>,
|
||||||
@@ -1038,7 +1044,7 @@ index 709e6d0..8788563 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@@ -46,6 +132,8 @@ struct Meta {
|
@@ -46,6 +138,8 @@ struct Meta {
|
||||||
implementation_name: Option<String>,
|
implementation_name: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
links: Links,
|
links: Links,
|
||||||
@@ -1047,7 +1053,7 @@ index 709e6d0..8788563 100644
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Default)]
|
#[derive(Deserialize, Default)]
|
||||||
@@ -115,6 +203,11 @@ pub async fn resolve_server(address: &str) -> crate::Result<AuthlibServer> {
|
@@ -119,6 +213,11 @@ pub async fn resolve_server(address: &str) -> crate::Result<AuthlibServer> {
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -1059,7 +1065,7 @@ index 709e6d0..8788563 100644
|
|||||||
Ok(AuthlibServer {
|
Ok(AuthlibServer {
|
||||||
api_root: api_root.as_str().trim_end_matches('/').to_owned(),
|
api_root: api_root.as_str().trim_end_matches('/').to_owned(),
|
||||||
name: metadata
|
name: metadata
|
||||||
@@ -125,6 +218,7 @@ pub async fn resolve_server(address: &str) -> crate::Result<AuthlibServer> {
|
@@ -129,6 +228,7 @@ pub async fn resolve_server(address: &str) -> crate::Result<AuthlibServer> {
|
||||||
implementation: metadata.meta.implementation_name,
|
implementation: metadata.meta.implementation_name,
|
||||||
homepage: metadata.meta.links.homepage,
|
homepage: metadata.meta.links.homepage,
|
||||||
register: metadata.meta.links.register,
|
register: metadata.meta.links.register,
|
||||||
|
|||||||
Reference in new issue
Block a user