Skip to content

Commit

Permalink
Extract server related functions into new class AuthenticationServer …
Browse files Browse the repository at this point in the history
…from Authentication
  • Loading branch information
TrojanerHD committed Sep 8, 2023
1 parent 7a8142a commit ad8c527
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 45 deletions.
49 changes: 8 additions & 41 deletions src/messages/permissions/Authentication.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import express, { Express } from 'express';
import DiscordClient from '../../DiscordClient';
import { URLSearchParams } from 'url';
import Common, { requestWrapper as request } from '../../common';
import { requestWrapper as request } from '../../common';
import { RequestOptions } from 'https';
import { Server } from 'http';
import Settings, { SettingsJSON } from '../../Settings';
import { GuildInfo } from '../../settings/SettingsDB';
import GuildSettings from '../../settings/GuildSettings';
import { Guild } from 'discord.js';
import AuthenticationServer from './AuthenticationServer';
import { Request, Response } from 'express-serve-static-core';
import { ParsedQs } from 'qs';

export interface TokenResponse {
access_token: string;
Expand All @@ -19,32 +17,18 @@ export interface TokenResponse {

export type MaybeTokenResponse = TokenResponse | { error: string } | void;

interface Listener {
export interface Listener {
guildId: string;
listener: (json?: MaybeTokenResponse) => void;
}

/**
* Creates an express app for the user to authorize the bot to allow changing command permissions
* Handles authentication for command permission updating
*/
export default abstract class Authentication {
static #app: Express = express();
static #server?: Server = undefined;
static #listeners: Listener[] = [];

/**
* Starts the express server if it has not been started.
* If no guilds are left that need authentication, the express server is stopped
*/
public static startServer(): void {
if (Authentication.#server !== undefined) {
if (!Authentication.#server.listening) Authentication.listen();
return;
}
if (Settings.settings.logging !== 'errors')
console.log('Start express server');

Authentication.#app.get('/', (req, res): void => {
static authenticationCallback(req: Request<{}, any, any, ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>, number>): void {
const request = Authentication.makeRequest(
req.query.code as string,
`${req.protocol}://${req.headers.host as string}${req.path}`
Expand All @@ -60,27 +44,10 @@ export default abstract class Authentication {

// Stop express app
if (Authentication.#listeners.length - 1 <= 0) {
Authentication.#server?.close();
AuthenticationServer.closeServer();
if (Settings.settings.logging !== 'errors')
console.log('Stop express server');
}
});
Authentication.listen();
}

/**
* Updates internal server parameter to listen on the app
*/
private static listen(): void {
if (
Settings.settings['express-port'] !== undefined &&
Settings.settings['express-port'] !== null &&
Settings.settings['express-port']! > 0
)
Authentication.#server = Authentication.#app.listen(
Settings.settings['express-port']
);
else Authentication.#server = Authentication.#app.listen();
}

/**
Expand Down
51 changes: 51 additions & 0 deletions src/messages/permissions/AuthenticationServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import express, { Express } from 'express';
import { Server } from 'http';
import Settings from '../../Settings';
import Authentication, { Listener, MaybeTokenResponse } from './Authentication';

/**
* Creates an express app for the user to authorize the bot to allow changing command permissions
*/
export default class AuthenticationServer {
static #app: Express = express();
static #server?: Server = undefined;

/**
* Starts the express server if it has not been started.
* If no guilds are left that need authentication, the express server is stopped
*/
public static startServer(): void {
if (AuthenticationServer.#server !== undefined) {
if (!AuthenticationServer.#server.listening)
AuthenticationServer.listen();
return;
}
if (Settings.settings.logging !== 'errors')
console.log('Start express server');

AuthenticationServer.#app.get('/', Authentication.authenticationCallback.bind(Authentication));
AuthenticationServer.listen();
}

/**
* Updates internal server parameter to listen on the app
*/
private static listen(): void {
if (
Settings.settings['express-port'] !== undefined &&
Settings.settings['express-port'] !== null &&
Settings.settings['express-port']! > 0
)
AuthenticationServer.#server = AuthenticationServer.#app.listen(
Settings.settings['express-port']
);
else AuthenticationServer.#server = AuthenticationServer.#app.listen();
}

/**
* Closes the server
*/
static closeServer(): void {
this.#server?.close();
}
}
5 changes: 3 additions & 2 deletions src/messages/permissions/CommandPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Authentication, { MaybeTokenResponse } from './Authentication';
import TokenHelper from './TokenHelper';
import { RequestOptions } from 'https';
import GuildSettings from '../../settings/GuildSettings';
import AuthenticationServer from './AuthenticationServer';

/**
* Set permissions for commands
Expand Down Expand Up @@ -45,7 +46,7 @@ export default class CommandPermissions {
.catch((err: Error): void => {
if (err.message !== 'invalid_grant') throw new Error(err.message);

Authentication.startServer();
AuthenticationServer.startServer();
Authentication.addListener(
this.#guild.id,
this.accessTokenReceived.bind(this)
Expand All @@ -54,7 +55,7 @@ export default class CommandPermissions {
else this.accessTokenReceived();
return;
}
Authentication.startServer();
AuthenticationServer.startServer();
Authentication.addListener(
this.#guild.id,
this.accessTokenReceived.bind(this)
Expand Down
5 changes: 3 additions & 2 deletions src/messages/permissions/TokenHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Authentication, { MaybeTokenResponse, TokenResponse } from './Authenticat
import { GuildInfo } from '../../settings/SettingsDB';
import GuildSettings from '../../settings/GuildSettings';
import Common from '../../common';
import AuthenticationServer from './AuthenticationServer';

/**
* Util functions to handle a Discord user token
Expand All @@ -14,7 +15,7 @@ export default abstract class TokenHelper {
* @returns The access token request promise
*/
static async getAccessToken(guild: Guild): Promise<void> {
Authentication.startServer();
AuthenticationServer.startServer();

const refreshToken: string | undefined =
await TokenHelper.getRefreshToken(guild.id);
Expand All @@ -35,7 +36,7 @@ export default abstract class TokenHelper {
public static async getRefreshToken(
guildId: string
): Promise<string | undefined> {
Authentication.startServer();
AuthenticationServer.startServer();

const settings: GuildInfo = await GuildSettings.settings(guildId);
return settings.refreshToken !== '' ? settings.refreshToken : undefined;
Expand Down

0 comments on commit ad8c527

Please sign in to comment.