Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 31 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# 💎 Rails 6 boilerplate with devise, JWT, graphQL, CanCanCan and RailsAdmin.

[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/zauberware/rails-devise-graphql/graphs/commit-activity)
[![GitHub license](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/zauberware/rails-devise-graphql/blob/master/LICENSE)
![GitHub top language](https://img.shields.io/github/languages/top/zauberware/rails-devise-graphql)
Expand All @@ -14,7 +15,9 @@ This is a boilerplate to build your next SaaS product. It's a RubyOnRails 6 back
- PostgreSQL Server as db connector

### Dependencies

This boilerplate works like a charm with the following gems:

- pg
- devise
- devise_invitable
Expand All @@ -32,12 +35,11 @@ This boilerplate works like a charm with the following gems:
- friendly_id
- dotenv


## 🚀 Quick start

You can have a running backend in seconds on [heroku](https://www.heroku.com):

[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/zauberware/rails-devise-graphql)
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/zauberware/rails-devise-graphql)

or clone this repo:

Expand All @@ -46,7 +48,7 @@ git clone https://github.com/zauberware/rails-devise-graphql my-saas-backend
cd my-saas-backend
```

Clone `env_sample` to .env for local development. We set it up with default rails `3000` and client `8000` ports:
Clone `env_sample` to .env for local development. We set it up with default rails `3000` and client `8000` ports:

```sh
cp env_sample .env
Expand Down Expand Up @@ -79,28 +81,31 @@ Download a GraphQL client like [GraphiQL](https://github.com/graphql/graphiql) o
## 🎁 What's included?

### 1. Database
The app uses a PostgreSQL database. It implements the connector with the gem `pg`. The app already includes a `User` and a `Company` model with basic setup. We see an `Company` as a company with it's users. We did **not** add multi-tenancy to this app. If you want to do it by yourself check out the [apartment](https://github.com/influitive/apartment) gem.

The app uses a PostgreSQL database. It implements the connector with the gem `pg`. The app already includes a `User` and a `Company` model with basic setup. We see an `Company` as a company with it's users. We did **not** add multi-tenancy to this app. If you want to do it by yourself check out the [apartment](https://github.com/influitive/apartment) gem.

### 2. Authentication

The app uses [devise](https://github.com/plataformatec/devise)'s logic for authentication. For graphQL API we use the JWT token, but to access the rails_admin backend we use standard devise views, but registration is excluded.

Change devise settings under `config/initializers/devise.rb` and `config/initializers/graphql_auth.rb`.

#### Invitations

Admins of a company can invite new users. The process is handled with `devise_invitable`. We added a `inviteUser` and `acceptInvite` mutation to handle this process via graphql.

Like in the reset password process we redirect the users to the frontend domain and not to backend.


### 3. JSON Web Token
[graphql-auth](https://github.com/o2web/graphql-auth) is a graphql/devise extension which uses JWT tokens for user authentication. It follows [secure by default](https://en.wikipedia.org/wiki/Secure_by_default) principle.

[graphql-auth](https://github.com/o2web/graphql-auth) is a graphql/devise extension which uses JWT tokens for user authentication. It follows [secure by default](https://en.wikipedia.org/wiki/Secure_by_default) principle.

### 4. GraphQL

[graphql-ruby](https://github.com/rmosolgo/graphql-ruby) is a Ruby implementation of GraphQL. Sadly it's not 100% open source, but with the free version allows you amazing things to do. See the [Getting Started Guide](https://graphql-ruby.org/) and the current implementations in this project under `app/graphql/`.

#### Filters, Sorting & Pagination

Our `BaseResolver` class provides everything you need to achieve filter, sorting and pagination. Have a look at the resolver `resolvers/users/users.rb`:

**How to:**
Expand All @@ -123,6 +128,7 @@ end
```

Set a connection_type as return type to allow pagination:

```ruby
type Types::Users::UserType.connection_type, null: false
```
Expand Down Expand Up @@ -156,40 +162,40 @@ end

We have disabled introspection of graphQL entry points here `app/graphql/graphql_schema.rb`. Remove `disable_introspection_entry_points` if you want to make the schema public accessible.


### 5. CORS
Protect your app and only allow specific domains to access your API. Set `CLIENT_URL=` in `.env` to your prefered client. If you need advanced options please change the CORS settings here `config/initializers/cors.rb`.

Protect your app and only allow specific domains to access your API. Set `CLIENT_URL=` in `.env` to your prefered client. If you need advanced options please change the CORS settings here `config/initializers/cors.rb`.

### 6. App server
The app uses [Puma](https://github.com/puma/puma) as the web serber. It is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications in development and production.

The app uses [Puma](https://github.com/puma/puma) as the web server. It is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications in development and production.

### 7. UUID
The app uses UUID as ids for active record entries in the database. If you want to know more about using uuid instead of integers read this [article by pawelurbanek.com](https://pawelurbanek.com/uuid-order-rails).

The app uses UUID as ids for active record entries in the database. If you want to know more about using uuid instead of integers read this [article by pawelurbanek.com](https://pawelurbanek.com/uuid-order-rails).

### 8. Automatic model annotation

Annotates Rails/ActiveRecord Models, routes, fixtures, and others based on the database schema. See [annotate_models gem](https://github.com/ctran/annotate_models).

Run `$ annotate` in project root folder to update annotations.


### 9. Abilities with CanCanCan

[CanCanCan](https://github.com/CanCanCommunity/cancancan) is an authorization library for Ruby and Ruby on Rails which restricts what resources a given user is allowed to access. We combine this gem with a `role` field defined on user model.

Start defining your abilities under `app/models/ability.rb`.


### 10. Rails Admin

To access the data of your application you can access the [rails_admin](https://github.com/sferik/rails_admin) dashboard under route `http://0.0.0.0:3000/admin`. Access is currently only allowed for users with super admin role.

If you want to give your admin interface a custom branding you can override sass variables or write your own css under `app/assets/stylesheets/rails_admin/custom`.

Change rails_admin settings under `config/initializers/rails_admin.rb`.


### 11. I18n

This app has the default language `en` and already set a secondary language `de`. We included the [rails-i18n](https://github.com/svenfuchs/rails-i18n) to support other languages out of the box. Add more languages under `config/initializers/locale.rb`.

#### Setting locale
Expand All @@ -210,16 +216,16 @@ To get translations for rails admin out of the box we use [rails_admin-i18n](htt

How to test your locale files and how to find missing one read [this](https://github.com/svenfuchs/rails-i18n#testing-your-locale-file).


### 12. HTTP Authentication

For your staging environment we recommend to use a HTTP Auth protection. To enable it set env var `IS_HTTP_AUTH_PROTECTED` to `true`.

Set user with `HTTP_AUTH_USER` and password with `HTTP_AUTH_PASSWORD`.

We enable HTTP auth currently for all controllers. The `ApplicationController` class includes the concern `HttpAuth`. Feel free to change it.


### 13. Auto generated slugs

To provider more user friendly urls for your frontend we are using [friendly_id](https://github.com/norman/friendly_id) to auto generate slugs for models. We have already implemented it for the `Company` model. For more configuration see `config/initializers/friendly_id.rb`.

To create a new slug field for a model add a field `slug`:
Expand All @@ -239,11 +245,11 @@ end
```

Replace traditional `Company.find(params[:id])` with `Company.friendly.find(params[:id])`

```ruby
company = Company.friendly.find(params[:id])
```


### 14. Testing

We are using the wonderful framework [rspec](https://github.com/rspec/rspec). The test suit also uses [factory_bot_rails](https://github.com/thoughtbot/factory_bot_rails) for fixtures.
Expand All @@ -266,7 +272,7 @@ Create fake data easily with [faker gem](https://github.com/faker-ruby/faker). C

[SimpleCov](https://github.com/simplecov-ruby/simplecov) is a code coverage analysis tool for Ruby. It uses Ruby's built-in Coverage library to gather code coverage data, but makes processing its results much easier by providing a clean API to filter, group, merge, format, and display those results, giving you a complete code coverage suite that can be set up with just a couple lines of code.

Open test coverage results with
Open test coverage results with

```sh
$ open /coverage/index.html
Expand All @@ -277,6 +283,7 @@ Open test coverage results with
We are using the wonderful [rubocop](https://github.com/rubocop-hq/rubocop-rails) to lint and auto fix the code. Install the rubocop VSCode extension to get best experience during development.

### 16. Security with Rack Attack

See `config/initializers/rack_attack.rb` file. We have defined a common set of rules to block users trying to access the application multiple times with wrong credentials, or trying to create a hundreds requests per minute.

To speed up tests add this to your `.env.test`
Expand All @@ -287,7 +294,9 @@ ATTACK_AUTHENTICATED_REQUEST_LIMIT=30
```

### 17. Sending emails

Set your SMTP settings with these environment variables:

- `SMTP_ADDRESS`
- `SMTP_PORT`
- `SMTP_DOMAIN`
Expand All @@ -302,8 +311,8 @@ Have a look at `config/environments/production.rb` where we set the `config.acti

Set the email address for your `ApplicationMailer` and devise emails with env var `DEVISE_MAILER_FROM`.


### 18. Deployment

The project runs on every server with ruby installed. The only dependency is a PostgreSQL database. Create a block `production:` in the`config/database.yml` for your connection.

#### Heroku
Expand All @@ -325,6 +334,7 @@ The pipeline has 2 environments: staging and production. Staging pipeline is get
It also triggers pipeline while opening a PR.

## What's missing?

- Check & retest locked accounts
- Invite for users, inviteMutation & acceptInviteMutation
- Registration add more fields (Firstname, Last name)
Expand All @@ -334,6 +344,7 @@ It also triggers pipeline while opening a PR.
Feel free to make feature request or join development!

## Share this repo

Help us to get more attention to this project:

![Twitter URL](https://img.shields.io/twitter/url?label=Tweet%20about%20this%20project&style=social&url=https%3A%2F%2Fgithub.com%2Fzauberware%2Frails-devise-graphql)
Expand All @@ -351,16 +362,14 @@ Thank you to **all our backers**! 🙏 ([Become a backer](https://opencollective

<a href="https://opencollective.com/rails-devise-graphql/sponsor/0/website" target="_blank"><img src="https://opencollective.com/rails-devise-graphql/sponsor/0/avatar.svg"></a>


## ❤️ Code of Conduct

Please note that zauberware has a [Code of Conduct](https://github.com/zauberware/rails-devise-graphql/blob/master/CODE_OF_CONDUCT.md). By participating in this project online or at events you agree to abide by its terms.


## Author

__Script:__ <https://github.com/zauberware/rails-devise-graphql>
**Script:** <https://github.com/zauberware/rails-devise-graphql>

__Author website:__ [https://www.zauberware.com](https://www.zauberware.com)
**Author website:** [https://www.zauberware.com](https://www.zauberware.com)

![zauberware technologies](https://avatars3.githubusercontent.com/u/1753330?s=200&v=4)