Newer
Older
goodnight / src / app.ts
import { json, urlencoded } from "body-parser";
import * as express from "express";
import * as session from "express-session";
import { join } from "path";

// WEBROOT has to end with "/". It should only be used to build absolute URLs.
const { PORT = 8080, WEBROOT = "/"} = process.env;

const loginHandler = (req:express.Request, res:express.Response, next:express.NextFunction) => {
    // if the user is already logged in then, redirect to content.
    if(req.session && req.session.username)
    {
        return res.redirect(WEBROOT + "beyond.html");
    }
    // if the user is not logged in yet, then continue the route (to serve the login page)
    else {
        next();
    }
};

// logout route ends the session (=perform logout)
function performLogout(req:express.Request, res:express.Response, next:express.NextFunction)
{
    if(req.session){
        req.session.destroy(err => {
            if(err){
                return next(err);
            }
            else
            {
                // TODO remove session from persistence.
                // TODO redirect to a page, that triggers a logout for all connected apps, to delete their sessions too.
                return res.redirect(WEBROOT);
            }
        });
    }
}

function performLogin(req:express.Request, res:express.Response)
{
    // verify credentials.
    // const isAuthenticated = usermanager.verifyCredential(req.body.username, req.body.password);
    const isAuthenticated = req.body.username === "peter" && req.body.password === "f";
    // fill session.
    if(isAuthenticated)
    {
        req.session.username = req.body.username;
        // TODO store session?
        // TOTO redirect to where they came from or to profile page (or continue route?)
        res.redirect(WEBROOT + "index.html");
    }
    else
    {
        res.redirect(WEBROOT + "login.html");
    }
}

const app = express();
app.disable("x-powered-by");

// For all routes: create/retreive session,
// so that it is accessible during later processing of requests.
// TODO persist session, so that it is still available after restart of the service.
app.use(session({
    resave: true,
    saveUninitialized: false,
    secret: "work hard",
}));

app.set("views", join(".","views"));
app.set("view engine", "pug");

// middleware for decoding post requests
app.use(urlencoded({extended:false}));
app.use(json());

app.get("/login.html", (req, res) => {
    res.render("login.pug");
});

app.post("/login", performLogin);

app.use("/style", express.static(join(".", "style")));

// ===========  SECURE DOMAIN =======================
// every endpoint after this should not be reachable without a username in the session.
app.use((req,res,next)=> {
    if(req.session && req.session.username)
    {
        next();
    }
    else
    {
        res.redirect("login.html");
    }
});

app.post("/logout", performLogout);

app.post("/logbedtime", (req, res) => {
    const username = req.session.username as string;
    const dateTimeString = req.body.dateTime as string;
    console.log(`${username}: bed time at ${dateTimeString}`);
    res.sendStatus(201);
});

app.post("/logwakeuptime", (req, res) => {
    const username = req.session.username as string;
    const dateTimeString = req.body.dateTime as string;
    console.log(`${username}: wake up at ${dateTimeString}`);
    res.sendStatus(201);
});

app.get("/index.html", (req, res) => {
    res.render("index.pug");
});

app.use("/js", express.static(join(".", "dist", "frontend")));

app.get("/", (req,res) => {
    res.redirect("/index.html");
});

app.listen(PORT, () => console.log(`Server started on port ${PORT}...`));