Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Atmakuja db changes #10

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
DB initial login test
  • Loading branch information
Red-Pyramid-Head authored and Pieloaf committed Nov 21, 2023
commit 3fa6093f0f3dcc5f1f88ff993d1e1d81d2bec446
6 changes: 6 additions & 0 deletions .env.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export MY_SQL_DB_HOST = '';
export MY_SQL_DB_USER = '';
export MY_SQL_DB_PASSWORD = '';
export MY_SQL_DB_PORT = '';
export MY_SQL_DB_DATABASE = '';
export MY_SQL_DB_CONNECTION_LIMIT = '';
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,30 @@
"main": "./build/index.js",
"scripts": {
"dev": "ts-node-dev --respawn src/index.ts",
"build": "tsc -p ./"
"build": "tsc && tsc-alias"
},
"author": "Pieloaf",
"license": "ISC",
"dependencies": {
"async-mqtt": "^2.6.3",
"dotenv": "^16.3.1",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.0"
"jsonwebtoken": "^9.0.0",
"mysql": "^2.18.1"
},
"devDependencies": {
"@types/express": "^4.17.14",
"@types/jsonwebtoken": "^9.0.2",
"@types/mysql": "^2.15.21",
"@types/node": "^18.11.0",
"@types/ws": "^8.5.3",
"discord-api-types": "^0.37.61",
"ts-node-dev": "^2.0.0",
"tsc": "^2.0.4",
"tsc-alias": "^1.8.8",
"typescript": "^4.8.4"
},
"engines": {
"node": ">=18.18.2"
}
}
}
56 changes: 56 additions & 0 deletions src/api/utils/mysql.connector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { createPool, Pool} from 'mysql';
import mysql, { Connection, MysqlError } from 'mysql';
import { DATA_SOURCES } from '../../config/vars.config';
const dataSource = DATA_SOURCES.mySqlDataSource;

//let pool: Pool;
let connection: Connection;
/**
* generates pool connection to be used throughout the app
*/
export const init = () => {
try {
connection = mysql.createConnection({
host : '127.0.0.1',
user : 'root',
password : 'root',
database : 'banner_saga_factions'
});
/*pool = createPool({
connectionLimit: dataSource.DB_CONNECTION_LIMIT,
host: dataSource.DB_HOST,
user: dataSource.DB_USER,
password: dataSource.DB_PASSWORD,
database: dataSource.DB_DATABASE,
});*/

console.debug('MySql Adapter Pool generated successfully');
} catch (error) {
console.error('[mysql.connector][init][Error]: ', error);
throw new Error('failed to initialized pool');
}
};

/**
* executes SQL queries in MySQL db
*
* @param {string} query - provide a valid SQL query
* @param {string[] | Object} params - provide the parameterized values used
* in the query
*/
export const execute = <T>(query: string, params: string[] | Object): Promise<T> => {
try {
if (!connection) throw new Error('Pool was not created. Ensure pool is created when running the app.');

return new Promise<T>((resolve, reject) => {
connection.query(query, params, (error, results) => {
if (error) reject(error);
else resolve(results);
});
});

} catch (error) {
console.error('[mysql.connector][execute][Error]: ', error);
throw new Error('failed to execute MySQL query');
}
}
42 changes: 42 additions & 0 deletions src/api/utils/users/users.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// import { Request, RequestHandler, Response } from 'express';
// import {
// ITeam,
// IGetTeamReq,
// IAddTeamReq,
// IUpdateTeamReq,
// IDeleteTeamReq
// } from './users.model';
// import * as UserService from './users.service';

// /**
// * Get active team records
// *
// * @param req Express Request
// * @param res Express Response
// */
// export const getTeams: RequestHandler = (req: Request, res: Response) => {
// const activeTeams = TEAMS.filter((team) => team.isActive);
// res.send(activeTeams);
// };

// /**
// * Get team record based on id provided
// *
// * @param req Express Request
// * @param res Express Response
// */
// // @ts-ignore
// export const getUsersById: RequestHandler = async (req: IGetTeamReq, res: Response) => {
// try {
// const team = await UserService.getUsersById(req.params.id);

// res.status(200).json({
// team
// });
// } catch (error) {
// console.error('[teams.controller][getTeamById][Error] ', typeof error === 'object' ? JSON.stringify(error) : error);
// res.status(500).json({
// message: 'There was an error when fetching team'
// });
// }
// };
13 changes: 13 additions & 0 deletions src/api/utils/users/users.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export class User {
id: number;
username: string;
password: string;
steam_id: string;

constructor(id: number, username: string, password: string, steam_id: string) {
this.id = id;
this.username = username;
this.password = password;
this.steam_id = steam_id;
}
}
15 changes: 15 additions & 0 deletions src/api/utils/users/users.queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export const UsersQueries = {
GetUsers: `
SELECT
*
FROM banner_saga_factions.users as u
`,

GetUserById: `
SELECT
*
FROM banner_saga_factions.users as u
WHERE
id = ?
`
};
18 changes: 18 additions & 0 deletions src/api/utils/users/users.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { execute } from "../mysql.connector";

import { UsersQueries } from "./users.queries";
import { User } from "./users.model";

/**
* gets active teams
*/
export const getUsers = async () => {
return execute<User[]>(UsersQueries.GetUsers, []);
};

/**
* gets a team based on id provided
*/
export const getUserById = async (id: User['id']) => {
return execute<User>(UsersQueries.GetUserById, [id]);
};
10 changes: 10 additions & 0 deletions src/config/vars.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const DATA_SOURCES = {
mySqlDataSource: {
DB_HOST: process.env.MY_SQL_DB_HOST,
DB_USER: process.env.MY_SQL_DB_USER,
DB_PASSWORD: process.env.MY_SQL_DB_PASSWORD,
DB_PORT: process.env.MY_SQL_DB_PORT,
DB_DATABASE: process.env.MY_SQL_DB_DATABASE,
DB_CONNECTION_LIMIT: process.env.MY_SQL_DB_CONNECTION_LIMIT ? parseInt(process.env.MY_SQL_DB_CONNECTION_LIMIT) : 4,
}
};
4 changes: 4 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ import { config } from "dotenv";
import { AccountRouter } from "./services/account";
import { DiscordLoginRouter } from "./services/auth/discord";
import { verify } from "jsonwebtoken";
import * as MySQLConnector from "./api/utils/mysql.connector";

config();

// create database pool
MySQLConnector.init();

const app = express();
const ServiceRouter = Router();

Expand Down
45 changes: 34 additions & 11 deletions src/services/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { GameModes } from "../../const";
import { Router } from "express";
import { verify } from "jsonwebtoken";
import { config } from "dotenv";
import { getUserById } from "@api/utils/users/users.service";
import { User } from "@api/utils/users/users.model";

config();

Expand All @@ -27,15 +29,20 @@ const getInitialData = (): any[] => {
return initialData;
};

const getUser = (user_id: number) => {
const getUser = async (user_id: number) => {
// look up user in database and return data
// needs some form of authentication
// maybe a user_id stored in a jwt token
// which can be passed as the username to the game from an external client
// anyway... on with the demo
return JSON.parse(readFileSync("./data/accounts.json", "utf-8")).find((acc: any) => acc.user_id === user_id);

let user = await getUserById(user_id);

return user;
};

type SessionOptions = (s: Session) => void;

export class Session {
display_name: string;
user_id: number;
Expand All @@ -45,9 +52,9 @@ export class Session {
battle_id?: string; // maybe not needed?
match_handle: number = 0; // TODO: this is a work around

constructor(user_id: number) {
this.display_name = getUser(user_id).username;
this.user_id = user_id;
constructor() {
this.display_name = "";
this.user_id = 0;
this.session_key = generateKey();
this.data = getInitialData();
}
Expand All @@ -65,6 +72,23 @@ export class Session {
pushData(...data: any) {
this.data.push(...data);
}

public SetDisplayName(displayName: string): SessionOptions {
return (s: Session): void => {
s.display_name = displayName;
};
}

public static async GetSessionInit(user_id: number) {
const user = await getUser(user_id);
var userJson = JSON.parse(JSON.stringify(user));
const s = new Session();

s.display_name = userJson[0].username;
s.user_id = userJson[0].id;

return s;
}
}

var sessions: { [key: string]: Session } = {};
Expand All @@ -73,8 +97,8 @@ export const sessionHandler = {
getSessions: (filterFunc: (s: Session, index: number, array: Session[]) => void = (_) => true): Session[] => {
return (Object.values(sessions) as Session[]).filter(filterFunc);
},
addSession: (user_id: number) => {
let session = new Session(user_id);
addSession: async (user_id: number) => {
const session = await Session.GetSessionInit(user_id);
sessions[session.session_key] = session;
return session.asJson();
},
Expand All @@ -87,11 +111,10 @@ export const sessionHandler = {
},
};

AuthRouter.post("/login/:httpVersion", (req, res) => {
AuthRouter.post("/login/:http_version", async (req, res) => {
let data = verify(req.body.steam_id, process.env.JWT_SECRET as string);
console.log(data); // Temporary
// TODO: lookup user in database
let userData = sessionHandler.addSession(293850);
console.log((data as any).discord_id);
let userData = await sessionHandler.addSession((data as any).discord_id);
res.json(userData);
});

Expand Down
22 changes: 9 additions & 13 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */

/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */

/* Language and Environment */
"target": "ES2017" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"target": "ES2022" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
Expand All @@ -23,26 +21,27 @@
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */

/* Modules */
"module": "commonjs" /* Specify what module code is generated. */,
"module": "NodeNext" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
"moduleResolution": "NodeNext" /* Specify how TypeScript looks up a file from a given module specifier. */,
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
"paths": {
"@api/*": [
"./src/api/*"
]
}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */

/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */

/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
Expand All @@ -67,14 +66,12 @@
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */

/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,

/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
Expand All @@ -95,9 +92,8 @@
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */

/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}
}
Loading