Commit bdddedf3 authored by Geovanny's avatar Geovanny

Nav bar done and some login

parent 541ddfa2
......@@ -3,6 +3,7 @@ server/node_modules/
server/.env
discord/.env
discord/__pycache__
web/node_modules
*.pyc
__pycache__
.vscode
\ No newline at end of file
......@@ -45,7 +45,7 @@ class UnitManager(commands.Cog):
except asyncio.TimeoutError:
return await ctx.send('Operation aborted')
if msg.content.lower() != 'yes':
if not(msg.content.lower() == 'yes' or msg.content.lower() == 'y'):
return await ctx.send('Operation aborted')
try:
await Api.put('/unit/{0}'.format(data['id']), params)
......@@ -91,13 +91,13 @@ class UnitManager(commands.Cog):
embed.add_field(name='ID', value=unit_data.id, inline=True)
embed.add_field(name='Name', value=unit_data.name)
embed.add_field(name='Type', value=unit_data.type, inline=True)
embed.add_field(name='Type', value=unit_data.unit_type, inline=True)
embed.add_field(name='HP', value=unit_data.hp)
embed.add_field(name='Stars', value=(unit_data.stars/2))
embed.add_field(name='Speed', value=unit_data.speed, inline=True)
embed.add_field(name='Range', value=unit_data.range)
embed.add_field(name='Ammo', value=unit)
embed.add_field(name='Leadership Cost', value=unit_data.leadership)
embed.add_field(name='Troop Count', value=unit_data.troop_count, inline=True)
embed.add_field(name='Range', value=unit_data.unit_range)
embed.add_field(name='Ammo', value=unit_data.ammo)
embed.add_field(name='Troop Count', value=unit_data.tc, inline=True)
embed.add_field(name='Piercing AP', value=unit_data.pap, inline=True)
embed.add_field(name='Piercing Dg', value=unit_data.pd, inline=True)
embed.add_field(name='Piercing Df', value=unit_data.pdf, inline=True)
......@@ -108,6 +108,8 @@ class UnitManager(commands.Cog):
embed.add_field(name='Blunt Dg', value=unit_data.bd, inline=True)
embed.add_field(name='Blunt Df', value=unit_data.bdf, inline=True)
embed.add_field(name='Labour', value=unit_data.labour, inline=True)
embed.add_field(name='Hero Level', value=unit_data.hl, inline=True)
embed.add_field(name='Leadership Cost', value=unit_data.ld)
await ctx.send(embed=embed)
......@@ -127,7 +129,7 @@ class UnitManager(commands.Cog):
await self.createUnitTable(ctx, units_data)
async def createUnitTable(self, ctx, data):
return await EmbedStyle.createPages(self.bot, ctx, data, 5, self.createUnitPage)
return await EmbedStyle.createPages(self.bot, ctx, data, 10, self.createUnitPage)
def createUnitPage(self, data, minI, maxI):
embed = discord.Embed(color=0x19212d)
......
class Unit(object):
def __init__(self, id, name, type, stars=0, hp=0, pap=0, pd=0, sap=0, sd=0, bap=0, bd=0, pdf=0, sdf=0, bdf=0, leadership=0, troop_count=0, hero_level=0, speed=0, range=0, ammo=0, labour=0,
def __init__(self, id, name, unit_type, stars=0, hp=0, pap=0, pd=0, sap=0, sd=0, bap=0, bd=0, pdf=0, sdf=0, bdf=0, ld=0, tc=0, hl=0, speed=0, unit_range=0, ammo=0, labour=0,
img=None,
vet_img=None,
unit_level=0,
elite_flg=None):
if unit_type=='':
unit_type = 'None'
self.id = id
self.name = name
self.type = type
self.unit_type = unit_type
self.stars = stars
self.hp = hp
self.pap = pap
......@@ -19,11 +21,11 @@ class Unit(object):
self.pdf = pdf
self.sdf = sdf
self.bdf = bdf
self.leadership = leadership
self.troop_count = troop_count
self.hero_level = hero_level
self.ld = ld
self.tc = tc
self.hl = hl
self.speed = speed
self.range = range
self.unit_range = unit_range
self.ammo = ammo
self.labour = labour
self.img = img
......@@ -46,4 +48,4 @@ class Unit(object):
}
def __str__(self):
return '[{0}] {1}\t| {2}\t| {3}'.format(self.id, self.name, self.type, self.stars)
\ No newline at end of file
return '[{0}] {1}\t| {2}\t| {3}'.format(self.id, self.name, self.unit_type, self.stars)
\ No newline at end of file
from discord_argparse import *
insert_param_converter = ArgumentConverter(
type = OptionalArgument(
unit_type = OptionalArgument(
str,
doc='Type of Unit',
),
......@@ -62,10 +62,10 @@ insert_param_converter = ArgumentConverter(
doc='Hero level required',
),
speed = OptionalArgument(
int,
float,
doc='Speed of unit',
),
range = OptionalArgument(
unit_range = OptionalArgument(
int,
doc='Range of unit',
),
......@@ -74,7 +74,7 @@ insert_param_converter = ArgumentConverter(
doc='Ammo if unit',
),
labour = OptionalArgument(
int,
float,
doc='Resourse collection labour',
),
img = OptionalArgument(
......@@ -92,7 +92,7 @@ modify_param_converter = ArgumentConverter(
str,
doc='New name',
),
type = OptionalArgument(
unit_type = OptionalArgument(
str,
doc='Type of Unit',
),
......@@ -153,10 +153,10 @@ modify_param_converter = ArgumentConverter(
doc='Hero level required',
),
speed = OptionalArgument(
int,
float,
doc='Speed of unit',
),
range = OptionalArgument(
unit_range = OptionalArgument(
int,
doc='Range of unit',
),
......@@ -165,7 +165,7 @@ modify_param_converter = ArgumentConverter(
doc='Ammo if unit',
),
labour = OptionalArgument(
int,
float,
doc='Resourse collection labour',
),
img = OptionalArgument(
......
......@@ -48,6 +48,8 @@ class UserManager(commands.Cog):
msg = await self.bot.wait_for('message', timeout=30.0, check=check)
except asyncio.TimeoutError:
return await ctx.send('Operation aborted')
if not(msg.content.lower() == 'yes' or msg.content.lower() == 'y'):
return await ctx.send('Operation aborted')
try:
session = await self.bot.getUserSession(ctx.message.author)
await Api.deleteSession('/user/unit/{0}'.format(data['id']), session)
......@@ -76,6 +78,8 @@ class UserManager(commands.Cog):
msg = await self.bot.wait_for('message', timeout=30.0, check=check)
except asyncio.TimeoutError:
return await ctx.send('Operation aborted')
if not(msg.content.lower() == 'yes' or msg.content.lower() == 'y'):
return await ctx.send('Operation aborted')
try:
session = await self.bot.getUserSession(ctx.message.author)
body = params
......@@ -104,11 +108,12 @@ class UserManager(commands.Cog):
msg = await self.bot.wait_for('message', timeout=30.0, check=check)
except asyncio.TimeoutError:
return await ctx.send('Operation aborted')
if not(msg.content.lower() == 'yes' or msg.content.lower() == 'y'):
return await ctx.send('Operation aborted')
try:
session = await self.bot.getUserSession(ctx.message.author)
body = params
body['unit_id'] = data['id']
print(body)
await Api.postSession('/user/unit', body, session)
return await ctx.send('Unit Assigned Successfully')
except ApiError as error:
......@@ -135,7 +140,7 @@ class UserManager(commands.Cog):
for i in range(minI, maxI):
if i < len(data):
unit = data[i]
units_str+= '[{0}] {1}\t| {2}\t| {3}\t| {4}\n'.format(unit.id, unit.name, unit.type, unit.stars, unit.unit_level)
units_str+= '[{0}] {1}\t| {2}\t| {3}\t| {4}\n'.format(unit.id, unit.name, unit.unit_type, unit.stars, unit.unit_level)
embed.add_field(name='id\t| name\t| type\t| stars\t| level', value=units_str)
......
......@@ -5,7 +5,7 @@ param_converter = ArgumentConverter(
str,
doc='Level of Unit',
),
eltie_flg = OptionalArgument(
elite_flg = OptionalArgument(
bool,
doc='Is Unit Elite',
)
......
......@@ -4,13 +4,20 @@ const Koa = require('koa');
const Router = require('@koa/router');
const bodyParser = require('koa-body');
const session = require('koa-session')
const serve = require('koa-static');
const logger = require('koa-logger')
const userRouter = require('./user/route');
const getUser = require('./user/model');
const [userRouter, userAuthRouter] = require('./user/route');
const unitRouter = require('./unit/route');
const SESS_CONFIG = require('./session_config');
const ENV = require('./settings')
const app = new Koa();
const router = new Router();
const authRouter = new Router();
app.use(serve(`${__dirname}/../web`))
app.use(logger())
app.keys = [ENV.SESS_KEY]
app.use(bodyParser());
......@@ -19,8 +26,30 @@ app.use(session(SESS_CONFIG, app));
router.use('/unit', unitRouter.routes(), unitRouter.allowedMethods());
router.use('/user', userRouter.routes(), userRouter.allowedMethods());
//app.use(auth());
authRouter.use('/user', userAuthRouter.routes(), userAuthRouter.allowedMethods());
app.use(router.routes()).use(router.allowedMethods());
// Make sure user is authorized
app.use(async (context, next) => {
if(context.session.user_id){
await next();
console.log(context.status)
} else {
context.response.status = 401;
}
});
// Add user to context
app.use(async (context, next) => {
const user = getUser.getUserFromId(context.session.user_id);
if(user){
context.user = user;
await next();
} else {
context.response.status = 403;
}
});
app.use(authRouter.routes()).use(authRouter.allowedMethods());
app.listen(3000, () => console.log('Server Started'));
\ No newline at end of file
......@@ -57,6 +57,14 @@
"negotiator": "0.6.2"
}
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"any-promise": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
......@@ -100,6 +108,16 @@
"ylru": "^1.2.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
......@@ -116,6 +134,19 @@
"type-is": "^1.6.14"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"content-disposition": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
......@@ -211,6 +242,11 @@
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"formidable": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz",
......@@ -226,6 +262,11 @@
"resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
"integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ="
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"http-assert": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.4.1.tgz",
......@@ -247,6 +288,11 @@
"toidentifier": "1.0.0"
}
},
"humanize-number": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/humanize-number/-/humanize-number-0.0.2.tgz",
"integrity": "sha1-EcCvakcWQ2M1iFiASPF5lUFInBg="
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
......@@ -388,6 +434,17 @@
}
}
},
"koa-logger": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/koa-logger/-/koa-logger-3.2.1.tgz",
"integrity": "sha512-MjlznhLLKy9+kG8nAXKJLM0/ClsQp/Or2vI3a5rbSQmgl8IJBQO0KI5FA70BvW+hqjtxjp49SpH2E7okS6NmHg==",
"requires": {
"bytes": "^3.1.0",
"chalk": "^2.4.2",
"humanize-number": "0.0.2",
"passthrough-counter": "^1.0.0"
}
},
"koa-send": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/koa-send/-/koa-send-5.0.0.tgz",
......@@ -526,6 +583,11 @@
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
},
"passthrough-counter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/passthrough-counter/-/passthrough-counter-1.0.0.tgz",
"integrity": "sha1-GWfZ5m2lcrXAI8eH2xEqOHqxZvo="
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
......@@ -657,6 +719,14 @@
"safe-buffer": "~5.1.0"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
},
"thenify": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz",
......
......@@ -6,6 +6,7 @@
"fs": "0.0.1-security",
"koa": "^2.11.0",
"koa-body": "^4.1.1",
"koa-logger": "^3.2.1",
"koa-session": "^5.13.1",
"koa-static": "^5.0.0",
"promise-mysql": "^4.1.3"
......
......@@ -4,7 +4,7 @@ const db = require('../database/database');
const unitModel = {};
const unit_columns = ['name', 'type', 'stars', 'hp', 'pap', 'pd', 'sap', 'sd', 'bap', 'bp', 'pdf', 'sdf', 'bdf', 'leadership', 'troop_count', 'hero_level', 'speed', 'range', 'ammo', 'labour', 'img', 'vet_img'];
const unit_columns = ['name', 'unit_type', 'stars', 'hp', 'pap', 'pd', 'sap', 'sd', 'bap', 'bp', 'pdf', 'sdf', 'bdf', 'ld', 'tc', 'hl', 'speed', 'unit_range', 'ammo', 'labour', 'img', 'vet_img'];
unitModel.getAll = async () =>{
const sql_text = 'SELECT * FROM units ORDER BY name ASC;';
......
......@@ -9,12 +9,12 @@ const userModel = {};
const uu_columns = ['unit_level', 'elite_flg'];
userModel.getUserFromId = async (id) => {
const sql_text = 'SELECT TOP 1 id, discord_id, house_id, leadership FROM users WHERE id = ?;';
const sql_text = 'SELECT id, discord_id, house_id, leadership FROM users WHERE id = ? LIMIT 1;';
const data = await db.con.query(sql_text,[id]);
return data[0];
}
userModel.getUserFromDiscord = async (discordId) =>{
const sql_text = 'SELECT id, discord_id, house_id, leadership FROM users WHERE discord_id = ?;';
const sql_text = 'SELECT id, discord_id, house_id, leadership FROM users WHERE discord_id = ? LIMIT 1;';
const data = await db.con.query(sql_text, [discordId]);
return data[0];
}
......
......@@ -4,14 +4,9 @@ const Koa = require('koa');
const Router = require('@koa/router');
const router = new Router();
const authRouter = new Router();
const userModel = require('./model');
function checkUser(context){
if(!context.session.user_id){
context.throw(401, 'No User Logged')
}
}
router.post('/d-login', async (context, next) =>{
if(context.session.user_id && userModel.getUserFromId(context.session.user_id)){
context.throw(400, 'User is Already Logged In')
......@@ -34,8 +29,43 @@ router.post('/d-login', async (context, next) =>{
}
});
router.get('/units', async (context, next) => {
checkUser(context);
router.post('/discord-register', async(context, next) =>{
const body = context.request.body;
if(!body || !body.discordId){
context.throw(422, 'No Discord Id')
}
const discord_id = body.discordId;
if(context.user && !context.user.discord_id){
try{
await userModel.addDiscordIdToUser(context.user.id, discord_id);
context.status = 204;
}catch(error){
console.log(error);
context.throw(422, 'Invalid Discord Id')
}
}
let user = undefined;
try{
user = await userModel.getUserFromDiscord(discord_id);
}catch(error){
console.log(error);
context.throw(422, 'Invalid Discord Id')
}
if(!user){
try{
await userModel.createUserWithDiscord(discord_id);
context.status = 204;
}catch(error){
context.throw(422, 'Failed to create user with Discord Id')
}
}else{
context.throw(422, 'User already exists')
}
});
authRouter.get('/units', async (context, next) => {
try{
const data = await userModel.getUserUnits(context.session.user_id);
if(data.length===1 && data[0].id===null){
......@@ -49,8 +79,7 @@ router.get('/units', async (context, next) => {
}
});
router.get('/unit/:term', async (context, next) =>{
checkUser(context);
authRouter.get('/unit/:term', async (context, next) =>{
try{
const data = await userModel.getUserUnit(context.session.user_id, context.params.term)
context.response.body = data;
......@@ -61,8 +90,7 @@ router.get('/unit/:term', async (context, next) =>{
}
})
router.post('/unit', async (context, next) => {
checkUser(context);
authRouter.post('/unit', async (context, next) => {
try{
const body = context.request.body;
if(!body.unit_id){
......@@ -79,8 +107,7 @@ router.post('/unit', async (context, next) => {
}
})
router.put('/unit/:unit_id', async (context, next) =>{
checkUser(context);
authRouter.put('/unit/:unit_id', async (context, next) =>{
try{
const body = context.request.body;
if(!body){
......@@ -94,8 +121,7 @@ router.put('/unit/:unit_id', async (context, next) =>{
}
})
router.delete('/unit/:unit_id', async (context, next) =>{
checkUser(context);
authRouter.delete('/unit/:unit_id', async (context, next) =>{
try{
await userModel.deleteUserUnit(context.session.user_id, context.params.unit_id);
context.status = 204;
......@@ -105,39 +131,5 @@ router.delete('/unit/:unit_id', async (context, next) =>{
}
})
router.post('/discord-register', async(context, next) =>{
const body = context.request.body;
if(!body || !body.discordId){
context.throw(422, 'No Discord Id')
}
const discord_id = body.discordId;
if(context.user && !context.user.discord_id){
try{
await userModel.addDiscordIdToUser(context.user.id, discord_id);
context.status = 204;
}catch(error){
console.log(error);
context.throw(422, 'Invalid Discord Id')
}
}
let user = undefined;
try{
data = await userModel.getUserFromDiscord(discord_id);
}catch(error){
console.log(error);
context.throw(422, 'Invalid Discord Id')
}
if(!user){
try{
await userModel.createUserWithDiscord(discord_id);
context.status = 204;
}catch(error){
context.throw(422, 'Failed to create user with Discord Id')
}
}else{
context.throw(422, 'User already exists')
}
});
module.exports = router;
\ No newline at end of file
module.exports = [router, authRouter];
\ No newline at end of file
@font-face {
font-family: 'Font Awesome 5 Brands';
font-style: normal;
font-weight: 400;
font-display: block;
src: url("/fontawesome/fa-brands-400.woff2") format("woff2");
}
@font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 400;
font-display: block;
src: url("/fontawesome/fa-regular-400.woff2") format("woff2");
}
@font-face {
font-family: 'Font Awesome 5 Free';
font-style: normal;
font-weight: 900;
font-display: block;
src: url("/fontawesome/fa-solid-900.woff2") format("woff2");
}
@mixin icon($icon_code, $style){
&::before {
font-family: 'Font Awesome 5 Free';
content: $icon_code;
display: inline-block;
@if $style == "solid" {
font-weight: 900;
} @else if $style == "regular" {
font-weight: 400;
}
@content;
}
}
@keyframes fa-spin {
0% { transform: rotate( 0deg); }
100% { transform: rotate(360deg); }
}
@mixin spin_icon{
animation: fa-spin 2s linear infinite;
}
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<meta charset="utf8"/>
<link rel="stylesheet" href="./stylesheets/main.css"/>
<script src="sugar.js"></script>
<script>Sugar.extend()</script>
<script src="main.js" type="module"></script>
</head>
<body>
<nav-placeholder></nav-placeholder>
<script src="/navbar/navbar.js"></script>
<h1>STUFF IN HERE</h1>
</body>
</html>
import Sync from './sync'
class LoginPageController{
constructor(view){
this.view = view;
this.sync = new Sync();
this.view.addEventListener('login_attempt', this.login(event.detail.credentials));
this.view.addEventListener('register_attempt', this.login(event.detail.credentials))
}
async login(credentials){
try{
const user_data = await this.sync.login(credentials);
localStorage.setItem('username', user_data.user_name);
location.replace('/');
}catch(error){
console.log(error);
alert('Failed to login')
}
}
async login(credentials){
try{
const user_data = await this.sync.register(credentials);
localStorage.setItem('username', user_data.user_name);
location.replace('/');
}catch(error){
console.log(error);
alert('Failed to register')
}
}
}
export default LoginPageController;
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<meta charset="utf8"/>
<link rel="stylesheet" href="./stylesheets/main.css"/>
<script src="sugar.js"></script>
<script>Sugar.extend()</script>
<script src="/main.js" type="module"></script>
</head>
<body>
<nav-placeholder></nav-placeholder>
<script src="/navbar/navbar.js"></script>
<content-body>
<center-div>
<div class="tab">
<button class="tablinks active" onclick="changeTab(event, 'Login')">Login</button>
<button class="tablinks" onclick="changeTab(event, 'Register')">Register</button>
</div>
<!-- Tab content -->
<div id="Login" class="tabcontent" style="display: block;">
<login-form>
<input type="text" name="login" placeholder="Login"/>
<input type="password" name="password" placeholder="********"/>
<button id="login_button">Log In</button>
</login-form>
</div>