This episode is for members only

Sign up to access "Laravel Teams" right now.

Get started
Already a member? Sign in to continue
Playing
20. Storing invitations

Episodes

0%
Your progress
  • Total: 4h 36m
  • Played: 0m
  • Remaining: 4h 36m
Join or sign in to track your progress
01. Introduction and demo
4m 49s
0%
02. Setup with Pest
4m 2s
0%
03. Building the user teams relations
6m 5s
0%
04. Creating a personal team when registering
6m 3s
0%
05. Leaving all teams when an account is deleted
3m 55s
0%
06. Tracking the current team
4m 50s
0%
07. Showing team details in the UI
2m 55s
0%
08. Switching to another team
7m 24s
0%
09. Authorising team switching
6m 53s
0%
10. Updating a team name
10m 48s
0%
11. Basic roles and permissions setup
5m 26s
0%
12. Team roles and permissions middleware
9m 18s
0%
13. Authorising current team updates
3m 43s
0%
14. Testing team permissions through HTTP requests
3m 58s
0%
15. Leaving a team
10m 50s
0%
16. Displaying team members
8m 42s
0%
17. Making team members look better
5m 3s
0%
18. Removing a team member
15m 18s
0%
19. Preventing self removal from a team
4m 7s
0%
20. Storing invitations
13m 31s
0%
21. Validating invitations
6m 38s
0%
22. Authorising team invitation creation
6m 22s
0%
23. Displaying invitations
3m 16s
0%
24. Revoking invitations
12m 46s
0%
25. Sending an invitation email
13m 6s
0%
26. Accepting an invitation
12m 22s
0%
27. Displaying a modal to change a member’s role
10m 31s
0%
28. Updating a member’s role
9m 5s
0%
29. More authorisation and checks for role changing
10m 14s
0%
30. Fixing up the email sending test details
49s
0%
31. Fixing and validating email addresses for invites
1m 32s
0%
32. Tidying up @can directive checks
3m 25s
0%
33. Detaching roles when removing users
5m
0%
34. Adding an extra layer of protection to the team middleware
6m 35s
0%
35. Getting related models through teams
5m 37s
0%
36. Building a helper to access the current team
10m 47s
0%
37. Getting all related models through all teams
7m 15s
0%
38. Creating new teams
13m 7s
0%

Transcript

00:00
Managing team invitations is probably the most difficult part of this entire thing. So let's get started with something really basic, creating the form and storing an invite. Okay so first of all we need a form but just before we do this let's go ahead and update our
00:13
admin role cedar to let this know that we can invite members to the team. So let's just call this invite to team and of course once again go ahead and just seed this in the database. Okay so now that we've done this let's go over to our team members and let's go down to the bottom here and we'll create our form but we can just straight away wrap this in an invite to team
00:38
so we know that it's hidden if we can't do that there's no point in showing this otherwise. Let's go ahead and end the account there and let's start to create this form out. We can actually take most of this boilerplate from the edit team form so let's actually copy the majority of this form in fact we'll take the entire thing it's pretty much going to be the same
00:57
and we can just modify it as we need. Okay so we don't know where this is going through to yet so let's get rid of the action here and we know that this is going to be a post request so we can just get rid of the method and this is going to be the email address of the person that we want to invite whether or not they've already got an account it doesn't matter. So let's change all of these over
01:17
to email the type here we will set to an email as well and we'll switch over all of these bits as well and let's get rid of autofocus on the page here and set up the email for this. Now we don't need an old value for this so we'll just take on an old default value so we'll just take the old email address. Okay so let's call this invite and then we'll say change this over to team invited and we
01:50
will show some slightly different text here so we'll say invite sent. Okay that should be everything we need we can always adjust it if not but let's just take a look there we go so we can go ahead and type in an email address here hit invite and of course that's gonna send that through. Okay so let's look now at how we're actually going to store invites that's going to be via a model so
02:14
let's go ahead and create out a model called team invite again we'll create a migration and a factory alongside of this as well so let's focus on the schema first so create team invites table let's think about what we need to store here so we need to know which team this actually relates to so let's go ahead and pull in a foreign id here for the team id and we'll constrain that to make sure
02:38
it exists next up is going to be a string so that's just going to be the email address of the person we've invited now this doesn't really matter what's stored here we're going to store it anyway just purely for display purposes but once we send this email off the user can sign in with any account it doesn't necessarily matter this is going to be valid for anyone who receives this email we're
03:02
going to make sure this email is signed and secure and also has an expiry so it can't hang around for too long and of course once the invitation has been accepted we're going to get rid of this in the database so it can't be used to be sent to anyone else so it's just for one person okay so because of that we're also going to need some sort of token to be stored in here as well this token
03:23
is going to be used purely to identify this invite not necessarily to sign the url so we're not using this as really a security feature we're just using it as a sort of identification token okay let's go ahead and migrate this and then we'll build out the controller to actually go ahead and store this we'll write a quick test for this we'll build on that test later because we want to make sure other
03:47
things are going to happen like an email is getting sent and all that stuff but let's go ahead and work on the basics so again we're going to pull this out to a completely new controller so let's go ahead and make a controller here called team invite controller and let's create out the route for this first of all so let's pull this down here and let's make this a post request through to the
04:07
team that we want to invite for and we'll just call this invites let's go ahead and say team invite controller and let's call this store that kind of makes sense and let's say team invites and store now that we've done this let's go over to our team members here and we'll update this to go through to there so let's say team invites store we need to pass the team through to this
04:37
so let's just pass the team that we are pushing this through to okay let's go over and try and submit this so let's just type in an email address here hit invite and yeah of course we haven't pulled out the method so let's do that quickly team invite controller and let's just create that method here really quickly pull the team in that we're trying to store for and let's go ahead and
05:01
just die dump on that team just to make sure and there we go great okay so what do we need to do well we need to create out an invite so how do we do this well we can create a relationship on our team that specifically has many invites and then we can just create directly through that so let's do that first so team.php and we'll go ahead and create out an invite this is really simple it's
05:25
just going to be a has many relationship because we just have that team id column in there so this is going to be this has many and we'll just reference that team invite model just while we're here as well let's open up team invite just to make sure nothing goes wrong and we'll set guarded here to false okay now that we've got this we can create this invite out passing in the email address
05:51
that we get through from the request we'll use this as a standard request now and then we'll switch that over to a form request later so let's just pull this from request email the reason i'm doing it like this rather than pulling it directly from only or any of the other methods that we have on the request is we also need to generate out a token so we can do this in any way so i'm just
06:13
going to use the string helper here to generate out a random 30 character string and that should be enough just to identify this remember we're not using this as a security measure okay let's go ahead and return back and we'll redirect with that status to show on the form that we've invited i think we call that team invited and that should be okay okay let's just try this out manually in
06:37
here first of all so let's go over to our team and let's have a look okay so i'm going to choose any of these email addresses we're going to add in a check to say that we can't invite ourselves but let's just use this email address for now okay yeah so let's go ahead and finish that off there and just retry that and if we open up our database we should now have an invite in there
06:59
with a random token great so let's test for this functionality and this is actually trickier than you might think because we're using random strings here so if we want to check that this token has been filled with a random string how are we going to do that in our tests well let's find out so let's make out a test here pest test and we'll create a team invite controller test let's go
07:21
over to that team invite controller test and let's just do the most basic first the sort of best case scenario creates an invite okay so what do we need to do well we need a user in here of course as always so let's grab out the user from our factory and let's just do this by acting as that user and then just posting through and we'll use the current team that the user is in as an example
07:46
so we're just inviting someone to our current team so team invites and store we're going to use the user's current team for this and what do we want to assert well we know that we want to assert a redirect and then down here we'll assert that this actually gets put into the database so let's go ahead and run this test first of all we'll just run this as the controller so team invite controller
08:08
test and we get a fail so let's just take a look and see what we've got here and okay yeah we didn't actually pass the data down in the test that kind of makes sense of course we need validation in here as well which we will be adding in a little bit later we're going to sort of skip that for now and look at the best case okay so let's choose an email address that we are inviting to this team
08:31
something different from the user's email address so we could even manually set the email address in here to distinguish that these are different but let's just leave that for now and there we go that passes so we know that we're redirected back but now we want to make sure that the database has this data so we can say assert database has we can choose the table which is going to be the team
08:52
invites and let's go ahead and figure out the data that we want to look for so we can look for the team id to make sure that this is being set correctly for the user's current team that we passed in the url so we can just say current team id we can check that the email address is in there because we've stored that as a local variable just up here like that and that's going to work so let's
09:15
go ahead and rerun our test and yeah the data is in the database but what happens when it comes to looking for the token well because we're using a randomly generated string over in here how do we go ahead and mock this well laravel provides a really nice way to do this so to do this let's just choose the string that we want to fake we're just going to put that as abc for now it doesn't
09:42
really matter what we do then up here what we can do is we can use the string facade so let's put in illuminate support string and we can use create random strings using and we can provide a factory here which returns a string for us so we can just do this as a short closure which returns the value abc what's going to happen now is we've done this before we've gone ahead and hit this point
10:07
inside of our controller this is now going to generate the value abc obviously only within our tests so that means that we can specifically check that the token has been stored with the value that we faked and this should go ahead and pass great so we know that that value is now in the database now there's one problem with using this is that for any other test that you run after this it's
10:30
always now going to use abc as the string and we might not want that so what we can do is we can actually return this back to normal what we don't want to do is return this back to normal down here because if for example this test fails then it's not never going to get to this point here and that means that our random strings for our future tests that might pass are going to go ahead and
10:55
use that same random string so basically what we want to do is somewhere within our tests is use an after each hook to go ahead and return these back to normal so we can just use a closure or a short closure in here and we can say string create random strings normally so after each test even if it fails we're going to go ahead and return them back to normal so we can put this either at
11:19
the top or the bottom wherever you want okay so let's go ahead and rerun this and there we go so after each test that we run within this test file specifically these strings are going to be returned back to normal let's go ahead and just add a really quick validation check to this i'm not going to write a test for this i don't generally write tests for simple validation but you can do
11:38
if you want to i prefer to do them in end to end tests but let's go ahead and add this in any way so over in our team invite controller let's go ahead and create our form request to deal with this and of course we know that later we're going to add in our policy stuff in there as well so let's go ahead and make out a form request so make request and this is going to be let's think about
11:58
team invite store request great so let's go ahead and switch this up team invite store request and let's go ahead and fill this in so we know that the email address is required we're going to need to add some more validation rules to this a little bit later i'm also going to set a max of 255 just because it's a database constraint but of course you can change that over as well if you want to
12:23
okay let's run our test again after that change and yeah just looks like it's failed so we've got a 403 here yeah that's just because by default this is set to false let's switch that to true just for that test to pass and of course we'll add in our policy stuff later okay so just if you did want to write a test this let's go ahead and do one anyway uh just so you know how to do this so
12:46
let's say it requires an email address we'll just add this as an example if you're new to testing particularly with pest so we're going to go ahead and do exactly the same thing let's pull out a user in here send a request down again in fact we can copy and paste this in here and we're going to send this request down but we are going to not send an email address down what do we need to
13:11
assert well we can assert that the session has errors and we can choose the errors and that's going to be an email address error so let's go ahead and just rerun our entire test and there we go we get green so really simple to do that just to make sure that that email is required we won't be doing that much throughout the course but there it is if you need it
38 episodes4 hrs 36 mins

Overview

Need team functionality in your Laravel application? Let’s build it from scratch.

We’ll cover the basics of creating teams, switching between them, sending secure team invites by email, and managing team members.

Powering everything will be roles and permissions for each member, with the ability to switch roles directly from your team dashboard.

Once you’re done, you’ll have mastered team functionality in Laravel.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!