Skip to content

Commit

Permalink
wip: update warning handling
Browse files Browse the repository at this point in the history
  • Loading branch information
tabarra committed Nov 29, 2023
1 parent b9d6318 commit 5fbd758
Show file tree
Hide file tree
Showing 19 changed files with 160 additions and 120 deletions.
76 changes: 32 additions & 44 deletions core/components/UpdateChecker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,13 @@ import { z } from "zod";
import got from '@core/extras/got.js';
import { txEnv } from '@core/globalData';
import consoleFactory from '@extras/console';
import { UpdateDataType } from '@shared/otherTypes';
import TxAdmin from '@core/txAdmin';
import { UpdateAvailableEventType } from '@shared/socketioTypes';
const console = consoleFactory(modulename);


type txUpdateDataType = {
semverDiff: semver.ReleaseType | null;
latest: string;
color: 'info' | 'secondary' | 'success' | 'warning' | 'danger';
};

type fxsUpdateDataType = {
color: 'info' | 'secondary' | 'success' | 'warning' | 'danger';
message: string;
subtext: string;
downloadLink: string;
};

//Schemas
const txVersion = z.string().refine(
(x) => x !== '0.0.0',
{ message: 'must not be 0.0.0' }
Expand All @@ -40,12 +31,14 @@ const changelogRespSchema = z.object({
});



export default class UpdateChecker {
txUpdateData?: txUpdateDataType;
fxsUpdateData?: fxsUpdateDataType;
#txAdmin: TxAdmin;
txaUpdateData?: UpdateDataType;
fxsUpdateData?: UpdateDataType;

constructor(txAdmin: TxAdmin) {
this.#txAdmin = txAdmin;

constructor() {
//Check for updates ASAP
this.checkChangelog();

Expand Down Expand Up @@ -84,19 +77,17 @@ export default class UpdateChecker {
console.warn('A patch (bug fix) update is available for txAdmin.');
console.warn('If you are experiencing any kind of issue, please update now.');
console.warn('For more information: https://discord.gg/uAmsGa2');
this.txUpdateData = {
semverDiff,
latest: apiResponse.latest_txadmin,
color: 'secondary',
this.txaUpdateData = {
version: apiResponse.latest_txadmin,
isImportant: false,
};
} else {
console.error('This version of txAdmin is outdated.');
console.error('Please update as soon as possible.');
console.error('For more information: https://discord.gg/uAmsGa2');
this.txUpdateData = {
semverDiff,
latest: apiResponse.latest_txadmin,
color: 'danger',
this.txaUpdateData = {
version: apiResponse.latest_txadmin,
isImportant: true,
};
}
}
Expand All @@ -106,45 +97,42 @@ export default class UpdateChecker {
}

//Checking FXServer version
//TODO: logic copied from dashboard webroute, adapt to new thing
try {
if (txEnv.fxServerVersion < apiResponse.critical) {
const shouldUpdate = {
color: 'danger',
message: 'A critical update is available for FXServer, you should update now.',
} as const;
if (apiResponse.critical > apiResponse.recommended) {
this.fxsUpdateData = {
...shouldUpdate,
subtext: `critical update ${txEnv.fxServerVersion}${apiResponse.critical}`,
downloadLink: apiResponse.critical_download,
version: apiResponse.critical.toString(),
isImportant: true,
}
} else {
this.fxsUpdateData = {
...shouldUpdate,
subtext: `recommended update ${txEnv.fxServerVersion}${apiResponse.recommended}`,
downloadLink: apiResponse.recommended_download,
version: apiResponse.recommended.toString(),
isImportant: true,
}
}
} else if (txEnv.fxServerVersion < apiResponse.recommended) {
this.fxsUpdateData = {
color: 'warning',
message: 'A recommended update is available for FXServer, you should update.',
subtext: `recommended update ${txEnv.fxServerVersion}${apiResponse.recommended}`,
downloadLink: apiResponse.recommended_download,
version: apiResponse.recommended.toString(),
isImportant: true,
};
} else if (txEnv.fxServerVersion < apiResponse.optional) {
this.fxsUpdateData = {
color: 'info',
message: 'An optional update is available for FXServer.',
subtext: `optional update ${txEnv.fxServerVersion}${apiResponse.optional}`,
downloadLink: apiResponse.optional_download,
version: apiResponse.optional.toString(),
isImportant: false,
};
}
} catch (error) {
console.warn('Error checking for FXServer updates. Enable verbosity for more information.');
console.verbose.dir(error);
}

//Sending event to the UI
if (this.txaUpdateData || this.fxsUpdateData) {
this.#txAdmin.webServer.webSocket.pushEvent<UpdateAvailableEventType>('updateAvailable', {
fxserver: this.fxsUpdateData,
txadmin: this.txaUpdateData,
});
}
}
};

Expand Down
6 changes: 4 additions & 2 deletions core/components/WebServer/getReactIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,10 @@ export default async function getReactIndex(ctx: CtxWithVars | AuthedCtx) {
const serverName = ctx.txAdmin.globalConfig.serverName || ctx.txAdmin.info.serverProfile;
const injectedConsts = {
//env
fxServerVersion: displayFxserverVersion,
txAdminVersion: txEnv.txAdminVersion,
fxsVersion: displayFxserverVersion,
fxsOutdated: ctx.txAdmin.updateChecker.fxsUpdateData,
txaVersion: txEnv.txAdminVersion,
txaOutdated: ctx.txAdmin.updateChecker.txaUpdateData,
isZapHosting: convars.isZapHosting, //not in use
isPterodactyl: convars.isPterodactyl, //not in use
isWebInterface: ctx.txVars.isWebInterface,
Expand Down
2 changes: 0 additions & 2 deletions core/components/WebServer/middlewares/ctxUtilsMw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,6 @@ export default async function ctxUtilsMw(ctx: CtxWithVars, next: Next) {
uiTheme: legacyTheme,
fxServerVersion: displayFxserverVersion,
txAdminVersion: txEnv.txAdminVersion,
txaOutdated: txAdmin.updateChecker?.txUpdateData,
fxsOutdated: txAdmin.updateChecker?.fxsUpdateData,
jsInjection: getJavascriptConsts({
isZapHosting: convars.isZapHosting, //not in use
isPterodactyl: convars.isPterodactyl, //not in use
Expand Down
32 changes: 31 additions & 1 deletion core/components/WebServer/webSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import TxAdmin from '@core/txAdmin';
import { AuthedAdminType, checkRequestAuth } from './authLogic';
import { SocketWithSession } from './ctxTypes';
import { isIpAddressLocal } from '@extras/isIpAddressLocal';
import { txEnv } from '@core/globalData';
const console = consoleFactory(modulename);

//Types
Expand Down Expand Up @@ -44,11 +45,18 @@ const terminateSession = (socket: SocketWithSession, reason: string, shouldLog =
}
} catch (error) { }
};
const forceUiReload = (socket: SocketWithSession) => {
try {
socket.emit('refreshToUpdate');
socket.disconnect();
} catch (error) { }
};

export default class WebSocket {
readonly #txAdmin: TxAdmin;
readonly #io: SocketIO;
readonly #rooms: Record<RoomNames, RoomType>;
#eventBuffer: { name: string, data: any }[] = [];

constructor(txAdmin: TxAdmin, io: SocketIO) {
this.#txAdmin = txAdmin;
Expand All @@ -69,6 +77,11 @@ export default class WebSocket {
* NOTE: For now the user MUST join a room, needs additional logic for 'web' room
*/
handleConnection(socket: SocketWithSession) {
//Check the UI version
if (socket.handshake.query.uiVersion !== txEnv.txAdminVersion) {
return forceUiReload(socket);
}

try {
//Checking for session auth
const reqIp = getIP(socket);
Expand Down Expand Up @@ -140,7 +153,7 @@ export default class WebSocket {


/**
* Adds data to the buffer
* Adds data to the a room buffer
*/
buffer<T>(roomName: RoomNames, data: T) {
const room = this.#rooms[roomName];
Expand All @@ -165,6 +178,7 @@ export default class WebSocket {
* NOTE: this will also send data to users that no longer have permissions
*/
flushBuffers() {
//Sending room data
for (const [roomName, room] of Object.entries(this.#rooms)) {
if (room.cumulativeBuffer && room.outBuffer.length) {
this.#io.to(roomName).emit(room.eventName, room.outBuffer);
Expand All @@ -180,6 +194,12 @@ export default class WebSocket {
room.outBuffer = null;
}
}

//Sending events
for (const event of this.#eventBuffer) {
this.#io.emit(event.name, event.data);
}
this.#eventBuffer = [];
}


Expand All @@ -196,4 +216,14 @@ export default class WebSocket {
room.outBuffer = room.initialData();
});
}


/**
* Broadcasts an event to all connected clients
* This is used for data syncs that are not related to a specific room
* eg: update available
*/
pushEvent<T>(name: string, data: T) {
this.#eventBuffer.push({ name, data });
}
};
2 changes: 1 addition & 1 deletion core/txAdmin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export default class TxAdmin {
this.persistentCache = new PersistentCache(this);
globalsInternal.persistentCache = this.persistentCache;

this.updateChecker = new UpdateChecker();
this.updateChecker = new UpdateChecker(this);
globalsInternal.updateChecker = this.updateChecker;
} catch (error) {
console.error(`Error starting main components:`);
Expand Down
10 changes: 10 additions & 0 deletions core/webroutes/authentication/verifyPassword.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const modulename = 'WebServer:AuthVerifyPassword';
import { AuthedAdmin, PassSessAuthType } from '@core/components/WebServer/authLogic';
import { InitializedCtx } from '@core/components/WebServer/ctxTypes';
import { txEnv } from '@core/globalData';
import consoleFactory from '@extras/console';
import { ApiVerifyPasswordResp, ReactAuthDataType } from '@shared/authApiTypes';
import { z } from 'zod';
Expand All @@ -17,6 +18,15 @@ export type ApiVerifyPasswordReqSchema = z.infer<typeof bodySchema>;
* Verify login
*/
export default async function AuthVerifyPassword(ctx: InitializedCtx) {
//Check UI version
const { uiVersion } = ctx.request.query;
if(uiVersion && uiVersion !== txEnv.txAdminVersion){
return ctx.send<ApiVerifyPasswordResp>({
error: `refreshToUpdate`,
});
}

//Checking body
const schemaRes = bodySchema.safeParse(ctx.request.body);
if (!schemaRes.success) {
return ctx.send<ApiVerifyPasswordResp>({
Expand Down
2 changes: 1 addition & 1 deletion docs/dev_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Processo:
- [x][1h] dynamic title
- [x][1h] dynamic favicon
- [x][1d] server status
- [ ][4h] update notices via socket.io
- [x][4h] update notices via socket.io
- [x][2h] tooltips on everything
- [ ][1h] zap hosting advertisement
- [ ][1d] toasts API
Expand Down
2 changes: 1 addition & 1 deletion panel/src/components/ErrorFallback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export function GenericErrorBoundaryCard(props: GenericErrorBoundaryCardProps) {
<p>
Versions:&nbsp;
<code className="text-muted-foreground">
txAdmin v{window.txConsts.txAdminVersion} atop FXServer b{window.txConsts.fxServerVersion}
txAdmin v{window.txConsts.txaVersion} atop FXServer b{window.txConsts.fxsVersion}
</code>
</p>
<p>
Expand Down
1 change: 0 additions & 1 deletion panel/src/hooks/playerlist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,3 @@ export const useProcessPlayerlistEvents = () => {
}
}
};

31 changes: 21 additions & 10 deletions panel/src/hooks/useWarningBar.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,47 @@
import { UpdateDataType } from '@shared/otherTypes';
import { UpdateAvailableEventType } from '@shared/socketioTypes';
import { atom, useAtom, useSetAtom } from 'jotai';

//FIXME: this should probably be somewhere else
type UpdateDataType = false | {
version: string;
isImportant: boolean;
}


/**
* Atoms
*/
const offlineWarningAtom = atom(false);
const txUpdateDataAtom = atom<UpdateDataType>(false);
const fxUpdateDataAtom = atom<UpdateDataType>(false);
const fxUpdateDataAtom = atom<UpdateDataType>(window.txConsts.fxsOutdated);
const txUpdateDataAtom = atom<UpdateDataType>(window.txConsts.txaOutdated);


/**
* Hooks
*/
export default function useWarningBar() {
const [offlineWarning, setOfflineWarning] = useAtom(offlineWarningAtom);
const [txUpdateData, setTxUpdateData] = useAtom(txUpdateDataAtom);
const [fxUpdateData, setFxUpdateData] = useAtom(fxUpdateDataAtom);
const [txUpdateData, setTxUpdateData] = useAtom(txUpdateDataAtom);

return {
offlineWarning, setOfflineWarning,
txUpdateData, setTxUpdateData,
fxUpdateData, setFxUpdateData,
txUpdateData, setTxUpdateData,
};
}

//Marks the socket as offline or online
export const useSetOfflineWarning = () => {
return useSetAtom(offlineWarningAtom);
}

export const useProcessUpdateAvailableEvent = () => {
const setFxUpdateData = useSetAtom(fxUpdateDataAtom);
const setTxUpdateData = useSetAtom(txUpdateDataAtom);

return (event: UpdateAvailableEventType) => {
setFxUpdateData(event.fxserver);
setTxUpdateData(event.txadmin);

//Hacky override to prevent sticky update warnings after updating
//NOTE: after adding the version check on socket handshake, i'm not sure if this is still required
window.txConsts.fxsOutdated = event.fxserver;
window.txConsts.txaOutdated = event.txadmin;
}
};
4 changes: 2 additions & 2 deletions panel/src/layout/AuthShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ export default function AuthShell() {

<div>
<small className="text-muted-foreground text-sm font-light">
tx: <strong>v{window.txConsts.txAdminVersion}</strong>
tx: <strong>v{window.txConsts.txaVersion}</strong>
&nbsp;|
fx: <strong>b{window.txConsts.fxServerVersion}</strong>
fx: <strong>b{window.txConsts.fxsVersion}</strong>
</small>
</div>
</div>
Expand Down
5 changes: 4 additions & 1 deletion panel/src/layout/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,10 @@ export function Header() {
<div className="h-14 lg:px-3 px-2 w-full max-w-[1920px] flex flex-row justify-between transition-all">
<div className="flex flex-row items-center flex-grow gap-5 mr-5">
<div className="w-sidebar hidden xl:flex justify-center">
<span className="h-7 w-36 bg-accent text-accent-foreground rounded text-center p-0.5 font-bold tracking-widest">FULL LOGO</span>
<span
className="h-7 w-36 bg-accent text-accent-foreground rounded text-center p-0.5 font-bold tracking-widest"
title={`tx: v${window.txConsts.txaVersion} | fx: b${window.txConsts.fxsVersion}`}
>FULL LOGO</span>
</div>
<div className="h-8 w-8 lg:h-10 lg:w-10 rounded hidden sm:max-xl:block bg-accent text-accent-foreground text-center">
TX
Expand Down

0 comments on commit 5fbd758

Please sign in to comment.