This project was developed for learning case at Rocketseat. It's a monorepo managed with TurboRepo that contains all the necessary boilerplate to setup a multi-tenant SaaS with Next.js and Fastify including authentication and RBAC authorization.
Tools | Β Β Β Β |
---|---|
API | Β Β Β Β Β Β Β Β Β Β Β Β |
Front-end | Β Β Β Β Β Β Β Β Β Β Β Β |
Packages and Config | Β Β Β Β Β |
Deploy | Β Β Β |
This project contains all the necessary boilerplate to setup a multi-tenant SaaS including authentication with RBAC, account settings, organizations management with projects, members, invitations and its settings. It started as a learning case and I end up creating more features and expanding all the project. Check it out:
Roles: the owner (administrator) of organizations who is able manage all data and actions; The regular member who is able to manage their projects; And the billing member who is able to manage, of course, the billing data. You can see the full detailed table below with the authorizations.
Authentication: consists into classic e-mail and password sign-in, also it includes the oAuth with third-party services from GitHub and Google. The traditional sign-up method requires an e-mail verification by a token valid for five minutes that is sent to the user inbox with instructions. The password recovery functionality works in a similar way of e-mail verification by a token sent to user e-mail.
Account settings: the user is able to manage their account: (1) basic information including the avatar, name and e-mail (to effectly change the e-mail, a revalidation is required); (2) set a password in case of social sign-in or change an existing one; (3) Connect or disconnect third-party authentication providers; (4) Manage all organizations that they are in and there's a option to leave organization from that they doesn't owns; (5) Delete account along with all owned organizations.
Organization projects: here the users can make the CRUD of projects, since this app is a boilerplate, it was developed a superficial projects section only with avatar, name, description and author.
Organization members: in this section the owner can manage the existing members of the organization being able to change their roles, remove them or transfer the ownership of the organization to one of them. There is also the option to invite new members for a specific role by sending an e-mail with the invitation link.
Organization settings: the owner has control of the entire organization: (1) change the avatar and its unique name; (2) It is possible to configure a unique domain, so new app users after signing up with the e-mail containing the domain could auto-join the organization. To be able to use a domain on organization, the owner must verify the domain ownership by setting a TXT entry on domain DNS records configuration of their domain; (3) The billing section, also shown to the billing member, is where the usage stats of organization are; (4) Finally, there it the option to shutdown the organization with all its data.
The API was developed using Fastify along with Prisma ORM and PostgreSQL as database; It was configured nodemailer to deal with transactional and validation e-mails; It was created a Cloudflare R2 bucket to store users, organizations and projects avatars using AWS SDK to establish the connection.
The front-end web app was developed using Next.js 15 with App Router with React 19 RC; It was used a not very known API client, KY, to deal with the requests that works very well with Next; It was used React Query to some client side requests; All design and components was written using shadcn/ui with Tailwind.
This project was prepared for deploy usign these three services: (1) Neon for hosting the PostgreSQL database; (2) Render to host the API; (3) Vercel to host the wep app. The API and Web apps were configured with my subdomain.
There are some pending stuff to do in here, so I'll be commiting in the near future.
Display contents
- Generate your .env file:
cp .env.example .env
- Follow the next steps to fill the information.
Display contents
Configure this services and paste all needed information to your .env file:
- Create a GitHub OAuth and a Google OAuth apps to be able to sign-in with these providers.
- Make sure your Google Account have 2FA activeted and then you must generate an app password to be able to send transactional and validation e-mails.
- Create a Cloudflare R2 bucket to upload the app avatars.
Display contents
# Generate RSA256 secret and public keys: (Requires OpenSSL installed)
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private_key.pem -out public_key.pem
# Convert keys to Base64: (MacOS/Linux)
base64 -i private_key.pem -o private_key.txt
base64 -i public_key.pem -o public_key.txt
[!TIP] Use ChatGPT:
- Private and public keys: "How to generate RS256 private and public keys on [YOUR OS]"
- Convert generated keys to base64: "How to convert file contents to base64 on [YOUR OS]"
Display contents
# root:
pnpm i
docker compose up -d # make sure you are running docker
# apps/api
pnpm run db:migrate # seeds will run along
# root:
pnpm run dev
Other available commands:
# apps/api
pnpm run db:deploy
pnpm run db:reset
pnpm run db:studio
[!NOTE] The commands starting with
pnpm run db:*
are used for loading environment variables into them.
- API: http://localhost:3333
- API Docs: http://localhost:3333/docs
- WEB: http://localhost:3000/
Description | Owner | Member | Billing | Anonymous |
---|---|---|---|---|
Update organization | β | β | β | β |
Delete organization | β | β | β | β |
Invite a member | β | β | β | β |
Revoke an invite | β | β | β | β |
List members | β | β | β | β |
Transfer ownership | π‘ | β | β | β |
Update member role | β | β | β | β |
Delete member | β | π‘ | β | β |
List projects | β | β | β | β |
Create a new project | β | β | β | β |
Update a project | β | π‘ | β | β |
Delete a project | β | π‘ | β | β |
Get billing details | β | β | β | β |
Export billing details | β | β | β | β |
β allowed | β not allowed | π‘ allowed with conditions
Conditions:
- Only owners are able to transfer organization ownership;
- Only administrators and project authors are able update/delete a project;
- Only auth users can update their preferences;
- Members are able to leave a organization that they are in;
- Invites can be accepted or rejected by anyone with the link;