sunrise-cms/routes/login.ts

145 lines
4.3 KiB
TypeScript

import { Router } from "express";
import * as configFunctions from "../helpers/functions.config.js";
import * as authenticationFunctions from "../helpers/functions.authentication.js";
import { useTestDatabases } from "../data/databasePaths.js";
import { getApiKey } from "../helpers/functions.api.js";
import type * as recordTypes from "../types/recordTypes";
export const router = Router();
const safeRedirects = new Set([
"/admin/fees",
"/admin/occupancytypes",
"/admin/tables",
"/lotoccupancies",
"/lotoccupancies/new",
"/lots",
"/lots/new",
"/maps",
"/maps/new",
"/workorders",
"/workorders/new",
"/reports"
]);
const getSafeRedirectURL = (possibleRedirectURL = "") => {
const urlPrefix = configFunctions.getProperty("reverseProxy.urlPrefix");
if (typeof possibleRedirectURL === "string") {
const urlToCheck = (
possibleRedirectURL.startsWith(urlPrefix)
? possibleRedirectURL.slice(urlPrefix.length)
: possibleRedirectURL
).toLowerCase();
if (
safeRedirects.has(urlToCheck) ||
/^(\/maps\/)\d+(\/edit)?$/.test(urlToCheck) ||
/^(\/lots\/)\d+(\/edit)?$/.test(urlToCheck) ||
/^(\/lotoccupancies\/)\d+(\/edit)?$/.test(urlToCheck) ||
/^(\/workorders\/)\d+(\/edit)?$/.test(urlToCheck)
) {
return urlPrefix + urlToCheck;
}
}
return urlPrefix + "/dashboard";
};
router
.route("/")
.get((request, response) => {
const sessionCookieName =
configFunctions.getProperty("session.cookieName");
if (request.session.user && request.cookies[sessionCookieName]) {
const redirectURL = getSafeRedirectURL(
(request.query.redirect || "") as string
);
response.redirect(redirectURL);
} else {
response.render("login", {
userName: "",
message: "",
redirect: request.query.redirect,
useTestDatabases
});
}
})
.post(async (request, response) => {
const userName = request.body.userName as string;
const passwordPlain = request.body.password as string;
const unsafeRedirectURL = request.body.redirect;
const redirectURL = getSafeRedirectURL(
typeof unsafeRedirectURL === "string" ? unsafeRedirectURL : ""
);
const isAuthenticated = await authenticationFunctions.authenticate(
userName,
passwordPlain
);
let userObject: recordTypes.User;
if (isAuthenticated) {
const userNameLowerCase = userName.toLowerCase();
const canLogin = configFunctions
.getProperty("users.canLogin")
.some((currentUserName) => {
return userNameLowerCase === currentUserName.toLowerCase();
});
if (canLogin) {
const canUpdate = configFunctions
.getProperty("users.canUpdate")
.some((currentUserName) => {
return (
userNameLowerCase === currentUserName.toLowerCase()
);
});
const isAdmin = configFunctions
.getProperty("users.isAdmin")
.some((currentUserName) => {
return (
userNameLowerCase === currentUserName.toLowerCase()
);
});
const apiKey = await getApiKey(userNameLowerCase);
userObject = {
userName: userNameLowerCase,
userProperties: {
canUpdate,
isAdmin,
apiKey
}
};
}
}
if (isAuthenticated && userObject) {
request.session.user = userObject;
response.redirect(redirectURL);
} else {
response.render("login", {
userName,
message: "Login Failed",
redirect: redirectURL,
useTestDatabases
});
}
});
export default router;