devise_invitations 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +3 -0
 - data/Gemfile +4 -0
 - data/Gemfile.lock +116 -0
 - data/LICENSE +9 -0
 - data/README.md +46 -0
 - data/Rakefile +12 -0
 - data/app/views/devise_invitations/mailer/instructions.html.erb +5 -0
 - data/circle.yml +11 -0
 - data/config/locales/devise_invitations.en.yml +7 -0
 - data/devise_invitations.gemspec +22 -0
 - data/lib/devise_invitations.rb +14 -0
 - data/lib/devise_invitations/controller.rb +26 -0
 - data/lib/devise_invitations/engine.rb +4 -0
 - data/lib/devise_invitations/mailer.rb +24 -0
 - data/lib/devise_invitations/model.rb +18 -0
 - data/lib/devise_invitations/version.rb +3 -0
 - data/lib/generators/devise_invitations/install_generator.rb +61 -0
 - data/lib/generators/devise_invitations/migrations/templates/migration.rb +19 -0
 - data/lib/generators/devise_invitations/models/templates/associations.rb +3 -0
 - data/lib/generators/devise_invitations/routes/templates/routes.rb +6 -0
 - data/lib/generators/devise_invitations/specs/templates/association.rb +2 -0
 - data/lib/generators/devise_invitations/specs/templates/controller.rb +71 -0
 - data/lib/generators/devise_invitations/specs/templates/factory.rb +7 -0
 - data/lib/generators/devise_invitations/specs/templates/model.rb +21 -0
 - data/lib/generators/devise_invitations/specs_generator.rb +30 -0
 - data/magic.sh +83 -0
 - metadata +129 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA1:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 7aac54a0d1a5d67f8a773fc598199289e6365b32
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 6c54a34bd81348aa616628c776a05cfd545d88d7
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 3c83fcc55964355ae244cd81c401baa549a9a43a6dfb63a6609152fd7cf378ad318baecf058b6712a20e14bc17452d31e4dae83054f106393454610b61eafb9c
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 484c2973f4247f5335773e28c370d1a61db1197e047a4524a8c0473c9bf52593e517a39d3f6f6dac37d81c4e2009424f205779c338a6e4ec4c7894e392533f4a
         
     | 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | 
         @@ -0,0 +1,116 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            PATH
         
     | 
| 
      
 2 
     | 
    
         
            +
              remote: .
         
     | 
| 
      
 3 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 4 
     | 
    
         
            +
                devise_invitations (0.1)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  devise_invitable (~> 1.5)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  faker (~> 1.6)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  has_secure_token (~> 1.0)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  shoulda-matchers (~> 2.0)
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            GEM
         
     | 
| 
      
 11 
     | 
    
         
            +
              remote: https://rubygems.org/
         
     | 
| 
      
 12 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 13 
     | 
    
         
            +
                actionmailer (4.2.5)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  actionpack (= 4.2.5)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  actionview (= 4.2.5)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  activejob (= 4.2.5)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  mail (~> 2.5, >= 2.5.4)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  rails-dom-testing (~> 1.0, >= 1.0.5)
         
     | 
| 
      
 19 
     | 
    
         
            +
                actionpack (4.2.5)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  actionview (= 4.2.5)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  activesupport (= 4.2.5)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  rack (~> 1.6)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  rack-test (~> 0.6.2)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  rails-dom-testing (~> 1.0, >= 1.0.5)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  rails-html-sanitizer (~> 1.0, >= 1.0.2)
         
     | 
| 
      
 26 
     | 
    
         
            +
                actionview (4.2.5)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  activesupport (= 4.2.5)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  builder (~> 3.1)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  erubis (~> 2.7.0)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  rails-dom-testing (~> 1.0, >= 1.0.5)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  rails-html-sanitizer (~> 1.0, >= 1.0.2)
         
     | 
| 
      
 32 
     | 
    
         
            +
                activejob (4.2.5)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  activesupport (= 4.2.5)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  globalid (>= 0.3.0)
         
     | 
| 
      
 35 
     | 
    
         
            +
                activemodel (4.2.5)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  activesupport (= 4.2.5)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  builder (~> 3.1)
         
     | 
| 
      
 38 
     | 
    
         
            +
                activerecord (4.2.5)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  activemodel (= 4.2.5)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  activesupport (= 4.2.5)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  arel (~> 6.0)
         
     | 
| 
      
 42 
     | 
    
         
            +
                activesupport (4.2.5)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  i18n (~> 0.7)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  json (~> 1.7, >= 1.7.7)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  minitest (~> 5.1)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  thread_safe (~> 0.3, >= 0.3.4)
         
     | 
| 
      
 47 
     | 
    
         
            +
                  tzinfo (~> 1.1)
         
     | 
| 
      
 48 
     | 
    
         
            +
                arel (6.0.3)
         
     | 
| 
      
 49 
     | 
    
         
            +
                bcrypt (3.1.10)
         
     | 
| 
      
 50 
     | 
    
         
            +
                builder (3.2.2)
         
     | 
| 
      
 51 
     | 
    
         
            +
                devise (3.5.4)
         
     | 
| 
      
 52 
     | 
    
         
            +
                  bcrypt (~> 3.0)
         
     | 
| 
      
 53 
     | 
    
         
            +
                  orm_adapter (~> 0.1)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  railties (>= 3.2.6, < 5)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  responders
         
     | 
| 
      
 56 
     | 
    
         
            +
                  thread_safe (~> 0.1)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  warden (~> 1.2.3)
         
     | 
| 
      
 58 
     | 
    
         
            +
                devise_invitable (1.5.5)
         
     | 
| 
      
 59 
     | 
    
         
            +
                  actionmailer (>= 3.2.6, < 5)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  devise (>= 3.2.0)
         
     | 
| 
      
 61 
     | 
    
         
            +
                erubis (2.7.0)
         
     | 
| 
      
 62 
     | 
    
         
            +
                faker (1.6.1)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  i18n (~> 0.5)
         
     | 
| 
      
 64 
     | 
    
         
            +
                globalid (0.3.6)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  activesupport (>= 4.1.0)
         
     | 
| 
      
 66 
     | 
    
         
            +
                has_secure_token (1.0.0)
         
     | 
| 
      
 67 
     | 
    
         
            +
                  activerecord (>= 3.0)
         
     | 
| 
      
 68 
     | 
    
         
            +
                i18n (0.7.0)
         
     | 
| 
      
 69 
     | 
    
         
            +
                json (1.8.3)
         
     | 
| 
      
 70 
     | 
    
         
            +
                loofah (2.0.3)
         
     | 
| 
      
 71 
     | 
    
         
            +
                  nokogiri (>= 1.5.9)
         
     | 
| 
      
 72 
     | 
    
         
            +
                mail (2.6.3)
         
     | 
| 
      
 73 
     | 
    
         
            +
                  mime-types (>= 1.16, < 3)
         
     | 
| 
      
 74 
     | 
    
         
            +
                mime-types (2.99)
         
     | 
| 
      
 75 
     | 
    
         
            +
                mini_portile2 (2.0.0)
         
     | 
| 
      
 76 
     | 
    
         
            +
                minitest (5.8.3)
         
     | 
| 
      
 77 
     | 
    
         
            +
                nokogiri (1.6.7.1)
         
     | 
| 
      
 78 
     | 
    
         
            +
                  mini_portile2 (~> 2.0.0.rc2)
         
     | 
| 
      
 79 
     | 
    
         
            +
                orm_adapter (0.5.0)
         
     | 
| 
      
 80 
     | 
    
         
            +
                rack (1.6.4)
         
     | 
| 
      
 81 
     | 
    
         
            +
                rack-test (0.6.3)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  rack (>= 1.0)
         
     | 
| 
      
 83 
     | 
    
         
            +
                rails-deprecated_sanitizer (1.0.3)
         
     | 
| 
      
 84 
     | 
    
         
            +
                  activesupport (>= 4.2.0.alpha)
         
     | 
| 
      
 85 
     | 
    
         
            +
                rails-dom-testing (1.0.7)
         
     | 
| 
      
 86 
     | 
    
         
            +
                  activesupport (>= 4.2.0.beta, < 5.0)
         
     | 
| 
      
 87 
     | 
    
         
            +
                  nokogiri (~> 1.6.0)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  rails-deprecated_sanitizer (>= 1.0.1)
         
     | 
| 
      
 89 
     | 
    
         
            +
                rails-html-sanitizer (1.0.2)
         
     | 
| 
      
 90 
     | 
    
         
            +
                  loofah (~> 2.0)
         
     | 
| 
      
 91 
     | 
    
         
            +
                railties (4.2.5)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  actionpack (= 4.2.5)
         
     | 
| 
      
 93 
     | 
    
         
            +
                  activesupport (= 4.2.5)
         
     | 
| 
      
 94 
     | 
    
         
            +
                  rake (>= 0.8.7)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  thor (>= 0.18.1, < 2.0)
         
     | 
| 
      
 96 
     | 
    
         
            +
                rake (10.5.0)
         
     | 
| 
      
 97 
     | 
    
         
            +
                responders (2.1.1)
         
     | 
| 
      
 98 
     | 
    
         
            +
                  railties (>= 4.2.0, < 5.1)
         
     | 
| 
      
 99 
     | 
    
         
            +
                shoulda-matchers (2.8.0)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  activesupport (>= 3.0.0)
         
     | 
| 
      
 101 
     | 
    
         
            +
                thor (0.19.1)
         
     | 
| 
      
 102 
     | 
    
         
            +
                thread_safe (0.3.5)
         
     | 
| 
      
 103 
     | 
    
         
            +
                tzinfo (1.2.2)
         
     | 
| 
      
 104 
     | 
    
         
            +
                  thread_safe (~> 0.1)
         
     | 
| 
      
 105 
     | 
    
         
            +
                warden (1.2.4)
         
     | 
| 
      
 106 
     | 
    
         
            +
                  rack (>= 1.0)
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
            PLATFORMS
         
     | 
| 
      
 109 
     | 
    
         
            +
              ruby
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            DEPENDENCIES
         
     | 
| 
      
 112 
     | 
    
         
            +
              devise_invitations!
         
     | 
| 
      
 113 
     | 
    
         
            +
              rake (~> 10.4)
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            BUNDLED WITH
         
     | 
| 
      
 116 
     | 
    
         
            +
               1.11.2
         
     | 
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2016 Roxas Shadow <webmaster@giovannicapuano.net> All rights reserved.
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            [](https://circleci.com/gh/RoxasShadow/devise_invitations)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            DeviseInvitable
         
     | 
| 
      
 4 
     | 
    
         
            +
            ===============
         
     | 
| 
      
 5 
     | 
    
         
            +
            Allow multiple invitations on top of [devise_invitable](https://github.com/scambra/devise_invitable).
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Why?
         
     | 
| 
      
 8 
     | 
    
         
            +
            ----
         
     | 
| 
      
 9 
     | 
    
         
            +
            Basically devise_invitable, by design, can't handle multiple invitations, since it doesn't use any support table but creates a new hidden `User` for every invitation, storing there both the inviter (through the polymorphic column `sent_by`) and the token.
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            This means that one user is invitable once and only once.
         
     | 
| 
      
 12 
     | 
    
         
            +
            This means that you'll find many hidden `User`s that probably will never sign up your website.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            So what?
         
     | 
| 
      
 15 
     | 
    
         
            +
            --------
         
     | 
| 
      
 16 
     | 
    
         
            +
            So let's create a new table that allows an email address to be invited multiple times by different people, allowing the user to ignore them and sign up normally or, instead, choosing which invitation mail s?he wants to accept. Invitations are not deleted after the related user signs up the website, and they'll be flagged too (`pending` are all the invitations sent, `accepted` is an invitation that has been accepted by an user and `ignored` are the invitations ignored by the user since s?he accepted the one marked as `accepted`).
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            But *devise_invitable* is useful!
         
     | 
| 
      
 19 
     | 
    
         
            +
            ---------------------------------
         
     | 
| 
      
 20 
     | 
    
         
            +
            I know, in fact I'm creating nothing but a layer on top of it. You still need and use *devise_invitable* (I mean, views, controller and the attributes it sets on the invited users).
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            Setup
         
     | 
| 
      
 23 
     | 
    
         
            +
            -----
         
     | 
| 
      
 24 
     | 
    
         
            +
            Create a model called `User`, then run both Devise and *devise_invitable* on it, following their instructions.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            Then, add `gem 'devise_invitations'` to your Gemfile and run `$ bundle install`.
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            You can install *devise_invitations* just by running `$ bin/rails g devise_invitations:install` and `bin/rake db:migrate`.
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            This is what's new in your project:
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            - A migration for a new table called `invitations` is created
         
     | 
| 
      
 33 
     | 
    
         
            +
            - A `has_many` association for `User` (useful to fetch the sent invitations) is injected
         
     | 
| 
      
 34 
     | 
    
         
            +
            - A new route for said action is injected as well
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            If you need to customize something feel free to hard-copy it into your project (i.e. the mailer and the related view).
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            If you use *RSpec* and *FactoryGirl* you can run `$ bin/rails g devise_invitations:specs` to copy the specs for the new associations, controllers and models to your codebase. You can extend and customize them as you wish.
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            Now, you need an action to let your users invite other ones. Basically it's just
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 43 
     | 
    
         
            +
            DeviseInvitations::Invitation.create!(email: params[:email], sent_by: current_user)
         
     | 
| 
      
 44 
     | 
    
         
            +
            ```
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            You can add new columns to the table for new attributes too, like `user_type`, `message` or whatever you want.
         
     | 
    
        data/Rakefile
    ADDED
    
    
    
        data/circle.yml
    ADDED
    
    
| 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require_relative 'lib/devise_invitations/version.rb'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 4 
     | 
    
         
            +
              s.name         = 'devise_invitations'
         
     | 
| 
      
 5 
     | 
    
         
            +
              s.version      = DeviseInvitations::VERSION
         
     | 
| 
      
 6 
     | 
    
         
            +
              s.platform     = Gem::Platform::RUBY
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.author       = 'Roxas Shadow'
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.email        = 'webmaster@giovannicapuano.net'
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.homepage     = 'https://github.com/RoxasShadow/devise_invitations'
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.summary      = 'Allow multiple invitations on top of devise_invitable'
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.description  = 'Extend devise and devise_invitable allowing multiple invitations.'
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.license      = 'BSD-2-Clause'
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              s.files        = `git ls-files`.split("\n")
         
     | 
| 
      
 15 
     | 
    
         
            +
              s.test_files   = `git ls-files specs`.split("\n")
         
     | 
| 
      
 16 
     | 
    
         
            +
              s.require_path = 'lib'
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              s.add_dependency 'devise_invitable', '~> 1.5'
         
     | 
| 
      
 19 
     | 
    
         
            +
              s.add_dependency 'has_secure_token', '~> 1.0'
         
     | 
| 
      
 20 
     | 
    
         
            +
              s.add_dependency 'shoulda-matchers', '~> 2.0'
         
     | 
| 
      
 21 
     | 
    
         
            +
              s.add_dependency 'faker', '~> 1.6'
         
     | 
| 
      
 22 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'has_secure_token' unless Rails.version.start_with?('5')
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            if Rails.env.test?
         
     | 
| 
      
 4 
     | 
    
         
            +
              require 'shoulda-matchers'
         
     | 
| 
      
 5 
     | 
    
         
            +
              require 'faker'
         
     | 
| 
      
 6 
     | 
    
         
            +
            end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            require 'devise_invitations/engine'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            module DeviseInvitations
         
     | 
| 
      
 11 
     | 
    
         
            +
              autoload :Mailer,                'devise_invitations/mailer'
         
     | 
| 
      
 12 
     | 
    
         
            +
              autoload :InvitationsController, 'devise_invitations/controller'
         
     | 
| 
      
 13 
     | 
    
         
            +
              autoload :Invitation,            'devise_invitations/model'
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class DeviseInvitations::InvitationsController < Devise::InvitationsController
         
     | 
| 
      
 2 
     | 
    
         
            +
              def accept
         
     | 
| 
      
 3 
     | 
    
         
            +
                invitation = DeviseInvitations::Invitation.pending.find_by(token: params[:token])
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                if invitation.present? && invitation.valid?
         
     | 
| 
      
 6 
     | 
    
         
            +
                  invitation_params = { email: invitation.email }
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  user = User.invite!(invitation_params, invitation.sent_by) do |u|
         
     | 
| 
      
 9 
     | 
    
         
            +
                    u.skip_invitation = true
         
     | 
| 
      
 10 
     | 
    
         
            +
                  end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  user.update(invitation_sent_at: Time.now.utc)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  statuses = DeviseInvitations::Invitation.statuses
         
     | 
| 
      
 15 
     | 
    
         
            +
                  invitation.update(status: statuses[:accepted])
         
     | 
| 
      
 16 
     | 
    
         
            +
                  DeviseInvitations::Invitation.pending
         
     | 
| 
      
 17 
     | 
    
         
            +
                    .where(email: invitation.email)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    .update_all(status: statuses[:ignored])
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  redirect_to accept_invitation_url(user, invitation_token: user.raw_invitation_token)
         
     | 
| 
      
 21 
     | 
    
         
            +
                else
         
     | 
| 
      
 22 
     | 
    
         
            +
                  flash[:error] = t('en.invitations.accept.not_valid')
         
     | 
| 
      
 23 
     | 
    
         
            +
                  redirect_to root_path
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
              end
         
     | 
| 
      
 26 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class DeviseInvitations::Mailer < ApplicationMailer
         
     | 
| 
      
 2 
     | 
    
         
            +
              def instructions(invitation)
         
     | 
| 
      
 3 
     | 
    
         
            +
                @token    = invitation.token
         
     | 
| 
      
 4 
     | 
    
         
            +
                @sender   = invitation.sent_by
         
     | 
| 
      
 5 
     | 
    
         
            +
                @app_name = app_name
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                mail(
         
     | 
| 
      
 8 
     | 
    
         
            +
                  subject: t('.subject'),
         
     | 
| 
      
 9 
     | 
    
         
            +
                  from:    @sender.email,
         
     | 
| 
      
 10 
     | 
    
         
            +
                  to:      invitation.email,
         
     | 
| 
      
 11 
     | 
    
         
            +
                )
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              private
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              def app_name
         
     | 
| 
      
 17 
     | 
    
         
            +
                Rails.application.class.parent_name
         
     | 
| 
      
 18 
     | 
    
         
            +
                  .underscore
         
     | 
| 
      
 19 
     | 
    
         
            +
                  .humanize
         
     | 
| 
      
 20 
     | 
    
         
            +
                  .split
         
     | 
| 
      
 21 
     | 
    
         
            +
                  .map(&:capitalize)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  .join(' ')
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class DeviseInvitations::Invitation < ActiveRecord::Base
         
     | 
| 
      
 2 
     | 
    
         
            +
              belongs_to :sent_by, class_name: 'User', foreign_key: 'sent_by_id'
         
     | 
| 
      
 3 
     | 
    
         
            +
              has_secure_token :token
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              validates :email, presence: true, format: { with: Devise.email_regexp }
         
     | 
| 
      
 6 
     | 
    
         
            +
              validates :email, :sent_by, uniqueness: { scope: [:email, :sent_by] }
         
     | 
| 
      
 7 
     | 
    
         
            +
              validate :presence_as_user, on: :create
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              enum status: [:pending, :accepted, :ignored]
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              after_create { DeviseInvitations::Mailer.instructions(self).deliver_later }
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              private
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def presence_as_user
         
     | 
| 
      
 16 
     | 
    
         
            +
                errors.add(:email, :user_already_exists) if User.exists?(email: email)
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,61 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module DeviseInvitations
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Generators
         
     | 
| 
      
 3 
     | 
    
         
            +
                class InstallGenerator < Rails::Generators::Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  def install
         
     | 
| 
      
 5 
     | 
    
         
            +
                    %w(migrations models routes).each do |m|
         
     | 
| 
      
 6 
     | 
    
         
            +
                      invoke "devise_invitations:#{m}"
         
     | 
| 
      
 7 
     | 
    
         
            +
                    end
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                class MigrationsGenerator < Rails::Generators::Base
         
     | 
| 
      
 12 
     | 
    
         
            +
                  include Rails::Generators::Migration
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  source_root File.expand_path('../migrations/templates', __FILE__)
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  def copy_migration
         
     | 
| 
      
 17 
     | 
    
         
            +
                    migration_template('migration.rb', 'db/migrate/create_invitations.rb')
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  def self.next_migration_number(path)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    if @prev_migration
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @prev_migration += 1
         
     | 
| 
      
 23 
     | 
    
         
            +
                    else
         
     | 
| 
      
 24 
     | 
    
         
            +
                      @prev_migration = Time.now.utc.strftime('%Y%m%d%H%M%S').to_i
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                    @prev_migration.to_s
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                class ModelsGenerator < Rails::Generators::Base
         
     | 
| 
      
 32 
     | 
    
         
            +
                  source_root File.expand_path('../models/templates', __FILE__)
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  def inject_associations
         
     | 
| 
      
 35 
     | 
    
         
            +
                    inject_into_file('app/models/user.rb', after: 'ActiveRecord::Base') do
         
     | 
| 
      
 36 
     | 
    
         
            +
                      File.read(
         
     | 
| 
      
 37 
     | 
    
         
            +
                        File.join(
         
     | 
| 
      
 38 
     | 
    
         
            +
                          File.expand_path('../models/templates', __FILE__),
         
     | 
| 
      
 39 
     | 
    
         
            +
                          'associations.rb'
         
     | 
| 
      
 40 
     | 
    
         
            +
                        )
         
     | 
| 
      
 41 
     | 
    
         
            +
                      )
         
     | 
| 
      
 42 
     | 
    
         
            +
                    end
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                class RoutesGenerator < Rails::Generators::Base
         
     | 
| 
      
 47 
     | 
    
         
            +
                  source_root File.expand_path('../routes/templates', __FILE__)
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  def inject_routes
         
     | 
| 
      
 50 
     | 
    
         
            +
                    inject_into_file('config/routes.rb', after: 'devise_for :users') do
         
     | 
| 
      
 51 
     | 
    
         
            +
                      File.read(
         
     | 
| 
      
 52 
     | 
    
         
            +
                        File.join(
         
     | 
| 
      
 53 
     | 
    
         
            +
                          File.expand_path('../routes/templates', __FILE__),
         
     | 
| 
      
 54 
     | 
    
         
            +
                          'routes.rb'
         
     | 
| 
      
 55 
     | 
    
         
            +
                        )
         
     | 
| 
      
 56 
     | 
    
         
            +
                      )
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class CreateInvitations < ActiveRecord::Migration
         
     | 
| 
      
 2 
     | 
    
         
            +
              def change
         
     | 
| 
      
 3 
     | 
    
         
            +
                create_table :invitations do |t|
         
     | 
| 
      
 4 
     | 
    
         
            +
                  t.integer :sent_by_id, null: false
         
     | 
| 
      
 5 
     | 
    
         
            +
                  t.string  :email,      null: false
         
     | 
| 
      
 6 
     | 
    
         
            +
                  t.integer :status,     null: false, default: 0
         
     | 
| 
      
 7 
     | 
    
         
            +
                  t.string  :token,      null: false
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  t.timestamps null: false
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                add_index :invitations, :sent_by_id
         
     | 
| 
      
 13 
     | 
    
         
            +
                add_index :invitations, :email
         
     | 
| 
      
 14 
     | 
    
         
            +
                add_index :invitations, :status
         
     | 
| 
      
 15 
     | 
    
         
            +
                add_index :invitations, :token
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                add_foreign_key :invitations, :users, column: :sent_by_id
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,71 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rails_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            RSpec.describe DeviseInvitations::InvitationsController do
         
     | 
| 
      
 4 
     | 
    
         
            +
              describe 'GET #accept' do
         
     | 
| 
      
 5 
     | 
    
         
            +
                before { @request.env['devise.mapping'] = Devise.mappings[:user] }
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                let(:email) { Faker::Internet.safe_email }
         
     | 
| 
      
 8 
     | 
    
         
            +
                let(:user)  { User.find_by(email: email) }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                let(:joe)    { create(:user) }
         
     | 
| 
      
 11 
     | 
    
         
            +
                let(:sender) { create(:user) }
         
     | 
| 
      
 12 
     | 
    
         
            +
                let(:jack)   { create(:user) }
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                let!(:joe_invitation)    { create(:invitation, email: email, sent_by: joe) }
         
     | 
| 
      
 15 
     | 
    
         
            +
                let!(:sender_invitation) { create(:invitation, email: email, sent_by: sender) }
         
     | 
| 
      
 16 
     | 
    
         
            +
                let!(:jack_invitation)   { create(:invitation, email: email, sent_by: jack) }
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                context 'token is valid' do
         
     | 
| 
      
 19 
     | 
    
         
            +
                  subject { get :accept, token: sender_invitation.token }
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  it { is_expected.to have_http_status(302) }
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                  it 'creates a new user' do
         
     | 
| 
      
 24 
     | 
    
         
            +
                    expect { subject }.to change { User.unscoped.find_by(email: email).class }
         
     | 
| 
      
 25 
     | 
    
         
            +
                      .from(NilClass)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      .to(User)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  it 'sets a invited_by attribute to the new user' do
         
     | 
| 
      
 30 
     | 
    
         
            +
                    subject
         
     | 
| 
      
 31 
     | 
    
         
            +
                    expect(user.invited_by).to eq sender
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  it 'flags as accepted the current invitation' do
         
     | 
| 
      
 35 
     | 
    
         
            +
                    expect { subject }.to change { sender_invitation.reload.status }
         
     | 
| 
      
 36 
     | 
    
         
            +
                      .from('pending')
         
     | 
| 
      
 37 
     | 
    
         
            +
                      .to('accepted')
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  it 'flags as ignored the remanining invitations' do
         
     | 
| 
      
 41 
     | 
    
         
            +
                    expect { subject }.to change { joe_invitation.reload.status }
         
     | 
| 
      
 42 
     | 
    
         
            +
                      .from('pending')
         
     | 
| 
      
 43 
     | 
    
         
            +
                      .to('ignored')
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  it 'does not accept additional requests' do
         
     | 
| 
      
 47 
     | 
    
         
            +
                    subject
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    expect { get :accept, token: sender_invitation.token }
         
     | 
| 
      
 50 
     | 
    
         
            +
                      .to change { flash[:error] }
         
     | 
| 
      
 51 
     | 
    
         
            +
                      .from(nil)
         
     | 
| 
      
 52 
     | 
    
         
            +
                      .to(I18n.t('en.invitations.accept.not_valid'))
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                context 'token is valid' do
         
     | 
| 
      
 57 
     | 
    
         
            +
                  subject { get :accept, token: 'lolwut' }
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  it { is_expected.to have_http_status(302) }
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  it 'generates a flash error' do
         
     | 
| 
      
 62 
     | 
    
         
            +
                    subject
         
     | 
| 
      
 63 
     | 
    
         
            +
                    expect(flash[:error]).to eq I18n.t('en.invitations.accept.not_valid')
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                  it 'does not create any new user' do
         
     | 
| 
      
 67 
     | 
    
         
            +
                    expect { subject }.to_not change { User.unscoped.count }
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
                end
         
     | 
| 
      
 70 
     | 
    
         
            +
              end
         
     | 
| 
      
 71 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rails_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            RSpec.describe DeviseInvitations::Invitation do
         
     | 
| 
      
 4 
     | 
    
         
            +
              it { is_expected.to belong_to :sent_by }
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              let(:valid) { build(:invitation) }
         
     | 
| 
      
 7 
     | 
    
         
            +
              it { expect(valid.pending?).to be_truthy }
         
     | 
| 
      
 8 
     | 
    
         
            +
              it { expect(valid.valid?).to be_truthy }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              let(:invalid) { build(:invitation, email: 'lolwut') }
         
     | 
| 
      
 11 
     | 
    
         
            +
              it { expect(invalid.valid?).to be_falsy }
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              context 'use an email that is already registered inside the platform' do
         
     | 
| 
      
 14 
     | 
    
         
            +
                before  { create(:user, email: 'joe@example.com') }
         
     | 
| 
      
 15 
     | 
    
         
            +
                subject { create(:invitation, email: 'joe@example.com') }
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                it 'raises an error' do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,30 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module DeviseInvitations
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Generators
         
     | 
| 
      
 3 
     | 
    
         
            +
                class SpecsGenerator < Rails::Generators::Base
         
     | 
| 
      
 4 
     | 
    
         
            +
                  source_root File.expand_path('../specs/templates', __FILE__)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  def copy_factory
         
     | 
| 
      
 7 
     | 
    
         
            +
                    copy_file('factory.rb', 'spec/factories/invitations.rb')
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                  def copy_controller
         
     | 
| 
      
 11 
     | 
    
         
            +
                    copy_file('controller.rb', 'spec/controllers/invitations_controller_spec.rb')
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def copy_model
         
     | 
| 
      
 15 
     | 
    
         
            +
                    copy_file('model.rb', 'spec/models/invitation_spec.rb')
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def inject_association
         
     | 
| 
      
 19 
     | 
    
         
            +
                    inject_into_file('spec/models/user_spec.rb', after: 'RSpec.describe User, type: :model do') do
         
     | 
| 
      
 20 
     | 
    
         
            +
                      File.read(
         
     | 
| 
      
 21 
     | 
    
         
            +
                        File.join(
         
     | 
| 
      
 22 
     | 
    
         
            +
                          File.expand_path('../specs/templates', __FILE__),
         
     | 
| 
      
 23 
     | 
    
         
            +
                          'association.rb'
         
     | 
| 
      
 24 
     | 
    
         
            +
                        )
         
     | 
| 
      
 25 
     | 
    
         
            +
                      )
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
              end
         
     | 
| 
      
 30 
     | 
    
         
            +
            end
         
     | 
    
        data/magic.sh
    ADDED
    
    | 
         @@ -0,0 +1,83 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ##
         
     | 
| 
      
 2 
     | 
    
         
            +
            # Hello, I'm a magical little girl in aid of CI-kun.
         
     | 
| 
      
 3 
     | 
    
         
            +
            # I'll create and setup a new Rails application from scratch so CI-kun
         
     | 
| 
      
 4 
     | 
    
         
            +
            # can test it. Bye-chi!
         
     | 
| 
      
 5 
     | 
    
         
            +
            ##
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            gem install rails
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            rails new test_app
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            cd test_app
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            echo "gem 'rspec-rails'
         
     | 
| 
      
 14 
     | 
    
         
            +
            gem 'factory_girl_rails'
         
     | 
| 
      
 15 
     | 
    
         
            +
            gem 'letter_opener'
         
     | 
| 
      
 16 
     | 
    
         
            +
            gem 'faker'
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            gem 'devise'
         
     | 
| 
      
 19 
     | 
    
         
            +
            gem 'devise_invitable'
         
     | 
| 
      
 20 
     | 
    
         
            +
            gem 'devise_invitations', path: '../'
         
     | 
| 
      
 21 
     | 
    
         
            +
            " >> Gemfile
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            echo "`sed '45d' Gemfile`" > Gemfile # spring a shit
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            bundle install
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            rails g rspec:install
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            # we need a root_path
         
     | 
| 
      
 30 
     | 
    
         
            +
            rails g controller welcome index
         
     | 
| 
      
 31 
     | 
    
         
            +
            contents="root 'welcome#index'"
         
     | 
| 
      
 32 
     | 
    
         
            +
            echo "`sed \"8s/^/$contents/\" config/routes.rb`" > config/routes.rb
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            rails g model user
         
     | 
| 
      
 35 
     | 
    
         
            +
            rails g mailer UserMailer # we need an ApplicationMailer too
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            rails g devise:install
         
     | 
| 
      
 38 
     | 
    
         
            +
            rails g devise user
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            rails g devise_invitable:install
         
     | 
| 
      
 41 
     | 
    
         
            +
            rails g devise_invitable user
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            ## Uncomment these to check the diff later
         
     | 
| 
      
 44 
     | 
    
         
            +
            # git init
         
     | 
| 
      
 45 
     | 
    
         
            +
            # git add .
         
     | 
| 
      
 46 
     | 
    
         
            +
            # git commit -m "Initial commit"
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            rails g devise_invitations:install
         
     | 
| 
      
 49 
     | 
    
         
            +
            rails g devise_invitations:specs
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            rake db:migrate
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
            # Enable FactoryGirl and Shoulda
         
     | 
| 
      
 54 
     | 
    
         
            +
            echo "
         
     | 
| 
      
 55 
     | 
    
         
            +
            RSpec.configure do |config|
         
     | 
| 
      
 56 
     | 
    
         
            +
              config.include FactoryGirl::Syntax::Methods
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            Shoulda::Matchers.configure do |config|
         
     | 
| 
      
 60 
     | 
    
         
            +
              config.integrate do |with|
         
     | 
| 
      
 61 
     | 
    
         
            +
                with.test_framework :rspec
         
     | 
| 
      
 62 
     | 
    
         
            +
                with.library :rails
         
     | 
| 
      
 63 
     | 
    
         
            +
              end
         
     | 
| 
      
 64 
     | 
    
         
            +
            end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            " >> spec/rails_helper.rb
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
            echo "FactoryGirl.define do
         
     | 
| 
      
 69 
     | 
    
         
            +
              factory :user do
         
     | 
| 
      
 70 
     | 
    
         
            +
                email { Faker::Internet.safe_email }
         
     | 
| 
      
 71 
     | 
    
         
            +
                password { Faker::Internet.password(8) }
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
            end
         
     | 
| 
      
 74 
     | 
    
         
            +
            " > spec/factories/users.rb
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            contents="config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }"
         
     | 
| 
      
 77 
     | 
    
         
            +
            echo "`sed \"39s/^/$contents/\" config/environments/test.rb`" > config/environments/test.rb
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            contents="config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }"
         
     | 
| 
      
 80 
     | 
    
         
            +
            echo "`sed \"38s/^/$contents/\" config/environments/development.rb`" > config/environments/development.rb
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
            contents="config.action_mailer.delivery_method = :letter_opener"
         
     | 
| 
      
 83 
     | 
    
         
            +
            echo "`sed \"33s/^/$contents/\" config/environments/development.rb`" > config/environments/development.rb
         
     | 
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,129 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: devise_invitations
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version
         
     | 
| 
      
 4 
     | 
    
         
            +
              version: '0.1'
         
     | 
| 
      
 5 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 6 
     | 
    
         
            +
            authors:
         
     | 
| 
      
 7 
     | 
    
         
            +
            - Roxas Shadow
         
     | 
| 
      
 8 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 9 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 10 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2016-01-19 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: devise_invitable
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '1.5'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '1.5'
         
     | 
| 
      
 27 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 28 
     | 
    
         
            +
              name: has_secure_token
         
     | 
| 
      
 29 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
      
 34 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 35 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 37 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 38 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '1.0'
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: shoulda-matchers
         
     | 
| 
      
 43 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 44 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 45 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 46 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
      
 48 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 49 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '2.0'
         
     | 
| 
      
 55 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 56 
     | 
    
         
            +
              name: faker
         
     | 
| 
      
 57 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 58 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 59 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 61 
     | 
    
         
            +
                    version: '1.6'
         
     | 
| 
      
 62 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 63 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 64 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 65 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 66 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 67 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 68 
     | 
    
         
            +
                    version: '1.6'
         
     | 
| 
      
 69 
     | 
    
         
            +
            description: Extend devise and devise_invitable allowing multiple invitations.
         
     | 
| 
      
 70 
     | 
    
         
            +
            email: webmaster@giovannicapuano.net
         
     | 
| 
      
 71 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 72 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 73 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 74 
     | 
    
         
            +
            files:
         
     | 
| 
      
 75 
     | 
    
         
            +
            - ".gitignore"
         
     | 
| 
      
 76 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 77 
     | 
    
         
            +
            - Gemfile.lock
         
     | 
| 
      
 78 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 79 
     | 
    
         
            +
            - README.md
         
     | 
| 
      
 80 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 81 
     | 
    
         
            +
            - app/views/devise_invitations/mailer/instructions.html.erb
         
     | 
| 
      
 82 
     | 
    
         
            +
            - circle.yml
         
     | 
| 
      
 83 
     | 
    
         
            +
            - config/locales/devise_invitations.en.yml
         
     | 
| 
      
 84 
     | 
    
         
            +
            - devise_invitations.gemspec
         
     | 
| 
      
 85 
     | 
    
         
            +
            - lib/devise_invitations.rb
         
     | 
| 
      
 86 
     | 
    
         
            +
            - lib/devise_invitations/controller.rb
         
     | 
| 
      
 87 
     | 
    
         
            +
            - lib/devise_invitations/engine.rb
         
     | 
| 
      
 88 
     | 
    
         
            +
            - lib/devise_invitations/mailer.rb
         
     | 
| 
      
 89 
     | 
    
         
            +
            - lib/devise_invitations/model.rb
         
     | 
| 
      
 90 
     | 
    
         
            +
            - lib/devise_invitations/version.rb
         
     | 
| 
      
 91 
     | 
    
         
            +
            - lib/generators/devise_invitations/.DS_Store
         
     | 
| 
      
 92 
     | 
    
         
            +
            - lib/generators/devise_invitations/install_generator.rb
         
     | 
| 
      
 93 
     | 
    
         
            +
            - lib/generators/devise_invitations/migrations/.DS_Store
         
     | 
| 
      
 94 
     | 
    
         
            +
            - lib/generators/devise_invitations/migrations/templates/migration.rb
         
     | 
| 
      
 95 
     | 
    
         
            +
            - lib/generators/devise_invitations/models/.DS_Store
         
     | 
| 
      
 96 
     | 
    
         
            +
            - lib/generators/devise_invitations/models/templates/associations.rb
         
     | 
| 
      
 97 
     | 
    
         
            +
            - lib/generators/devise_invitations/routes/templates/routes.rb
         
     | 
| 
      
 98 
     | 
    
         
            +
            - lib/generators/devise_invitations/specs/.DS_Store
         
     | 
| 
      
 99 
     | 
    
         
            +
            - lib/generators/devise_invitations/specs/templates/association.rb
         
     | 
| 
      
 100 
     | 
    
         
            +
            - lib/generators/devise_invitations/specs/templates/controller.rb
         
     | 
| 
      
 101 
     | 
    
         
            +
            - lib/generators/devise_invitations/specs/templates/factory.rb
         
     | 
| 
      
 102 
     | 
    
         
            +
            - lib/generators/devise_invitations/specs/templates/model.rb
         
     | 
| 
      
 103 
     | 
    
         
            +
            - lib/generators/devise_invitations/specs_generator.rb
         
     | 
| 
      
 104 
     | 
    
         
            +
            - magic.sh
         
     | 
| 
      
 105 
     | 
    
         
            +
            homepage: https://github.com/RoxasShadow/devise_invitations
         
     | 
| 
      
 106 
     | 
    
         
            +
            licenses:
         
     | 
| 
      
 107 
     | 
    
         
            +
            - BSD-2-Clause
         
     | 
| 
      
 108 
     | 
    
         
            +
            metadata: {}
         
     | 
| 
      
 109 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 110 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 111 
     | 
    
         
            +
            require_paths:
         
     | 
| 
      
 112 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 113 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 114 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 115 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 116 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 117 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 118 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         
     | 
| 
      
 119 
     | 
    
         
            +
              requirements:
         
     | 
| 
      
 120 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 121 
     | 
    
         
            +
                - !ruby/object:Gem::Version
         
     | 
| 
      
 122 
     | 
    
         
            +
                  version: '0'
         
     | 
| 
      
 123 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 124 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 125 
     | 
    
         
            +
            rubygems_version: 2.5.1
         
     | 
| 
      
 126 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 127 
     | 
    
         
            +
            specification_version: 4
         
     | 
| 
      
 128 
     | 
    
         
            +
            summary: Allow multiple invitations on top of devise_invitable
         
     | 
| 
      
 129 
     | 
    
         
            +
            test_files: []
         
     |