310 lines
12 KiB
TypeScript
310 lines
12 KiB
TypeScript
import * as net from "net";
|
|
|
|
export enum Severity {
|
|
OK = "OK",
|
|
Warning = "WARN",
|
|
Error = "ERR",
|
|
Skip = "SKIP",
|
|
}
|
|
|
|
export interface Status {
|
|
severity: Severity;
|
|
message: string;
|
|
}
|
|
|
|
export interface DiagnosticStep {
|
|
run: () => Promise<Status>;
|
|
name: string;
|
|
status?: Status;
|
|
}
|
|
|
|
export interface Diagnostic {
|
|
title: string;
|
|
steps: Array<DiagnosticStep>;
|
|
status?: Status;
|
|
}
|
|
|
|
const domain = "/web/access/smgames.club";
|
|
|
|
export var diagnostics: Ref<Diagnostic[]> = ref([
|
|
{
|
|
title: "Matrix Server Acs.",
|
|
steps: [
|
|
{
|
|
name: "Version access",
|
|
run: () => {
|
|
// The Matrix server should be hosted at smgames.club - Attempt to connect to the server
|
|
// TODO: Better checking - This just checks for resources.
|
|
|
|
// Check _matrix/client/versions - Should return a JSON object
|
|
// Else, return an error
|
|
const url = `${domain}/_matrix/client/versions`;
|
|
return fetch(url)
|
|
.then((response) => {
|
|
if (response.ok) {
|
|
return {
|
|
severity: Severity.OK,
|
|
message: "Matrix server is accessible.",
|
|
};
|
|
} else {
|
|
return {
|
|
severity: Severity.Error,
|
|
message: "Response was not OK.",
|
|
};
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
return {
|
|
severity: Severity.Error,
|
|
message:
|
|
"Unable to get a response when querying the version: " +
|
|
error,
|
|
};
|
|
});
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: "Primary Domain",
|
|
steps: [
|
|
{
|
|
name: "Fetch Index",
|
|
run: () => {
|
|
// Check that the domain resolves
|
|
const url = `${domain}`;
|
|
return fetch(url)
|
|
.then((response) => {
|
|
if (response.ok) {
|
|
return {
|
|
severity: Severity.OK,
|
|
message: "Able to fetch.",
|
|
};
|
|
} else {
|
|
return {
|
|
severity: Severity.Error,
|
|
message: "Response was not OK.",
|
|
};
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
return {
|
|
severity: Severity.Error,
|
|
message:
|
|
"Unable to get a response when querying the domain: " +
|
|
error,
|
|
};
|
|
});
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: "Services Reverse Proxy",
|
|
steps: [
|
|
{
|
|
name: "Access Index",
|
|
run: () => {
|
|
const service_url = "/web/access/services.smgames.club";
|
|
return fetch(service_url)
|
|
.then((response) => {
|
|
if (response.ok) {
|
|
return {
|
|
severity: Severity.OK,
|
|
message: "Able to fetch index.",
|
|
};
|
|
} else {
|
|
return {
|
|
severity: Severity.Error,
|
|
message: "Index response was not OK: " +
|
|
response.statusText,
|
|
};
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
return {
|
|
severity: Severity.Error,
|
|
message:
|
|
"Unable to get a response when querying the domain index: " +
|
|
error,
|
|
};
|
|
});
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: "Minecraft",
|
|
steps: [
|
|
{
|
|
name: "WS Connect",
|
|
run: () => {
|
|
const minecraft_server = "ws://social.smgames.club:25565"; // WebSocket URL for Minecraft
|
|
const timeoutDuration = 100; // Timeout duration in ms
|
|
|
|
return new Promise<Status>((resolve, reject) => {
|
|
const socket = new WebSocket(minecraft_server);
|
|
|
|
// Set up a timeout to reject the promise if the connection takes too long
|
|
const timeout = setTimeout(() => {
|
|
reject({
|
|
severity: Severity.Error,
|
|
message:
|
|
`Timeout while trying to connect to Minecraft server via WebSocket on port 25565.`,
|
|
});
|
|
socket.close(); // Close the WebSocket connection in case of timeout
|
|
}, timeoutDuration);
|
|
|
|
socket.onopen = () => {
|
|
clearTimeout(timeout); // Clear the timeout once the connection is successful
|
|
resolve({
|
|
severity: Severity.OK,
|
|
message:
|
|
"WebSocket connection successful to Minecraft server on port 25565.",
|
|
});
|
|
socket.close(); // Close the WebSocket connection after success
|
|
};
|
|
|
|
socket.onerror = (err) => {
|
|
clearTimeout(timeout); // Clear the timeout if an error occurs
|
|
reject({
|
|
severity: Severity.Error,
|
|
message:
|
|
"Unable to connect to Minecraft server via WebSocket on port 25565: " +
|
|
err,
|
|
});
|
|
socket.close(); // Close the WebSocket connection after error
|
|
};
|
|
|
|
socket.onclose = (event) => {
|
|
clearTimeout(timeout); // Clear the timeout when the connection is closed
|
|
if (!event.wasClean) {
|
|
reject({
|
|
severity: Severity.Error,
|
|
message:
|
|
"WebSocket connection closed unexpectedly to Minecraft server on port 25565.",
|
|
});
|
|
}
|
|
};
|
|
|
|
socket.onmessage = (event) => {
|
|
// Optionally handle any WebSocket messages if necessary
|
|
};
|
|
});
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: "Forgejo",
|
|
steps: [
|
|
{
|
|
name: "Fetch Index",
|
|
run: () => {
|
|
const service_url = "/web/access/git.smgames.club";
|
|
return fetch(service_url)
|
|
.then((response) => {
|
|
if (response.ok) {
|
|
return {
|
|
severity: Severity.OK,
|
|
message: "Able to fetch index.",
|
|
};
|
|
} else {
|
|
return {
|
|
severity: Severity.Error,
|
|
message: "Index response was not OK: " +
|
|
response.statusText,
|
|
};
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
return {
|
|
severity: Severity.Error,
|
|
message:
|
|
"Unable to get a response when querying the domain index: " +
|
|
error,
|
|
};
|
|
});
|
|
},
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: "Social",
|
|
steps: [
|
|
{
|
|
name: "Fetch Index",
|
|
run: () => {
|
|
const service_url = "/web/access/social.smgames.club";
|
|
return fetch(service_url)
|
|
.then((response) => {
|
|
if (response.ok) {
|
|
return {
|
|
severity: Severity.OK,
|
|
message: "Able to fetch index.",
|
|
};
|
|
} else {
|
|
return {
|
|
severity: Severity.Error,
|
|
message: "Index response was not OK: " +
|
|
response.statusText,
|
|
};
|
|
}
|
|
})
|
|
.catch((error) => {
|
|
return {
|
|
severity: Severity.Error,
|
|
message:
|
|
"Unable to get a response when querying the domain index: " +
|
|
error,
|
|
};
|
|
});
|
|
},
|
|
},
|
|
]
|
|
}
|
|
]);
|
|
|
|
// Run all diagnostics
|
|
export async function run_diagnostics() {
|
|
for (const diagnostic of diagnostics.value) {
|
|
try {
|
|
if (diagnostic.steps === undefined || diagnostic.steps.length === 0) {
|
|
diagnostic.status = {
|
|
severity: Severity.Skip,
|
|
message: "No steps available to take.",
|
|
};
|
|
continue;
|
|
}
|
|
diagnostic.status = {
|
|
severity: Severity.OK,
|
|
message: "Successfully verified.",
|
|
};
|
|
for (const step of diagnostic.steps) {
|
|
try {
|
|
const res = await step.run();
|
|
step.status = res;
|
|
} catch (err: any) {
|
|
step.status = {
|
|
severity: Severity.Error,
|
|
message: err.message,
|
|
};
|
|
}
|
|
if (step.status.severity === Severity.Error) {
|
|
diagnostic.status = {
|
|
severity: Severity.Error,
|
|
message: "One or more steps failed.",
|
|
};
|
|
}
|
|
}
|
|
} catch (err: any) {
|
|
diagnostic.status = {
|
|
severity: Severity.Error,
|
|
message: err.message,
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
// Run diagnostics on load
|
|
run_diagnostics();
|