So now that we've gone through all of the various different types of increasing security for our users
we've looked at encryption, hashing, salting, using OAuth and other services to login our users.
There's just one thing that our website needs, some actual functionality. Because at the moment when you
log into the service, it takes you to a static page that just shows one secret which is the one that
we've hardcoded on our secrets.
ejs page.
Now that's probably not what we want right?
Instead we'd want the user to be able to submit a secret and see all of the secrets that other users
have submitted.
So we need to fix this.
So let's go into our app.js and firstly set up a get route for going to /submit.
So let's put a app.get for the /submit route and here we should check to see if the
user is logged in i.e. see if req.isAuthenticated is true.
And if they are then they should be taken to the submit page over here and we should render it so that
the user can submit a secret.
So I'm simply going to copy this and paste it inside here and change the render to submit.
Now it's the same if they were not logged in we would also redirect them to log in.
So now if we check out what it looks like when we go to submit a secret and log in as our local user
with their password 123456,
at the moment it still redirects to the secrets page after we log in.
But if we click on submit a secret now because we have our login session saved, then it takes us to
the submit page.
So here we're supposed to write a secret,
I don't know,
"My favorite color is blue."
It's not much of a secret but here we go.
And always click submit it will post to the /submit route where we can pick up the secret
that the user typed in, save that into their account and then take them back to the secrets page.
So the next thing we should do is to set up that app.post route.
And the reason why the submit page is making an app.post to this route is because we have a submit
button here that completes the form, makes a post request to the /submit route.
And now we're going to handle that right here.
So inside here is where we're going to save the secret that the user typed in.
So let's create a new concconst ept called submittedSecret
and let's set this to equal req.body.secret because when we look in here the input that
has a type of text for the users secret has the name of secret.
So that means we can happen to it when this form gets submitted through req.
.body.secret. And that is what we're going to save into this new constant right here.
So the next thing we want to do is to find the current user in our database and then save the secret
into their file.
So how do we know who the current user is?
Well, passport very handily actually saves the users details because when we initiate a new login session
it will say that users details into the request variable.
So that means if I go ahead and console.log req.user, I'll actually be able to see what's
saved for my current session.
So let's hit save and let's go back to our home page,
let's log in our user through our local strategy, hit login and we now get to the secrets page.
So if I go ahead and click on submit a secret and type the same thing as before, click submit,
now that should trigger my console log and you can see it now posts everything that we have saved about
this current user.
We can access their id and also their username,
so basically everything that exists inside here other than their salt and hash.
So that means we can now find this user using their id in the database and save the secret that they
created to this document.
But in order to do that, we first have to amend our schema.
So in addition to everything else that's inside the schema, I'm going to add one more field and this
is going to be their secret.
So it's also going to be a string.
And now when the user makes that post request, I'm going to find the user using that req.user.
because that refers to the id that we have for them in our database.id
And then I'm going to add that secret that they submitted to that secret field that I created in the
schema.
So let's go ahead and tap into the user model.
I'm going to findById where the id is req.user.id. And once that's completed, we might
either get an error or we might get a foundUser if they do indeed exist. And if there were any errors
we're simply going to console log it
but if there were no errors and if the foundUser did indeed exist then we're going to set the found
user's secret field to equal the submittedSecret.
And then we're going to save this found user with their newly updated secret.
And once that save has completed, then we can res.redirect them to the secrets page so that they can
see their own secret alongside everybody else's.
So let's close off these lines of code and let's hit save and let's go back to our home page, login
our user so remember because every time our server restarts our sessions and cookies gets wiped out.
So now we're ready to submit a secret.
And I'm going to add the same secret here to that user which is the local mongoose user.
And now if I go into my Robo 3T, update my database, I should be able to see a secret field that's
filled in for this user.
So now that we've added in the secret, it's time to be able to render it on the secret page
right?
I want to be able to find all the users that have a secret posted and be able to render them on the secrets
page.
So that way it's no longer just a static page with only a single secret.
So to do that we have to update the app.get for our secrets route.
We're no longer just going to check to see if they're authenticated or if they're not, redirect them
to login, because this is no longer going to be a privileged page.
Anybody with a logged in or not logged in should be able to see the secrets that have been submitted
anonymously.
So we don't need to check to see if they're authenticated but instead we're going to trawl through our
database and find all of the secret that have been submitted on the database.
So to do that we're going to use our model of users and we're going to use find and we're going to look
through this collection and find all the places where the field secret actually has a value.
Now how do we do this? If we were to search Google for say MongoDB field not null i.e. it contains some
data, then we can see that other people already asked about this. And there's several ways that you can
do this. You can either do it through checking whether if it exists
so this means that there is a field called IMAGE URL but you can also check to see that it's not
equal to null.
So it means it actually has a value so in this case there actually is an image URL in this collection.
So this is what we want.
So in our case we're going to check through our collection of users and look through the secret field
and then let's add in this not equal to null part that's enclosed in curly braces into this find condition.
So we're going to put it inside here.
So we're going to make sure that we open up a set of curly braces.
So notice how this is one set of curly braces
and this defines the condition that we're going to look through our database with.
And then this is another set of curly braces which is going to be the condition for actually which documents
to pick out based on the secret field.
And here we're going to type in what we saw over here which is a $ not equals to or 'ne'
:
so this code should now look through all of our users in our users collection,
look through the secret fields and pick out the users where the secret field is not equal to null.
So all of these conditions end right here
so make sure that you add the comma there and all of these curly braces are one set of here.
It's really really easy to mess this part up
and I do it very often because there's so many curly braces. So here after all of those curly braces
and after the colon and after the comma, we're going to add our callback function with our error or any
of the foundUsers.
So if there were any errors then we're going to simply log it
but otherwise if indeed we actually did find some users, so foundUsers is not equal to nil, then we're
going to res.render our secrets.ejs page and we're going to pass in a variable. Let's call
that variable
usersWithSecrets because that's essentially what we're searching for
right?
We're trying to find all the users which have a filled secret field. And we're going to pass in these
foundUsers as the value for this variable.
So let's go ahead and close off these lines of code and we can now pick this up inside our secret.
ejs.
So at the moment the secret text is a single hard coded value, it's "Jack Bauer is my hero."
So let's go ahead and delete that secret text and instead replace it using the secrets that we actually
have in our database.
So we know that we get access inside secrets.ejs to a variable called usersWithSecrets.
So inside here we can run a forEach loop. So we can happen to usersWithSecrets and we can call for
each on this variable to loop through that array and then we're going to add in a callback function
in here to pick up all of those users inside the usersWithSecrets array.
And for each of those users, we're going to render the value of the user.secrets field inside a paragraph
element.
So inside here between the two p tags is where we're going to add our special EJS tag, so angle
bracket percentage sign equals
and then it ends with percentage sign closing angle bracket. And in between right here just after the
equals sign is where we're going to tap into user.secret.
So this will loop through all the users with secrets. For each user that has a secret
we're going to render it inside a paragraph tag and all we need to do now is to mark out the part of
this file that is actually Javascript rather than HTML.
And we do that of course using this angle and percentage signs, percentage sign angle.
So now let's save everything and let's go ahead and test it out.
I'm going to go and register.
Let's say that I sign up with Google again. And you can see that I get taken to the secrets page and
it shows that previous secret that I submitted as the other user.
So let's say that I submit a secret under this other account as well.
Let's add that "Jack Bauer is my hero." again and let's click submit. And you can see we now have two secrets.
So the more users we have, the more secrets they submit the more that gets shown up over here.
So this is a very very basic and minimalist version of the Whisper app because the users usernames or
passwords or emails, none of that is associated with their secret.
So users can sign up, submit their secrets for all the world to see but they don't have to tell the world
who they are.
And we keep their secret secret using all of our advanced authentication methods.
So I hope you had fun learning all of the aspects of authentication.
So until next time.
That's all from me, Angela at the App brewery.