Issue
So I am creating a User Profile page. The users could login to their account, and then be directed to their unique profile. I’m intending the format to be:
Now my problem is that some of my universal public pages are in the ejs default "views" folder, including the universal login.ejs, registration.ejs, Dashboard pages etc. They are to be rendered when users want to access them
However, the user-unique pages, such as each user’s profile page, are under different directories, named by their username. When users successfully authenticate, these pages should also be rendered when the users want to access them. However, when I run the server in local host, the console told me that those pages have to be under the views folder
Error: Failed to lookup view "./username/profile" in views directory
So I’m assuming that I have to put all the users’ files inside the views directory in order for them to be shown, am I right? Is there any solutions to avoid this?
The initialising codes are below. I’m using MongoDB
const express = require("express");
const app = express();
const BodyParser = require("body-parser");
const ejs = require("ejs");
const mongoose = require("mongoose");
app.use(express.static("public"));
app.set("view engine", "ejs");
app.use(BodyParser.urlencoded({extended: true}));
// using Mongoose to create a User Database, that stores user id and password
userSchema = {username: String, password: String}
User = new mongoose.model("User", userSchema);
And below are the actual function that redirects users to their profile.ejs
app.post("/login", function(req, res)
{
var username = req.body.username; // these are just the user entry fields in login.ejs
var password = req.body.password;
User.findOne({username: username}, function(err, UserFound)
{
if (UserFound)
{
if (UserFound.password === password)
{
user_dir = "./" + username + "/profile"
res.render(user_dir) // here I want to render the users' unique profile page
}
else
{console.log("password incorrect")}
}
else
{console.log("username incorrect")}
})
});
Solution
If you render the file manually using the ejs
lib itself, you get more fine-grained control over things like directory paths, etc.
For example, your login endpoint could look like this:
app.post("/login", function(req, res) {
const {username, password} = req.body
User.findOne({username}, async function(err, UserFound) {
if (UserFound && UserFound.password === password) {
const profile = `./${username}/profile.ejs`
const html = await ejs.renderFile(profile /*{data goes here if necessary}*/)
res.send(html)
} else {
console.log("username or password incorrect") // It is conventional to combine username / password incorrect warning to obfuscate this info from a potential attacker
}
})
});
Completely unrelated aside: it looks like you’re comparing the passwords without hashing them first – are you storing your passwords in plaintext? If the answer is either "yes" or "I don’t know", and you intend to use this app in a production setting, please look into password hashing