Reorganised some routing logic. Added separate views for SPAs and reorganised static folders to be globally accessible, so that the separate views can access the right folder. Language can be permanently changed for account.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,3 +1,5 @@
|
||||
node_modules
|
||||
dist
|
||||
static/semantic
|
||||
static/semantic
|
||||
static/frontend
|
||||
static/game
|
||||
2
.idea/modules.xml
generated
2
.idea/modules.xml
generated
@@ -3,7 +3,7 @@
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/kadi_backend.iml" filepath="$PROJECT_DIR$/.idea/kadi_backend.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kadi_frontend/.idea/kniffel.iml" filepath="$PROJECT_DIR$/../kadi_frontend/.idea/kniffel.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kadi_frontend/.idea/kadi_frontendä.iml" filepath="$PROJECT_DIR$/../kadi_frontend/.idea/kadi_frontendä.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kadi_game/.idea/kadi_game.iml" filepath="$PROJECT_DIR$/../kadi_game/.idea/kadi_game.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../../../.idea/www.iml" filepath="$PROJECT_DIR$/../../../.idea/www.iml" />
|
||||
</modules>
|
||||
|
||||
4815
package-lock.json
generated
4815
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -20,7 +20,9 @@
|
||||
"express-session": "^1.17.1",
|
||||
"mongoose": "^5.9.11",
|
||||
"passport": "^0.4.1",
|
||||
"passport-local": "^1.0.0"
|
||||
"passport-local": "^1.0.0",
|
||||
"diff": ">=3.5.0",
|
||||
"lodash.template": ">=4.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bcrypt": "^3.0.0",
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import passport from "passport";
|
||||
import DbUser, {IDbUser, IDbUserDoc} from "../models/dbUser";
|
||||
import {IDbUserDoc} from "../models/dbUser";
|
||||
import {RequestHandler} from "express";
|
||||
import SavedGame from "../models/savedGame";
|
||||
|
||||
export const whoAmI: RequestHandler = async (req, res) => {
|
||||
if (req.isAuthenticated()) {
|
||||
const user = req.user as IDbUserDoc;
|
||||
res.json({loggedIn: true, username: user.username});
|
||||
res.json({loggedIn: true, username: user.username, lang: user.lang});
|
||||
}
|
||||
else {
|
||||
res.json({loggedIn: false});
|
||||
}
|
||||
};
|
||||
|
||||
export const changeLang: RequestHandler = async (req, res) => {
|
||||
const user = (req.user as IDbUserDoc);
|
||||
user.changeLang(req.body.lang);
|
||||
};
|
||||
@@ -7,6 +7,7 @@ export const listGames: RequestHandler = async (req, res) => {
|
||||
const user = (req.user as IDbUserDoc);
|
||||
const dbUser = await DbUser.findById(user._id, {"savedGames.game": 1, "savedGames.createdAt": 1});
|
||||
if (dbUser) {
|
||||
console.log(dbUser.savedGames);
|
||||
res.json({games: dbUser.savedGames});
|
||||
}
|
||||
else {
|
||||
@@ -16,25 +17,5 @@ export const listGames: RequestHandler = async (req, res) => {
|
||||
|
||||
export const saveGame: RequestHandler = async (req, res) => {
|
||||
const user = (req.user as IDbUserDoc);
|
||||
const handleError = (err: string) => {
|
||||
res.send({error: true, message: err});
|
||||
};
|
||||
DbUser.findById(user, (err, user) => {
|
||||
if (err) {
|
||||
handleError(err);
|
||||
}
|
||||
else if (user) {
|
||||
const newGame = new SavedGame();
|
||||
newGame.game = req.body;
|
||||
user.savedGames.push(newGame);
|
||||
user.save((err) => {
|
||||
if (err) {
|
||||
return handleError(err);
|
||||
}
|
||||
else {
|
||||
res.send("Thanks for submitting your game, " + user.username + "!");
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
await user.addGame(req.body);
|
||||
};
|
||||
5
src/enums.ts
Normal file
5
src/enums.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export enum SupportedLang {
|
||||
gb = "gb",
|
||||
de = "de",
|
||||
it = "it",
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import Settings from "./server-config.json";
|
||||
import flash from "express-flash";
|
||||
import passport from "passport";
|
||||
import session from "express-session";
|
||||
import * as path from "path";
|
||||
import MainRouter from "./routers/mainRouter";
|
||||
|
||||
// MongoDB Setup
|
||||
@@ -23,6 +22,7 @@ const app = express();
|
||||
app.use(express.json());
|
||||
app.set("port", process.env.PORT || 3000);
|
||||
app.set("view-engine", "ejs");
|
||||
app.set("views", "views");
|
||||
app.use(express.urlencoded({ extended: false}));
|
||||
app.use(flash());
|
||||
app.use(session({
|
||||
@@ -39,7 +39,11 @@ app.locals = {
|
||||
initialisePassport();
|
||||
app.use(passport.initialize());
|
||||
app.use(passport.session());
|
||||
|
||||
app.use((req, res, next) => {
|
||||
console.log(req.originalUrl);
|
||||
next();
|
||||
});
|
||||
app.use(Settings.serverRoot + "/static", express.static("static"));
|
||||
app.use(Settings.serverRoot, MainRouter);
|
||||
|
||||
const server = app.listen(app.get("port"), () => {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import mongoose from "mongoose";
|
||||
import Player, {IPlayer, IPlayerDoc, PlayerSchema} from "./player";
|
||||
import {AccountStats, AccountStatsSchema, IAccountStats, IAccountStatsDoc} from "./stats";
|
||||
import {ISavedGame, ISavedGameDoc, SavedGameSchema} from "./savedGame";
|
||||
import SavedGame, {ISavedGame, ISavedGameDoc, SavedGameSchema} from "./savedGame";
|
||||
import bcrypt from "bcrypt";
|
||||
import {SupportedLang} from "../enums";
|
||||
|
||||
export class CredentialsTakenError extends Error {
|
||||
public emailExists: boolean;
|
||||
@@ -19,6 +20,7 @@ export interface IDbUser {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
lang?: SupportedLang;
|
||||
friends?: IDbUser[];
|
||||
player?: IPlayer;
|
||||
guests?: IPlayer[];
|
||||
@@ -30,11 +32,14 @@ export interface IDbUserDoc extends mongoose.Document {
|
||||
username: string;
|
||||
email: string;
|
||||
password: string;
|
||||
lang: SupportedLang;
|
||||
friends: IDbUserDoc[];
|
||||
player: IPlayerDoc;
|
||||
guests: IPlayerDoc[];
|
||||
accountStats: IAccountStatsDoc;
|
||||
savedGames: ISavedGameDoc[];
|
||||
changeLang(lang: SupportedLang): void;
|
||||
addGame(game: any): Promise<string | null>;
|
||||
}
|
||||
|
||||
export interface IDbUserModel extends mongoose.Model<IDbUserDoc> {
|
||||
@@ -49,11 +54,12 @@ export const DbUserSchema = new mongoose.Schema({
|
||||
username: { type: String, required: true, unique: true },
|
||||
email: { type: String, required: true, unique: true },
|
||||
password: { type: String, required: true },
|
||||
friends: {type: [mongoose.Schema.Types.ObjectId], required: true, default: []},
|
||||
lang: { type: String, required: true },
|
||||
friends: {type: [mongoose.Schema.Types.ObjectId], default: []},
|
||||
player: {type: PlayerSchema, required: true, unique: true},
|
||||
guests: {type: [PlayerSchema], required: true, default: []},
|
||||
accountStats: {type: AccountStatsSchema, required: true, default: () => ({}) },
|
||||
savedGames: {type: [SavedGameSchema], required: true, default: []},
|
||||
guests: {type: [PlayerSchema], default: []},
|
||||
accountStats: {type: AccountStatsSchema, default: () => ({}) },
|
||||
savedGames: {type: [SavedGameSchema], default: []},
|
||||
});
|
||||
|
||||
DbUserSchema.statics.findByEmail = async function (emailQuery: string) {
|
||||
@@ -63,11 +69,12 @@ DbUserSchema.statics.findByEmail = async function (emailQuery: string) {
|
||||
DbUserSchema.statics.addNewUser = async function (user: IDbUser) {
|
||||
const player = new Player( { nick: user.username });
|
||||
return this.create({
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
password: user.password,
|
||||
player
|
||||
});
|
||||
username: user.username,
|
||||
email: user.email,
|
||||
password: user.password,
|
||||
lang: SupportedLang.gb,
|
||||
player
|
||||
});
|
||||
};
|
||||
|
||||
DbUserSchema.statics.registerUser = async function (username: string, email: string, password: string) {
|
||||
@@ -90,5 +97,19 @@ DbUserSchema.statics.userWithUsernameExists = async function (username: string)
|
||||
return this.exists({username});
|
||||
};
|
||||
|
||||
DbUserSchema.methods.addGame = function (game: any): void {
|
||||
const newGame = new SavedGame();
|
||||
newGame.game = game;
|
||||
DbUser.updateOne(this, {$push: {savedGames: newGame}}, (err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
DbUserSchema.methods.changeLang = function (lang: SupportedLang): void {
|
||||
if (lang in SupportedLang) {
|
||||
DbUser.updateOne(this, {lang: lang});
|
||||
}
|
||||
};
|
||||
|
||||
const DbUser = mongoose.model<IDbUserDoc, IDbUserModel>("DbUser", DbUserSchema);
|
||||
export default DbUser;
|
||||
@@ -45,7 +45,7 @@ export const initialisePassport = () => {
|
||||
done(null, user._id)
|
||||
});
|
||||
passport.deserializeUser(async (id: string, done) => {
|
||||
const user: IDbUserDoc | null = await DbUser.findById(id);
|
||||
const user: IDbUserDoc | null = await DbUser.findById(id, {username: 1, password: 1, lang: 1, email: 1});
|
||||
done(null, user);
|
||||
});
|
||||
};
|
||||
@@ -1,11 +1,12 @@
|
||||
import express from "express";
|
||||
import {requireAuthenticated, requireNotAuthenticated} from "../passport-config";
|
||||
import {requireAuthenticated} from "../passport-config";
|
||||
import * as stats from "../controllers/statsController";
|
||||
import * as dbUser from "../controllers/dbUserController"
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.get("/user", dbUser.whoAmI);
|
||||
router.post("/changeLang", requireAuthenticated, dbUser.changeLang);
|
||||
router.get("/games", requireAuthenticated, stats.listGames);
|
||||
router.post("/savegame", requireAuthenticated, stats.saveGame);
|
||||
|
||||
|
||||
@@ -1,23 +1,25 @@
|
||||
import express from "express";
|
||||
import {requireAuthenticated, requireNotAuthenticated} from "../passport-config";
|
||||
import {requireAuthenticated} from "../passport-config";
|
||||
import routers from "./routers";
|
||||
import {IDbUser} from "../models/dbUser";
|
||||
import * as path from "path";
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
router.use("/account", routers.signup);
|
||||
router.use("/api", routers.api);
|
||||
router.use("/game/static", express.static(path.join(__dirname, "../game/static")));
|
||||
router.use("/static", express.static(path.join(__dirname, "../frontend/static")));
|
||||
router.use("/static", express.static("static"));
|
||||
|
||||
// General Endpoints
|
||||
router.get("/game", requireAuthenticated, (req, res) => {
|
||||
res.sendFile(path.join(__dirname + "/../game/index.html"));
|
||||
res.render("gameIndex.ejs", {
|
||||
username: (req.user as IDbUser).username,
|
||||
rootUrl: req.app.locals.rootUrl
|
||||
});
|
||||
});
|
||||
router.get("", requireAuthenticated, (req, res) => {
|
||||
res.sendFile(path.join(__dirname + "/../frontend/index.html"), {username: (req.user as IDbUser).username});
|
||||
|
||||
router.get("/**", requireAuthenticated, (req, res) => {
|
||||
res.render("frontendIndex.ejs", {
|
||||
username: (req.user as IDbUser).username,
|
||||
rootUrl: req.app.locals.rootUrl
|
||||
});
|
||||
});
|
||||
|
||||
export default router;
|
||||
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
22
views/frontendIndex.ejs
Executable file
22
views/frontendIndex.ejs
Executable file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href=<%= rootUrl + "/static/favicon.ico" %> />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Score dice games with K A D I"
|
||||
/>
|
||||
<link rel="manifest" href=<%= rootUrl + "/static/frontend/manifest.json" %> />
|
||||
<title>K A D I - Digital Dice</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<script src=<%= rootUrl + "/static/frontend/bundle.js" %>></script>
|
||||
</body>
|
||||
</html>
|
||||
22
views/gameIndex.ejs
Executable file
22
views/gameIndex.ejs
Executable file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href=<%= rootUrl + "/static/favicon.ico" %> />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Score dice games with K A D I"
|
||||
/>
|
||||
<link rel="manifest" href=<%= rootUrl + "/static/game/manifest.json" %> />
|
||||
<title>K A D I - Digital Dice</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<script src=<%= rootUrl + "/static/game/bundle.js" %>></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="<%= rootUrl %>/static/favicon.ico" />
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="icon" href="<%= rootUrl %>/static/favicon.ico" />
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
||||
|
||||
Reference in New Issue
Block a user