feat: Implement the /user/me endpoint
This commit is contained in:
@@ -4,27 +4,39 @@ import * as bodyparser from "body-parser";
|
||||
import { authRoute } from "../security/token";
|
||||
|
||||
const userRouter = express.Router();
|
||||
userRouter.use(bodyparser.json());
|
||||
userRouter.use(authRoute);
|
||||
userRouter.use(bodyparser.json());
|
||||
|
||||
// Return the user object if the user is still authenticated
|
||||
userRouter.get("/get", async (req, res) => {
|
||||
console.log("STUB: /user/get");
|
||||
userRouter.get("/me", async (req, res) => {
|
||||
//@ts-ignore
|
||||
const { db, token } = req;
|
||||
|
||||
// TODO: Stub
|
||||
res.send({
|
||||
error: "0",
|
||||
data: {
|
||||
test: 0,
|
||||
},
|
||||
});
|
||||
const session = await db.collection("sessions").findOne({ token, });
|
||||
if (session !== null) {
|
||||
const user = await db.collection("users").findOne({ username: session.username });
|
||||
|
||||
// TODO: Strip salt, hash, _id
|
||||
res.send({
|
||||
error: "0",
|
||||
data: Object.assign({}, user, {
|
||||
sessionToken: token,
|
||||
}),
|
||||
});
|
||||
} else {
|
||||
res.send({
|
||||
error: "404",
|
||||
data: {},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Removes the user's session
|
||||
userRouter.get("/logout", async (req, res) => {
|
||||
console.log("STUB: /user/logout");
|
||||
// Try to remove the session
|
||||
//@ts-ignore
|
||||
await req.db.collections("sessions").findOneAndDelete({ session: req.get("Token") });
|
||||
|
||||
// TODO: Stub
|
||||
res.send({
|
||||
error: "0",
|
||||
data: {},
|
||||
|
||||
@@ -12,88 +12,94 @@ import LevelRouter from "./api/level";
|
||||
const baseRouter = express.Router();
|
||||
const authRouter = express.Router();
|
||||
|
||||
authRouter.use(bodyparser.json());
|
||||
authRouter.use(async (req, res, next) => {
|
||||
const token = req.get("Token");
|
||||
if (token) {
|
||||
// Check if were authenticated
|
||||
const auth = await isAuthenticated(token);
|
||||
if (auth)
|
||||
next();
|
||||
else
|
||||
res.send({
|
||||
error: "401",
|
||||
data: {},
|
||||
});
|
||||
} else {
|
||||
res.send({
|
||||
error: "401",
|
||||
data: {},
|
||||
});
|
||||
import { MongoClient } from "mongodb";
|
||||
const assert = require('assert');
|
||||
|
||||
(async function() {
|
||||
// Connection URL
|
||||
const url = 'mongodb://128.1.0.2:27017/myproject';
|
||||
// Database Name
|
||||
const dbName = 'myproject';
|
||||
let client: MongoClient;
|
||||
|
||||
try {
|
||||
// Use connect method to connect to the Server
|
||||
client = await MongoClient.connect(url);
|
||||
console.log("Connected to MongoDB");
|
||||
} catch (err) {
|
||||
console.log(err.stack);
|
||||
assert(1, 2);
|
||||
}
|
||||
});
|
||||
|
||||
const app = express();
|
||||
app.use(bodyparser.json());
|
||||
// app.use((req, res, next) => {
|
||||
// // TODO: Change this to our domain
|
||||
// res.append("Access-Control-Allow-Origin", "*");
|
||||
// res.append("Access-Control-Allow-Headers", "Content-Type,Token");
|
||||
// next();
|
||||
// });
|
||||
app.options("*", cors());
|
||||
const db = client.db(dbName);
|
||||
console.log("Connected to the database");
|
||||
|
||||
app.use("/api/level", LevelRouter);
|
||||
app.use("/api/class", ClassRouter);
|
||||
app.use("/api/user", UserRouter);
|
||||
app.get("/api/levels", async (req, res) => {
|
||||
const levels = [{
|
||||
name: "Der Bauer auf dem Feld",
|
||||
desc: "So fängt alles an: Du bist ein einfacher Bauer und musst dich die Karriereleiter mit deinen freshen Latein-Skills hinaufarbeiten",
|
||||
level: 1,
|
||||
done: true,
|
||||
}, {
|
||||
name: "???",
|
||||
desc: "Warum schreibe ich überhaupt was?dsd dddddddddddddddddddddd",
|
||||
level: 2,
|
||||
done: false,
|
||||
}];
|
||||
|
||||
res.send({
|
||||
error: "0",
|
||||
data: {
|
||||
levels,
|
||||
},
|
||||
const app = express();
|
||||
app.use(bodyparser.json());
|
||||
app.options("*", cors());
|
||||
|
||||
app.use((req, res, next) => {
|
||||
// Every route should have access to the database so that
|
||||
// we can easily make calls to it
|
||||
// @ts-ignore
|
||||
req.db = db;
|
||||
next();
|
||||
});
|
||||
});
|
||||
app.get("/api/health", (req, res) => {
|
||||
res.send({
|
||||
error: "0",
|
||||
data: {
|
||||
msg: "lol",
|
||||
},
|
||||
});
|
||||
});
|
||||
app.post("/api/login", async (req, res) => {
|
||||
const { body } = req;
|
||||
app.use("/api/level", LevelRouter);
|
||||
app.use("/api/class", ClassRouter);
|
||||
app.use("/api/user", UserRouter);
|
||||
app.get("/api/levels", async (req, res) => {
|
||||
const levels = [{
|
||||
name: "Der Bauer auf dem Feld",
|
||||
desc: "So fängt alles an: Du bist ein einfacher Bauer und musst dich die Karriereleiter mit deinen freshen Latein-Skills hinaufarbeiten",
|
||||
level: 1,
|
||||
done: true,
|
||||
}, {
|
||||
name: "???",
|
||||
desc: "Warum schreibe ich überhaupt was?dsd dddddddddddddddddddddd",
|
||||
level: 2,
|
||||
done: false,
|
||||
}];
|
||||
|
||||
console.log("Stub: /login");
|
||||
|
||||
// Check if all arguments were sent
|
||||
if (!body || !("username" in body) || !("password" in body)) {
|
||||
res.send({
|
||||
error: "400",
|
||||
error: "0",
|
||||
data: {
|
||||
msg: "Username or password not specified",
|
||||
levels,
|
||||
},
|
||||
});
|
||||
});
|
||||
app.get("/api/health", (req, res) => {
|
||||
res.send({
|
||||
error: "0",
|
||||
data: {
|
||||
msg: "lol",
|
||||
},
|
||||
});
|
||||
});
|
||||
app.post("/api/login", async (req, res) => {
|
||||
// Check if all arguments were sent
|
||||
const { body } = req;
|
||||
if (!body || !("username" in body) || !("password" in body)) {
|
||||
res.send({
|
||||
error: "400",
|
||||
data: {
|
||||
msg: "Username or password not specified",
|
||||
},
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to log the user in
|
||||
const userData = await performLogin(body.username, body.password)
|
||||
.catch((err) => {
|
||||
// Try to log the user in
|
||||
try {
|
||||
const userData = await performLogin(body.username, body.password, db);
|
||||
res.send({
|
||||
error: "0",
|
||||
data: userData,
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
console.log("Could not resolve login promise!", err);
|
||||
|
||||
// If anything was wrong, just tell the client
|
||||
@@ -103,13 +109,10 @@ app.post("/api/login", async (req, res) => {
|
||||
msg: "Username or password is wrong",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
res.send({
|
||||
error: "0",
|
||||
data: userData,
|
||||
}
|
||||
});
|
||||
});
|
||||
app.listen(8080, () => {
|
||||
console.log("Starting on port 8080");
|
||||
});
|
||||
const server = app.listen(8080, () => {
|
||||
console.log("Starting on port 8080");
|
||||
});
|
||||
})();
|
||||
|
||||
|
||||
@@ -1,30 +1,45 @@
|
||||
import { pbkdf2Sync } from "crypto";
|
||||
import { pbkdf2Sync, randomBytes } from "crypto";
|
||||
|
||||
import { Db } from "mongodb";
|
||||
|
||||
import { IUser } from "shared/user";
|
||||
|
||||
export function isAuthenticated(token: string): Promise<boolean> {
|
||||
return new Promise((res, rej) => {
|
||||
// TODO
|
||||
res(true);
|
||||
});
|
||||
export async function isAuthenticated(token: string, db: Db): Promise<boolean> {
|
||||
// See if we can find a session with that token
|
||||
const session = await db.collection("sessions").findOne({ token, });
|
||||
return session !== null;
|
||||
}
|
||||
|
||||
export function performLogin(username: string, password: string): Promise<IUser | {}> {
|
||||
return new Promise((res, rej) => {
|
||||
// Hash the password
|
||||
// TODO: Fetch the salt
|
||||
const salt = "";
|
||||
const hash = pbkdf2Sync(password, salt, 50000, 512, "sha512").toString("hex");
|
||||
|
||||
// TODO: Look up the user, compare hashes and send the returned user
|
||||
res({
|
||||
username: "Polynom",
|
||||
uid: "1",
|
||||
showWelcome: true,
|
||||
classId: "test",
|
||||
score: 4,
|
||||
|
||||
sessionToken: "abc123",
|
||||
});
|
||||
export async function performLogin(username: string, password: string, db: Db): Promise<IUser> {
|
||||
const user = await db.collection("users").findOne({
|
||||
username,
|
||||
});
|
||||
|
||||
// Hash the password
|
||||
const hash = pbkdf2Sync(password, user.salt, 50000, 512, "sha512").toString("hex");
|
||||
if (hash === user.hash) {
|
||||
// Create a session
|
||||
const sessionToken = randomBytes(20).toString("hex");
|
||||
|
||||
// Store the token
|
||||
await db.collection("sessions").insertOne({
|
||||
username: user.username,
|
||||
token: sessionToken,
|
||||
});
|
||||
|
||||
return {
|
||||
username: user.username,
|
||||
uid: user.uid,
|
||||
showWelcome: user.showWelcome,
|
||||
//@ts-ignore
|
||||
classId: user.classId,
|
||||
|
||||
// TODO: Implement
|
||||
score: 4,
|
||||
sessionToken,
|
||||
};
|
||||
} else {
|
||||
// It does not matter what we throw
|
||||
throw new Error("LOL");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,18 +6,26 @@ export async function authRoute(req: Request, res: Response, next: () => void) {
|
||||
const token = req.get("Token");
|
||||
if (token) {
|
||||
// Check if were authenticated
|
||||
const auth = await isAuthenticated(token);
|
||||
if (auth)
|
||||
//@ts-ignore
|
||||
const auth = await isAuthenticated(token, req.db);
|
||||
if (auth) {
|
||||
//@ts-ignore
|
||||
req.token = token;
|
||||
next();
|
||||
else
|
||||
} else {
|
||||
res.send({
|
||||
error: "401",
|
||||
data: {},
|
||||
error: "403",
|
||||
data: {
|
||||
msg: "Session Token not found!",
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
res.send({
|
||||
error: "401",
|
||||
data: {},
|
||||
error: "403",
|
||||
data: {
|
||||
msg: "No Session Token specified",
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user