diff --git a/Gemfile b/Gemfile
index bf2549e36db20c991a787caf7df06bf03a6d9356..60610a767c844961814add11e95f85f14785dd28 100644
--- a/Gemfile
+++ b/Gemfile
@@ -179,4 +179,4 @@ gem 'acts_as_list'
 
 gem 'faraday-net_http_persistent', '~> 2.0'
 
-gem 'elasticsearch'
+gem 'elasticsearch', '< 7.14'
diff --git a/Gemfile.lock b/Gemfile.lock
index fa48df2baec286a61ab54c658765c27dc9372390..1b2095412db1cce0a600cfd3520d218f763587cd 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -12,101 +12,107 @@ GIT
 
 GIT
   remote: https://github.com/kreeti/kt-paperclip.git
-  revision: ab1016d77336a8d7b9db72eb29b6bd19af4027fc
+  revision: 7f73b7442743f57fb957b4bb54c1bca11ddd1c72
   branch: master
   specs:
-    kt-paperclip (6.4.1)
+    kt-paperclip (7.1.1)
       activemodel (>= 4.2.0)
       activesupport (>= 4.2.0)
+      marcel (~> 1.0.1)
       mime-types
-      mimemagic (~> 0.3.0)
       terrapin (~> 0.6.0)
 
 GIT
   remote: https://github.com/lynndylanhurley/devise_token_auth.git
-  revision: 4c5245b88b39c1bb305e0cbdbfc2513eebdeda93
+  revision: 8f44a8c66fd772b2d33be4ba187c0b1a47caba2a
   branch: master
   specs:
     devise_token_auth (1.2.0)
       bcrypt (~> 3.0)
       devise (> 3.5.2, < 5)
-      rails (>= 4.2.0, < 6.2)
+      rails (>= 4.2.0, < 7.1)
 
 GEM
   remote: https://rubygems.org/
   specs:
-    actioncable (6.1.4)
-      actionpack (= 6.1.4)
-      activesupport (= 6.1.4)
+    actioncable (7.0.3)
+      actionpack (= 7.0.3)
+      activesupport (= 7.0.3)
       nio4r (~> 2.0)
       websocket-driver (>= 0.6.1)
-    actionmailbox (6.1.4)
-      actionpack (= 6.1.4)
-      activejob (= 6.1.4)
-      activerecord (= 6.1.4)
-      activestorage (= 6.1.4)
-      activesupport (= 6.1.4)
+    actionmailbox (7.0.3)
+      actionpack (= 7.0.3)
+      activejob (= 7.0.3)
+      activerecord (= 7.0.3)
+      activestorage (= 7.0.3)
+      activesupport (= 7.0.3)
       mail (>= 2.7.1)
-    actionmailer (6.1.4)
-      actionpack (= 6.1.4)
-      actionview (= 6.1.4)
-      activejob (= 6.1.4)
-      activesupport (= 6.1.4)
+      net-imap
+      net-pop
+      net-smtp
+    actionmailer (7.0.3)
+      actionpack (= 7.0.3)
+      actionview (= 7.0.3)
+      activejob (= 7.0.3)
+      activesupport (= 7.0.3)
       mail (~> 2.5, >= 2.5.4)
+      net-imap
+      net-pop
+      net-smtp
       rails-dom-testing (~> 2.0)
-    actionpack (6.1.4)
-      actionview (= 6.1.4)
-      activesupport (= 6.1.4)
-      rack (~> 2.0, >= 2.0.9)
+    actionpack (7.0.3)
+      actionview (= 7.0.3)
+      activesupport (= 7.0.3)
+      rack (~> 2.0, >= 2.2.0)
       rack-test (>= 0.6.3)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.2.0)
-    actiontext (6.1.4)
-      actionpack (= 6.1.4)
-      activerecord (= 6.1.4)
-      activestorage (= 6.1.4)
-      activesupport (= 6.1.4)
+    actiontext (7.0.3)
+      actionpack (= 7.0.3)
+      activerecord (= 7.0.3)
+      activestorage (= 7.0.3)
+      activesupport (= 7.0.3)
+      globalid (>= 0.6.0)
       nokogiri (>= 1.8.5)
-    actionview (6.1.4)
-      activesupport (= 6.1.4)
+    actionview (7.0.3)
+      activesupport (= 7.0.3)
       builder (~> 3.1)
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.1, >= 1.2.0)
-    active_model_serializers (0.10.12)
-      actionpack (>= 4.1, < 6.2)
-      activemodel (>= 4.1, < 6.2)
+    active_model_serializers (0.10.13)
+      actionpack (>= 4.1, < 7.1)
+      activemodel (>= 4.1, < 7.1)
       case_transform (>= 0.2)
       jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
-    activejob (6.1.4)
-      activesupport (= 6.1.4)
+    activejob (7.0.3)
+      activesupport (= 7.0.3)
       globalid (>= 0.3.6)
-    activemodel (6.1.4)
-      activesupport (= 6.1.4)
-    activerecord (6.1.4)
-      activemodel (= 6.1.4)
-      activesupport (= 6.1.4)
-    activerecord-import (1.1.0)
-      activerecord (>= 3.2)
-    activestorage (6.1.4)
-      actionpack (= 6.1.4)
-      activejob (= 6.1.4)
-      activerecord (= 6.1.4)
-      activesupport (= 6.1.4)
-      marcel (~> 1.0.0)
+    activemodel (7.0.3)
+      activesupport (= 7.0.3)
+    activerecord (7.0.3)
+      activemodel (= 7.0.3)
+      activesupport (= 7.0.3)
+    activerecord-import (1.4.0)
+      activerecord (>= 4.2)
+    activestorage (7.0.3)
+      actionpack (= 7.0.3)
+      activejob (= 7.0.3)
+      activerecord (= 7.0.3)
+      activesupport (= 7.0.3)
+      marcel (~> 1.0)
       mini_mime (>= 1.1.0)
-    activesupport (6.1.4)
+    activesupport (7.0.3)
       concurrent-ruby (~> 1.0, >= 1.0.2)
       i18n (>= 1.6, < 2)
       minitest (>= 5.1)
       tzinfo (~> 2.0)
-      zeitwerk (~> 2.3)
     acts_as_list (1.0.4)
       activerecord (>= 4.2)
-    addressable (2.7.0)
+    addressable (2.8.0)
       public_suffix (>= 2.0.2, < 5.0)
-    annotate (3.1.1)
-      activerecord (>= 3.2, < 7.0)
+    annotate (3.2.0)
+      activerecord (>= 3.2, < 8.0)
       rake (>= 10.4, < 14.0)
     ansi (1.5.0)
     ast (2.4.2)
@@ -114,16 +120,16 @@ GEM
       descendants_tracker (~> 0.0.4)
       ice_nine (~> 0.11.0)
       thread_safe (~> 0.3, >= 0.3.1)
-    bcrypt (3.1.16)
-    benchmark-ips (2.9.1)
+    bcrypt (3.1.18)
+    benchmark-ips (2.10.0)
     better_errors (2.8.3)
       coderay (>= 1.0.0)
       erubi (>= 1.0.0)
       rack (>= 0.9.0)
     bindex (0.8.1)
-    brakeman (5.0.1)
+    brakeman (5.2.3)
     builder (3.2.4)
-    bullet (6.1.4)
+    bullet (7.0.2)
       activesupport (>= 3.0.0)
       uniform_notifier (~> 1.11)
     byebug (11.1.3)
@@ -135,12 +141,12 @@ GEM
     coderay (1.1.3)
     coercible (1.0.0)
       descendants_tracker (~> 0.0.1)
-    concurrent-ruby (1.1.9)
+    concurrent-ruby (1.1.10)
     connection_pool (2.2.5)
     crass (1.0.6)
-    curb (0.9.11)
+    curb (1.0.1)
     cvss (0.99.0)
-    dalli (2.7.11)
+    dalli (3.2.2)
     database_cleaner (2.0.1)
       database_cleaner-active_record (~> 2.0.0)
     database_cleaner-active_record (2.0.1)
@@ -157,8 +163,8 @@ GEM
       sqlite3
       sys-uname
       terminal-table
-    dead_end (1.1.7)
-    derailed_benchmarks (2.1.0)
+    dead_end (4.0.0)
+    derailed_benchmarks (2.1.1)
       benchmark-ips (~> 2)
       dead_end
       get_process_mem (~> 0)
@@ -172,254 +178,282 @@ GEM
       thor (>= 0.19, < 2)
     descendants_tracker (0.0.4)
       thread_safe (~> 0.3, >= 0.3.1)
-    devise (4.8.0)
+    devise (4.8.1)
       bcrypt (~> 3.0)
       orm_adapter (~> 0.1)
       railties (>= 4.1.0)
       responders
       warden (~> 1.2.3)
-    diff-lcs (1.4.4)
+    diff-lcs (1.5.0)
+    digest (3.1.0)
     docile (1.4.0)
-    elasticsearch (7.13.0)
-      elasticsearch-api (= 7.13.0)
-      elasticsearch-transport (= 7.13.0)
-    elasticsearch-api (7.13.0)
+    elasticsearch (7.13.3)
+      elasticsearch-api (= 7.13.3)
+      elasticsearch-transport (= 7.13.3)
+    elasticsearch-api (7.13.3)
       multi_json
-    elasticsearch-transport (7.13.0)
+    elasticsearch-transport (7.13.3)
       faraday (~> 1)
       multi_json
     equalizer (0.0.11)
     erubi (1.10.0)
-    erubis (2.7.0)
     execjs (2.8.1)
-    factory_bot (6.2.0)
+    factory_bot (6.2.1)
       activesupport (>= 5.0.0)
     factory_bot_rails (6.2.0)
       factory_bot (~> 6.2.0)
       railties (>= 5.0.0)
-    faker (2.18.0)
-      i18n (>= 1.6, < 2)
-    faraday (1.4.2)
+    faker (2.21.0)
+      i18n (>= 1.8.11, < 2)
+    faraday (1.9.0)
       faraday-em_http (~> 1.0)
       faraday-em_synchrony (~> 1.0)
       faraday-excon (~> 1.1)
-      faraday-net_http (~> 1.0)
-      faraday-net_http_persistent (~> 1.1)
-      multipart-post (>= 1.2, < 3)
+      faraday-httpclient (< 3)
+      faraday-multipart (~> 1.0)
+      faraday-net_http (< 3)
+      faraday-net_http_persistent (< 3)
+      faraday-patron (< 3)
+      faraday-rack (~> 1.0)
+      faraday-retry (~> 1.0)
       ruby2_keywords (>= 0.0.4)
     faraday-em_http (1.0.0)
     faraday-em_synchrony (1.0.0)
     faraday-excon (1.1.0)
-    faraday-net_http (1.0.1)
-    faraday-net_http_persistent (1.1.0)
+    faraday-httpclient (2.0.1)
+      httpclient (>= 2.2)
+    faraday-multipart (1.0.4)
+      multipart-post (~> 2)
+    faraday-net_http (2.0.3)
+    faraday-net_http_persistent (2.0.1)
+      faraday-net_http
+      net-http-persistent (~> 4.0)
+    faraday-patron (2.0.1)
+      patron (>= 0.4.2)
+    faraday-rack (1.0.0)
+    faraday-retry (1.0.3)
     feature (1.4.0)
-    ffi (1.15.1)
-    ffi-libarchive (1.0.17)
+    ffi (1.15.5)
+    ffi-libarchive (1.1.3)
       ffi (~> 1.0)
     flamegraph (0.9.5)
-    flay (2.12.1)
-      erubis (~> 2.7.0)
+    flay (2.13.0)
+      erubi (~> 1.10)
       path_expander (~> 1.0)
       ruby_parser (~> 3.0)
       sexp_processor (~> 4.0)
-    flog (4.6.4)
+    flog (4.6.5)
       path_expander (~> 1.0)
       ruby_parser (~> 3.1, > 3.1.0)
       sexp_processor (~> 4.8)
     get_process_mem (0.2.7)
       ffi (~> 1.0)
-    gitlab (4.17.0)
+    gitlab (4.18.0)
       httparty (~> 0.18)
-      terminal-table (~> 1.5, >= 1.5.1)
-    globalid (0.5.1)
+      terminal-table (>= 1.5.1)
+    globalid (1.0.0)
       activesupport (>= 5.0)
-    haml (5.2.1)
+    haml (5.2.2)
       temple (>= 0.8.0)
       tilt
-    hashie (4.1.0)
+    hashie (5.0.0)
     heapy (0.2.0)
       thor
-    httparty (0.18.1)
+    httparty (0.20.0)
       mime-types (~> 3.0)
       multi_xml (>= 0.5.2)
-    i18n (1.8.10)
+    httpclient (2.8.3)
+    i18n (1.10.0)
       concurrent-ruby (~> 1.0)
     ice_nine (0.11.2)
     immigrant (0.3.6)
       activerecord (>= 3.0)
-    json (2.5.1)
+    json (2.6.2)
     jsonapi-renderer (0.2.2)
     justify (1.0.2)
-    jwt (2.2.3)
+    jwt (2.4.1)
     kwalify (0.7.2)
     launchy (2.5.0)
       addressable (~> 2.7)
     logger-colors (1.0.0)
-    loofah (2.10.0)
+    loofah (2.18.0)
       crass (~> 1.0.2)
       nokogiri (>= 1.5.9)
     mail (2.7.1)
       mini_mime (>= 0.1.1)
-    marcel (1.0.1)
+    marcel (1.0.2)
     memory_profiler (1.0.0)
     method_source (1.0.0)
-    mime-types (3.3.1)
+    mime-types (3.4.1)
       mime-types-data (~> 3.2015)
-    mime-types-data (3.2021.0225)
-    mimemagic (0.3.10)
+    mime-types-data (3.2022.0105)
+    mimemagic (0.4.3)
       nokogiri (~> 1)
       rake
-    mina (1.2.3)
+    mina (1.2.4)
       open4 (~> 1.3.4)
       rake
     mini_histogram (0.3.1)
-    mini_mime (1.1.0)
-    mini_portile2 (2.5.3)
-    minitest (5.14.4)
-    minitest-reporters (1.4.3)
+    mini_mime (1.1.2)
+    minitest (5.16.1)
+    minitest-reporters (1.5.0)
       ansi
       builder
       minitest (>= 5.0)
       ruby-progressbar
     multi_json (1.15.0)
     multi_xml (0.6.0)
-    multipart-post (2.1.1)
+    multipart-post (2.2.3)
     mustache (1.1.1)
     mustermann (1.1.1)
       ruby2_keywords (~> 0.0.1)
     net-http-persistent (4.0.1)
       connection_pool (~> 2.2)
-    nio4r (2.5.7)
-    nokogiri (1.11.7)
-      mini_portile2 (~> 2.5.0)
+    net-imap (0.2.3)
+      digest
+      net-protocol
+      strscan
+    net-pop (0.1.1)
+      digest
+      net-protocol
+      timeout
+    net-protocol (0.1.3)
+      timeout
+    net-smtp (0.3.1)
+      digest
+      net-protocol
+      timeout
+    nio4r (2.5.8)
+    nokogiri (1.13.6-x86_64-linux)
       racc (~> 1.4)
-    oauth (0.5.6)
-    oauth2 (1.4.7)
-      faraday (>= 0.8, < 2.0)
+    oauth (0.5.10)
+    oauth2 (1.4.9)
+      faraday (>= 0.17.3, < 3.0)
       jwt (>= 1.0, < 3.0)
       multi_json (~> 1.3)
       multi_xml (~> 0.5)
       rack (>= 1.2, < 3)
-    omniauth (2.0.4)
+    omniauth (1.9.1)
       hashie (>= 3.4.6)
       rack (>= 1.6.2, < 3)
-      rack-protection
-    omniauth-facebook (8.0.0)
+    omniauth-facebook (9.0.0)
       omniauth-oauth2 (~> 1.2)
-    omniauth-google-oauth2 (1.0.0)
+    omniauth-google-oauth2 (0.8.2)
       jwt (>= 2.0)
       oauth2 (~> 1.1)
-      omniauth (~> 2.0)
-      omniauth-oauth2 (~> 1.7.1)
+      omniauth (~> 1.1)
+      omniauth-oauth2 (>= 1.6)
     omniauth-oauth (1.2.0)
       oauth
       omniauth (>= 1.0, < 3)
-    omniauth-oauth2 (1.7.1)
-      oauth2 (~> 1.4)
+    omniauth-oauth2 (1.7.3)
+      oauth2 (>= 1.4, < 3)
       omniauth (>= 1.9, < 3)
     omniauth-twitter (1.4.0)
       omniauth-oauth (~> 1.1)
       rack
     open4 (1.3.4)
     orm_adapter (0.5.0)
-    paper_trail (12.0.0)
+    paper_trail (12.3.0)
       activerecord (>= 5.2)
       request_store (~> 1.1)
-    parallel (1.20.1)
-    paranoia (2.4.3)
-      activerecord (>= 4.0, < 6.2)
-    parser (3.0.1.1)
+    parallel (1.22.1)
+    paranoia (2.6.0)
+      activerecord (>= 5.1, < 7.1)
+    parser (3.1.2.0)
       ast (~> 2.4.1)
     path_expander (1.1.0)
-    pg (1.2.3)
+    patron (0.13.3)
+    pg (1.4.1)
     phantomjs (2.1.1.0)
-    psych (3.3.2)
+    psych (4.0.4)
+      stringio
     ptools (1.4.2)
-    public_activity (1.6.4)
-      actionpack (>= 3.0.0)
-      activerecord (>= 3.0)
+    public_activity (2.0.1)
+      actionpack (>= 5.0.0)
+      activerecord (>= 5.0)
       i18n (>= 0.5.0)
-      railties (>= 3.0.0)
-    public_suffix (4.0.6)
-    puma (5.3.2)
+      railties (>= 5.0.0)
+    public_suffix (4.0.7)
+    puma (5.6.4)
       nio4r (~> 2.0)
-    pundit (2.1.0)
+    pundit (2.2.0)
       activesupport (>= 3.0.0)
-    racc (1.5.2)
-    rack (2.2.3)
-    rack-attack (6.5.0)
+    racc (1.6.0)
+    rack (2.2.3.1)
+    rack-attack (6.6.1)
       rack (>= 1.0, < 3)
     rack-cors (1.1.1)
       rack (>= 2.0.0)
-    rack-mini-profiler (2.3.2)
+    rack-mini-profiler (3.0.0)
       rack (>= 1.2.0)
-    rack-protection (2.1.0)
+    rack-protection (2.2.0)
       rack
-    rack-test (1.1.0)
-      rack (>= 1.0, < 3)
-    rails (6.1.4)
-      actioncable (= 6.1.4)
-      actionmailbox (= 6.1.4)
-      actionmailer (= 6.1.4)
-      actionpack (= 6.1.4)
-      actiontext (= 6.1.4)
-      actionview (= 6.1.4)
-      activejob (= 6.1.4)
-      activemodel (= 6.1.4)
-      activerecord (= 6.1.4)
-      activestorage (= 6.1.4)
-      activesupport (= 6.1.4)
+    rack-test (2.0.1)
+      rack (>= 1.3)
+    rails (7.0.3)
+      actioncable (= 7.0.3)
+      actionmailbox (= 7.0.3)
+      actionmailer (= 7.0.3)
+      actionpack (= 7.0.3)
+      actiontext (= 7.0.3)
+      actionview (= 7.0.3)
+      activejob (= 7.0.3)
+      activemodel (= 7.0.3)
+      activerecord (= 7.0.3)
+      activestorage (= 7.0.3)
+      activesupport (= 7.0.3)
       bundler (>= 1.15.0)
-      railties (= 6.1.4)
-      sprockets-rails (>= 2.0.0)
+      railties (= 7.0.3)
     rails-dom-testing (2.0.3)
       activesupport (>= 4.2.0)
       nokogiri (>= 1.6)
-    rails-erd (1.6.1)
+    rails-erd (1.7.1)
       activerecord (>= 4.2)
       activesupport (>= 4.2)
       choice (~> 0.2.0)
       ruby-graphviz (~> 1.2)
-    rails-html-sanitizer (1.3.0)
+    rails-html-sanitizer (1.4.3)
       loofah (~> 2.3)
-    railties (6.1.4)
-      actionpack (= 6.1.4)
-      activesupport (= 6.1.4)
+    railties (7.0.3)
+      actionpack (= 7.0.3)
+      activesupport (= 7.0.3)
       method_source
-      rake (>= 0.13)
+      rake (>= 12.2)
       thor (~> 1.0)
-    rainbow (3.0.0)
+      zeitwerk (~> 2.5)
+    rainbow (3.1.1)
     rake (13.0.6)
-    rdoc (6.3.1)
-    redis (4.2.5)
-    reek (6.0.4)
+    rdoc (6.4.0)
+      psych (>= 4.0.0)
+    redis (4.7.0)
+    reek (6.1.1)
       kwalify (~> 0.7.0)
-      parser (~> 3.0.0)
-      psych (~> 3.1)
+      parser (~> 3.1.0)
       rainbow (>= 2.0, < 4.0)
-    regexp_parser (2.1.1)
-    request_store (1.5.0)
+    regexp_parser (2.5.0)
+    request_store (1.5.1)
       rack (>= 1.4)
-    resource_kit (0.1.7)
+    resource_kit (0.1.8)
       addressable (>= 2.3.6, < 3.0.0)
     responders (3.0.1)
       actionpack (>= 5.0)
       railties (>= 5.0)
     rexml (3.2.5)
-    rmagick (4.2.2)
-    rspec (3.10.0)
-      rspec-core (~> 3.10.0)
-      rspec-expectations (~> 3.10.0)
-      rspec-mocks (~> 3.10.0)
-    rspec-core (3.10.1)
-      rspec-support (~> 3.10.0)
-    rspec-expectations (3.10.1)
+    rmagick (4.2.5)
+    rspec (3.11.0)
+      rspec-core (~> 3.11.0)
+      rspec-expectations (~> 3.11.0)
+      rspec-mocks (~> 3.11.0)
+    rspec-core (3.11.0)
+      rspec-support (~> 3.11.0)
+    rspec-expectations (3.11.0)
       diff-lcs (>= 1.2.0, < 2.0)
-      rspec-support (~> 3.10.0)
-    rspec-mocks (3.10.2)
+      rspec-support (~> 3.11.0)
+    rspec-mocks (3.11.1)
       diff-lcs (>= 1.2.0, < 2.0)
-      rspec-support (~> 3.10.0)
-    rspec-rails (5.0.1)
+      rspec-support (~> 3.11.0)
+    rspec-rails (5.1.2)
       actionpack (>= 5.2)
       activesupport (>= 5.2)
       railties (>= 5.2)
@@ -427,30 +461,30 @@ GEM
       rspec-expectations (~> 3.10)
       rspec-mocks (~> 3.10)
       rspec-support (~> 3.10)
-    rspec-support (3.10.2)
+    rspec-support (3.11.0)
     rspec_api_documentation (6.1.0)
       activesupport (>= 3.0.0)
       mustache (~> 1.0, >= 0.99.4)
       rspec (~> 3.0)
-    rubocop (1.15.0)
+    rubocop (1.31.0)
       parallel (~> 1.10)
-      parser (>= 3.0.0.0)
+      parser (>= 3.1.0.0)
       rainbow (>= 2.2.2, < 4.0)
       regexp_parser (>= 1.8, < 3.0)
-      rexml
-      rubocop-ast (>= 1.5.0, < 2.0)
+      rexml (>= 3.2.5, < 4.0)
+      rubocop-ast (>= 1.18.0, < 2.0)
       ruby-progressbar (~> 1.7)
       unicode-display_width (>= 1.4.0, < 3.0)
-    rubocop-ast (1.6.0)
-      parser (>= 3.0.1.1)
+    rubocop-ast (1.18.0)
+      parser (>= 3.1.1.0)
     ruby-graphviz (1.2.5)
       rexml
     ruby-progressbar (1.11.0)
-    ruby-statistics (2.1.3)
-    ruby2_keywords (0.0.4)
-    ruby_parser (3.16.0)
-      sexp_processor (~> 4.15, >= 4.15.1)
-    rubycritic (4.6.1)
+    ruby-statistics (3.0.0)
+    ruby2_keywords (0.0.5)
+    ruby_parser (3.19.1)
+      sexp_processor (~> 4.16)
+    rubycritic (4.7.0)
       flay (~> 2.8)
       flog (~> 4.4)
       launchy (>= 2.0.0)
@@ -461,23 +495,22 @@ GEM
       simplecov (>= 0.17.0)
       tty-which (~> 0.4.0)
       virtus (~> 1.0)
-    rubyzip (2.3.0)
+    rubyzip (2.3.2)
     screencap (0.1.4)
       phantomjs
-    sdoc (2.2.0)
+    sdoc (2.4.0)
       rdoc (>= 5.0)
-    searchkick (4.4.4)
-      activemodel (>= 5)
-      elasticsearch (>= 6)
+    searchkick (5.0.4)
+      activemodel (>= 5.2)
       hashie
-    sexp_processor (4.15.3)
+    sexp_processor (4.16.1)
     shoulda (4.0.0)
       shoulda-context (~> 2.0)
       shoulda-matchers (~> 4.0)
     shoulda-context (2.0.0)
     shoulda-matchers (4.5.1)
       activesupport (>= 4.2.0)
-    sidekiq (6.2.1)
+    sidekiq (6.5.1)
       connection_pool (>= 2.2.2)
       rack (~> 2.0)
       redis (>= 4.2.0)
@@ -486,41 +519,38 @@ GEM
       simplecov-html (~> 0.11)
       simplecov_json_formatter (~> 0.1)
     simplecov-html (0.12.3)
-    simplecov_json_formatter (0.1.3)
-    sinatra (2.1.0)
+    simplecov_json_formatter (0.1.4)
+    sinatra (2.2.0)
       mustermann (~> 1.0)
       rack (~> 2.2)
-      rack-protection (= 2.1.0)
+      rack-protection (= 2.2.0)
       tilt (~> 2.0)
     slim (4.1.0)
       temple (>= 0.7.6, < 0.9)
       tilt (>= 2.0.6, < 2.1)
-    spring (2.1.1)
-    sprockets (4.0.2)
-      concurrent-ruby (~> 1.0)
-      rack (> 1, < 3)
-    sprockets-rails (3.2.2)
-      actionpack (>= 4.0)
-      activesupport (>= 4.0)
-      sprockets (>= 3.0.0)
-    sqlite3 (1.4.2)
-    stackprof (0.2.17)
+    spring (4.0.0)
+    sqlite3 (1.4.4)
+    stackprof (0.2.19)
     streamio-ffmpeg (3.0.2)
       multi_json (~> 1.8)
+    stringio (3.0.2)
+    strscan (3.0.3)
     sys-uname (1.2.2)
       ffi (~> 1.1)
     temple (0.8.2)
-    terminal-table (1.6.0)
+    terminal-table (3.0.2)
+      unicode-display_width (>= 1.1.1, < 3)
     terrapin (0.6.0)
       climate_control (>= 0.0.3, < 1.0)
-    thor (1.1.0)
+    thor (1.2.1)
     thread_safe (0.3.6)
     tilt (2.0.10)
+    timeout (0.3.0)
     tty-which (0.4.2)
     tzinfo (2.0.4)
       concurrent-ruby (~> 1.0)
-    unicode-display_width (2.0.0)
-    uniform_notifier (1.14.2)
+    unicode-display_width (2.2.0)
+    uniform_notifier (1.16.0)
     virtus (1.0.5)
       axiom-types (~> 0.1)
       coercible (~> 1.0)
@@ -538,10 +568,10 @@ GEM
     websocket-extensions (0.1.5)
     whenever (1.0.0)
       chronic (>= 0.6.3)
-    zeitwerk (2.4.2)
+    zeitwerk (2.6.0)
 
 PLATFORMS
-  ruby
+  x86_64-linux
 
 DEPENDENCIES
   active_model_serializers
@@ -562,9 +592,12 @@ DEPENDENCIES
   devise
   devise_token_auth!
   dspace_rest_client!
+  elasticsearch (< 7.14)
   execjs
   factory_bot_rails
   faker
+  faraday
+  faraday-net_http_persistent (~> 2.0)
   feature
   ffi-libarchive
   flamegraph
@@ -574,8 +607,9 @@ DEPENDENCIES
   mimemagic
   mina
   minitest-reporters
+  net-http-persistent
   omniauth-facebook
-  omniauth-google-oauth2
+  omniauth-google-oauth2 (= 0.8.2)
   omniauth-twitter
   paper_trail
   paranoia
@@ -610,4 +644,4 @@ DEPENDENCIES
   whenever
 
 BUNDLED WITH
-   2.2.15
+   2.3.15
diff --git a/app/controllers/concerns/paginator.rb b/app/controllers/concerns/paginator.rb
index af015ff08cf386bb3a8a6fff7f96e8a8567cfe90..b921923444853fb9fe9a87942eaddc62fa404f39 100644
--- a/app/controllers/concerns/paginator.rb
+++ b/app/controllers/concerns/paginator.rb
@@ -27,6 +27,12 @@ module Paginator
     return model[offset..limit]
   end
 
+  #return paginate for select queries
+  def paginate_select(model, total)
+    total_count_select total
+    return model
+  end
+  
   private
 
     def limit
@@ -66,5 +72,8 @@ module Paginator
     def total_count(model)
       headers['X-Total-Count'] = model.count
     end
-
+    
+    def total_count_select(total)
+      headers['X-Total-Count'] = total
+    end
 end
diff --git a/app/controllers/v1/complaint_votes_controller.rb b/app/controllers/v1/complaint_votes_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..af971d16e881423b7631fba62d20653d5c0b4efd
--- /dev/null
+++ b/app/controllers/v1/complaint_votes_controller.rb
@@ -0,0 +1,112 @@
+
+# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre
+# Departamento de Informatica - Universidade Federal do Parana
+#
+# This file is part of portalmec.
+#
+# portalmec is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# portalmec is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
+
+class V1::ComplaintVotesController < ApplicationController
+    include ::DeletedObjectsController
+    include ::Paginator
+    before_action :set_complaint_vote, only: [:show, :update, :destroy]
+
+    # GET /v1/complaint_votes
+    def index
+        complaint_votes = paginate ComplaintVote
+        render json: complaint_votes
+    end
+
+    # GET /v1/complaint_votes/{id}
+    def show
+        render json: @complaint_vote
+    end
+
+    # POST /v1/complaint_votes
+    def create
+        @complaint_vote = ComplaintVote.new(complaint_vote_params)
+
+        if @complaint_vote.save
+            render json: @complaint_vote, status: :created
+        else
+            render json: @complaint_vote.errors, status: :unprocessable_entity
+        end
+        
+        verify_votes(@complaint_vote)
+    end
+
+    # Set the params required for creating a complaint vote
+    def complaint_vote_params
+        params.require(:complaint_vote).permit(:complainable_type, :complainable_id, :pros, :cons, :user_id)
+    end
+
+    # PUT/PATCH /v1/complaint_votes/{id}
+    def update
+        if @complaint_vote.update(complaint_vote_params)
+            render json: @complaint_vote
+        else 
+            render json: @complaint_vote.errors, status: :unprocessable_entity
+        end
+    end
+
+    # DELETE /v1/complaint_votes/{id}
+    def destroy
+        @complaint_vote.destroy
+        response = { 'status': 'deleted' }
+        render status: :ok, json: response
+    end
+
+    def set_complaint_vote
+        # @complaint_vote = ComplaintVote.where(id: params[:id]).first
+        
+        # render status: :not_found if @complaint_vote.blank?
+        
+        # @complaint_vote
+
+        @complaint_vote ||= ComplaintVote.find_by_id(params[:id]).first
+        if @complaint_vote.blank?
+            render status: :not_found
+        end
+    end
+    
+    # if the difference between the pros and cons votes is more than 2, destroy the learning object  
+    def verify_votes(complaint_vote)
+
+        data = ComplaintVote.select("complainable_id, sum(pros) as pros, sum(cons) as cons")
+                            .where("complainable_id = ?", complaint_vote.complainable_id)
+                            .group("complaint_votes.complainable_id")
+
+        data.each do |d|
+            if (d.complainable_id == complaint_vote.complainable_id)
+                if d.pros - d.cons > 2
+                    ComplaintVote.where("complainable_id = ?", complaint_vote.complainable_id).destroy_all
+                    Complaint.where("complainable_id = ?", complaint_vote.complainable_id).destroy_all
+                    LearningObject.where(id: complaint_vote.complainable_id).update_all(deleted_at: Time.now)
+                    #Complaint.find_by_complainable_id(complaint_vote.complainable_id).update(state: 2)
+                    #Complaint.find_by_complainable_id(complaint_vote.complainable_id).destroy
+                    #ComplaintVote.find_by_complainable_id(complaint_vote.complainable_id).destroy
+                    #LearningObject.find_by_id(complaint_vote.complainable_id).destroy
+                    # puts "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"
+                    # puts "  pros maior que cons, pros = #{d.pros}, cons = #{d.cons}"
+                    # puts "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-"
+                elsif d.cons - d.pros > 2
+                    ComplaintVote.where("complainable_id = ?", complaint_vote.complainable_id).destroy_all
+                    Complaint.where("complainable_id = ?", complaint_vote.complainable_id).update_all(state: Complaint.states[:rejected])
+                    LearningObject.where(id: complaint_vote.complainable_id).update_all(state: LearningObject.states[:published])
+                end
+            end
+        end
+    end
+
+end
diff --git a/app/controllers/v1/complaints_controller.rb b/app/controllers/v1/complaints_controller.rb
index 16ca72fb7b6d86e004583e37d557585772d0fa69..0931bbfb974e6ade913946f784e4aed7b57b02ca 100644
--- a/app/controllers/v1/complaints_controller.rb
+++ b/app/controllers/v1/complaints_controller.rb
@@ -54,7 +54,9 @@ class V1::ComplaintsController < ApplicationController
     if @complaint.save
       ComplaintsMailer.new_complaint_received(@complaint, @current_user).deliver_now
       
-      @complaint.complainable.treat_complaintment
+      if (Complaint.where(complainable_id: @complaint.complainable_id).count >= 2)
+        LearningObject.where(id: @complaint.complainable_id).update_all(state: LearningObject.states[:suspended])
+      end
       
       render json: @complaint, status: :created
     else
diff --git a/app/controllers/v1/contacts_controller.rb b/app/controllers/v1/contacts_controller.rb
index 8680c4914ad6367512f8f0cda24949b75c595d17..48ddb15586f19d42609892f395ba3e259c0c8f91 100644
--- a/app/controllers/v1/contacts_controller.rb
+++ b/app/controllers/v1/contacts_controller.rb
@@ -22,13 +22,13 @@ class V1::ContactsController < ApplicationController
 
   before_action :authenticate_user!, except: [:create]
   before_action :set_contact, only: [:show, :update, :destroy]
-	before_action :set_new_contact, only: :index
+    before_action :set_new_contact, only: :index
   before_action :authorize!, except: [:create]
 
   # GET v1/contacts
   def index
     contacts = paginate policy_scope(Contact)
-		render json: contacts
+        render json: contacts
   end
 
   # GET v1/contacts/1
@@ -82,8 +82,8 @@ class V1::ContactsController < ApplicationController
     def authorize!
       authorize @contact
     end
-
-		def set_new_contact
-			@contact ||= Contact.new
-		end
+    
+    def set_new_contact
+      @contact ||= Contact.new
+  end
 end
diff --git a/app/controllers/v1/learning_objects_complaints_controller.rb b/app/controllers/v1/learning_objects_complaints_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a44b8afe8be401703816537bd218fbd58520fc11
--- /dev/null
+++ b/app/controllers/v1/learning_objects_complaints_controller.rb
@@ -0,0 +1,107 @@
+class V1::LearningObjectsComplaintsController < ApplicationController
+
+    include ::DeletedObjectsController
+    include ::Paginator
+
+    # learning_object_complaints[i] = data of a complaint (always in even positions)
+    # learning_object_complaints[i+1] = image of learning_object, and user, also contains the tags of the object and the download link (always in odd positions)
+
+    def generate_priority_queue(complaints_priority)
+
+        complaints_curator = []
+        complaints_priority.each do |complainable|
+
+            # Select all complaints related to the complainable_id (attributes that have been sumed)
+            complaints_curator << ComplaintReason.joins("INNER JOIN complaints ON complaint_reasons.id = complaints.complaint_reason_id 
+                 INNER JOIN learning_objects on complaints.complainable_id = learning_objects.id
+                 INNER JOIN users ON learning_objects.publisher_id = users.id 
+                 INNER JOIN object_types ON learning_objects.object_type_id = object_types.id
+                 ")
+                .select("learning_objects.id as learning_object_id, learning_objects.name, learning_objects.review_average, 
+                    learning_objects.likes_count, users.name as publisher_name,
+                    object_types.name as type_object, complaints.description, complaint_reasons.id as complaint_reason_id, 
+                    complaint_reasons.reason, complaint_reasons.priority")
+                .where("complaints.complainable_id = ? AND complaints.state = 0", complainable.complainable_id).order("complaint_reasons.priority DESC")
+
+            #find the learning_object by the complainable_id
+            learning_object = LearningObject.where(id: complainable.complainable_id)
+            
+            lo_data = Hash.new
+
+            tags = Tagging.joins(:tag).where("taggings.taggable_id = ?", complainable.complainable_id).select("tags.name")
+            all_tags = []
+
+            #add all tags to lo_data hash
+            tags.each do |tag|
+                if (tag.name != nil)
+                    all_tags << tag.name
+                end
+            end
+
+            lo_data['tags'] = all_tags
+            
+            #iterate by all learning_objects found
+            for lo in learning_object
+                
+                lo_data['learning_object_thumb'] = lo.thumbnail
+                if (lo.publisher_id != nil) 
+                    user = User.where(id: lo.publisher_id).first
+                    lo_data['user_avatar'] = user.avatar
+                end
+                lo_data['download_link'] = lo.download_link
+
+            end
+
+            complaints_curator << lo_data
+        end
+        
+        return complaints_curator
+        
+    end
+
+    # GET v1/learning_objects_complaints
+    def index
+                
+        
+        #select and sum the priority if has two or more complaints
+        complaints_priority = ComplaintReason.joins(:complaints).select("complainable_id, SUM(complaint_reasons.priority) as priorities")
+        .where("complaints.state = 0").group("complainable_id").having("(COUNT(complainable_id) > 1 OR SUM(complaint_reasons.priority) > 20)")
+        .order("priorities DESC").order("complainable_id").limit(params["limit"]).offset(params["offset"])
+        
+        total = ComplaintReason.joins(:complaints).select("complainable_id, SUM(complaint_reasons.priority)")
+        .where("complaints.state = 0").group("complainable_id").having("COUNT(complainable_id) > 1 OR SUM(complaint_reasons.priority) > 20")
+
+        queue = generate_priority_queue(complaints_priority)
+        complaints_queue = paginate_select(queue, total.length)
+
+        render json: complaints_queue
+
+    end
+
+    # GET v1/learning_objects_complaints/queue_user/:user_id
+    def queue_user
+        #select and sum the priority if has two or more complaints
+        complaints_priority = ComplaintReason.joins(:complaints).select("complainable_id, SUM(complaint_reasons.priority) as priorities")
+        .where("complaints.state = 0").where.not("complaints.user_id = ?",params[:user_id]).group("complainable_id").having("(COUNT(complainable_id) > 1 OR SUM(complaint_reasons.priority) > 20)")
+        .order("priorities DESC").order("complainable_id").limit(params["limit"]).offset(params["offset"])
+        
+        total = ComplaintReason.joins(:complaints).select("complainable_id, SUM(complaint_reasons.priority)")
+        .where("complaints.state = 0").where.not("complaints.user_id = ?",params[:user_id]).group("complainable_id").having("COUNT(complainable_id) > 1 OR SUM(complaint_reasons.priority) > 20")
+
+        queue = generate_priority_queue(complaints_priority)
+        complaints_queue = paginate_select(queue, total.length)
+
+        render json: complaints_queue
+
+    end
+    
+    def show
+        id = params[:id]
+        complaints = ComplaintReason.joins("INNER JOIN complaints ON complaint_reasons.id = complaints.complaint_reason_id")
+        .where("complaints.complainable_id = ?",id)
+        .select("complaints.description, complaint_reasons.reason, complaint_reasons.priority")
+        render json: complaints
+    end
+
+end
+
diff --git a/app/controllers/v1/sessions_controller.rb b/app/controllers/v1/sessions_controller.rb
index 4f8004aedcbb2f8a124fc76e34db6963712717f9..dd672999832e3d94000dee943fd9e8f4dd081a73 100644
--- a/app/controllers/v1/sessions_controller.rb
+++ b/app/controllers/v1/sessions_controller.rb
@@ -19,48 +19,75 @@
 
 require 'open-uri'
   class V1::SessionsController < DeviseTokenAuth::SessionsController
+
+    #function to create a new session
     def create
-      # Check
-      field = (resource_params.keys.map(&:to_sym) & resource_class.authentication_keys).first
+      
+      #verify if the user exist and is active
+      if User.find_by_email(resource_params[:email]).present?
+        if User.find_by_email(resource_params[:email]).confirmed_at.present?
+          field = (resource_params.keys.map(&:to_sym) & resource_class.authentication_keys).first
+          @resource = nil
 
-      @resource = nil
-      if field
-        q_value = get_case_insensitive_field_from_resource_params(field)
+          if field
+            q_value = get_case_insensitive_field_from_resource_params(field)
 
-        @resource = find_resource(field, q_value)
-      end
+            @resource = find_resource(field, q_value)
+          end
 
-      if @resource && valid_params?(field, q_value) && (!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?)
-        valid_password = @resource.valid_password?(resource_params[:password])
-        if (@resource.respond_to?(:valid_for_authentication?) && !@resource.valid_for_authentication? { valid_password }) || !valid_password
-          return render_create_error_bad_credentials
-        end
-        @token = @resource.create_token
-        @resource.save
+          #verify the credentials
+          if @resource && valid_params?(field, q_value) && (!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?)
+            valid_password = @resource.valid_password?(resource_params[:password])
+            if (@resource.respond_to?(:valid_for_authentication?) && !@resource.valid_for_authentication? { valid_password }) || !valid_password
+              return render_create_error_bad_credentials
+            end
+
+            @token = @resource.create_token
+            @resource.save
+
+            sign_in(:user, @resource, store: false, bypass: false)
+
+            yield @resource if block_given?
 
-        sign_in(:user, @resource, store: false, bypass: false)
+            render_create_success
 
-        yield @resource if block_given?
+          elsif @resource && !(!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?)
+            # verify if user is to be reactivated
+            reactivate_user?
+            if @resource.blocked?
+              render_create_error_blocked
+            elsif @resource.banished?
+              render_create_error_banished
+            end
 
-        render_create_success
-      elsif @resource && !(!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?)
-        # verify if user is to be reactivated
-        reactivate_user?
-        if @resource.blocked?
-          render_create_error_blocked
-        elsif @resource.banished?
-          render_create_error_banished
+          else
+            render_create_error_bad_credentials
+          end
+      
+        #in case of the user is not confirmed, find the user and send an email confirmation
+        else
+          return render_create_error_not_confirmed
         end
-      else
-        render_create_error_bad_credentials
+
+      else  
+        return render_create_error_bad_credentials
       end
+
+    end
+
+    def render_create_error_not_confirmed
+      render json: {
+        success: false,
+        errors: [ I18n.t("devise.failure.unconfirmed")],
+      }, status: 417
+       
     end
 
     def render_create_error_banished
       render json: {
         success: false,
         errors: [ I18n.t("devise.sessions.banished")]
-      }, status: 401
+      }, status: 406
     end
 
     def render_create_error_blocked
@@ -68,7 +95,7 @@ require 'open-uri'
         success: false,
         errors: [ I18n.t("devise.sessions.blocked")],
         avaliable_at: @resource.reactivated_at
-      }, status: 401
+      }, status: 406
     end
         
     def reactivate_user?
diff --git a/app/controllers/v1/submissions_controller.rb b/app/controllers/v1/submissions_controller.rb
index 6e717db34bfc02c95fadfd127d277d715b41c61e..d38fb01dfa75cc069fb0a863a92fe98f4a245fe6 100644
--- a/app/controllers/v1/submissions_controller.rb
+++ b/app/controllers/v1/submissions_controller.rb
@@ -20,13 +20,16 @@
 class V1::SubmissionsController < ApplicationController
   include ::Paginator
 
-  before_action :set_new_submission, only: :index
-  before_action :set_submission, only: [:show, :answer, :destroy]
+  before_action :set_new_submission , only: :index
+  before_action :set_submission , only: [:show, :answer, :destroy]
   before_action :authenticate_user!
-  before_action :authorize!, except: :create
+  before_action :authorize!, except: [:create, :user_submissions, :all_users_submissions]
 
   def index
+    
+
     submissions = paginate Submission.all
+  
     render json: submissions
   end
 
@@ -34,6 +37,19 @@ class V1::SubmissionsController < ApplicationController
     render json: @submission
   end
 
+  def user_submissions
+    submission_user = Submission.where(submitter_id: params[:user_id]).where(status: 0)
+    all_submission_user = paginate submission_user
+    render json: all_submission_user
+  end
+  
+  def all_users_submissions
+    # show all submissions of all users without from the current user
+    submissions_users = Submission.where(status: 0).where.not(submitter_id: params[:user_id])
+    all_submissions_users = paginate submissions_users
+    render json: all_submissions_users
+  end
+
   def create
     learning_object = LearningObject.where(id: submission_params[:learning_object_id]).first
     if learning_object.blank?
@@ -72,10 +88,9 @@ class V1::SubmissionsController < ApplicationController
       end
       @submission.curator = current_user
       if @submission.save
-        if @submission.accepted?
-          publisher = LearningObjectPublisher.new(DspaceService.create_client)
-          publisher.publish @submission.learning_object
-        else
+        if @submission.accepted?def user_submissions
+          render status: :ok
+        end
           @submission.learning_object.destroy
         end
         render json: @submission, status: :ok
@@ -118,4 +133,5 @@ class V1::SubmissionsController < ApplicationController
   def authorize!
     authorize @submission
   end
+
 end
diff --git a/app/controllers/v1/unlocked_achievements_controller.rb b/app/controllers/v1/unlocked_achievements_controller.rb
index fd09b410adfe70547fe93f77552a8ed5e1d8621e..f3fe91ab1e98475c67bed892c6e6eb718d72f7a4 100644
--- a/app/controllers/v1/unlocked_achievements_controller.rb
+++ b/app/controllers/v1/unlocked_achievements_controller.rb
@@ -32,6 +32,15 @@ class V1::UnlockedAchievementsController < ApplicationController
     render json: @achievement
   end
 
+  # GET /v1/unlocked_achievements/user/:id
+  def show_specific
+
+    # search for a all unlocked_achievements of a specific user
+    un_achievement = paginate User.find_by_id(params[:user_id]).unlocked_achievements
+    render json: un_achievement
+    
+  end
+
   private
 
   def set_achievement
diff --git a/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb
index 138c45b5de824b2235d7544ca47c0c839174694c..d45e800378bbb4844e7e356775b9df979e6a0ba9 100644
--- a/app/controllers/v1/users_controller.rb
+++ b/app/controllers/v1/users_controller.rb
@@ -38,21 +38,30 @@ class V1::UsersController < ApplicationController
     # current_user completes an action
     # action counters and user progresses for achievements are updated,
     # and if an achievement was conquered its rewards are given
+    
     quantity = params[:quantity].to_i > 1 ? params[:quantity].to_i : 1
 
     success, response = current_user.complete_action(Action.where(id: params[:action_id]).first, quantity)
     status = success ? :ok : :unprocessable_entity
+    
 
     render json: response, status: status
   end
 
+  def confirm_email
+    @user = User.find_by_confirm_token(params[:id])
+    if @user
+      @user.email_activate
+    end
+  end
+  
   # POST /v1/users/purchase_item
   def purchase_item
     # purchases given item for current user
     item = Item.find_by(id: params[:item_id])
     user_item = UserItem.where(user: current_user, item: item).first
     if !user_item.blank?
-      render json: { "error": "You already own this item." }, status: :unprocessable_entity
+      render json: { "error": "Você já possui este item." }, status: :unprocessable_entity
     else
       if current_user.points >= item.price - item.discount
         current_user.points -= item.price - item.discount
@@ -63,7 +72,7 @@ class V1::UsersController < ApplicationController
           render json: current_user.user_items, status: :ok
         end
       else
-        render json: { "error": "You don't have the required points for this item." }, status: :unprocessable_entity
+        render json: { "error": "Você não possui gemas suficientes para esta compra." }, status: :unprocessable_entity
       end
     end
   end
@@ -97,7 +106,7 @@ class V1::UsersController < ApplicationController
 
   # GET /v1/users/action_counters
   def action_counters
-    # retorna action_counters e contagens correspondentes
+    # return action_counters and counters for given user
     render json: paginate(current_user.action_counters), status: :ok
   end
 
@@ -139,6 +148,7 @@ class V1::UsersController < ApplicationController
     authorize user
 
     if user.save
+      UserMailer.welcome_email(user).deliver_now
       render json: user, status: :created
     else
       render json: user.errors, status: :unprocessable_entity
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index 248a26994a93a14bafa79b6281ea82d335b71247..8f0e167ed6b1dafd0655a6054c1a6aea1c41a380 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -18,7 +18,7 @@
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
 class ApplicationMailer < ActionMailer::Base
-  default to: 'plataformaintegrada@mec.gov.br'
+  #default to: 'plataformaintegrada@mec.gov.br'
   default from: 'portalmec@inf.ufpr.br'
-  #layout 'mailer'
+  layout 'mailer'
 end
diff --git a/app/mailers/contacts_mailer.rb b/app/mailers/contacts_mailer.rb
index 35764830b3c05b3bc84b5f4cbd61fa2edcfb6141..385967ee17330fa74aa080b081494d0571a93f82 100644
--- a/app/mailers/contacts_mailer.rb
+++ b/app/mailers/contacts_mailer.rb
@@ -18,12 +18,12 @@
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
 class ContactsMailer < ApplicationMailer
-    default from: Proc.new { @contact.email }
+    default to: 'portalmec@inf.ufpr.br'
 
     def new_contact_received(contact)
         @contact = contact
         @subject = "Contato de " + @contact.name
-        mail(subject: @subject)
+        mail(from: @contact.email, subject: @subject)
     end
 
     def contact_updated(contact)
diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb
new file mode 100644
index 0000000000000000000000000000000000000000..1bb6cc43c39f90705ba99b9470f0e97d15d1e210
--- /dev/null
+++ b/app/mailers/user_mailer.rb
@@ -0,0 +1,18 @@
+class UserMailer < ActionMailer::Base
+
+    #set the default email sender
+    default from: 'portalmec_tec@inf.ufpr.br'
+
+    #function to send email to user when he/she is created through the admin panel
+    def welcome_email (user)
+        @user = user
+        mail(to: @user.email, subject: 'Bem vindo ao PortalMec!')
+    end
+
+    #function to send email confirmation to user, this view is located in app/views/user_mailer/email_confirmation.html.erb
+    def email_confirmation (user)
+        @user = user
+        mail(to: @user.email, subject: 'Confirmação de email')
+    end
+
+end
diff --git a/app/models/achievement.rb b/app/models/achievement.rb
index f6175da002c0750d3947f5e770fea91df5cb8e9f..b29f43f06b655ffb6a7e3d4a4d5e87f8bdc24199 100644
--- a/app/models/achievement.rb
+++ b/app/models/achievement.rb
@@ -18,7 +18,7 @@
 
 # == Schema Information
 #
-# Table name: achievement
+# Table name: achievements
 
 # t.string      :name
 # t.string      :description
diff --git a/app/models/action.rb b/app/models/action.rb
index 33cbf2dfc0fc4325ef215348f19c0cec94fd13e5..ff7b2450cb1d12da141d88da11de889ed453deed 100644
--- a/app/models/action.rb
+++ b/app/models/action.rb
@@ -18,7 +18,7 @@
 
 # == Schema Information
 #
-# Table name: action
+# Table name: actions
 
 # t.integer  "name"
 # t.integer  "description"
@@ -26,6 +26,8 @@
 # t.datetime "updated_at"
 # t.integer  "reward_experience"
 
+# this table has the following foreign keys: requirements | action_counters
+
 class Action < ApplicationRecord
   has_many :requirements
   has_many :action_counters
diff --git a/app/models/action_counter.rb b/app/models/action_counter.rb
index bf221cae4a32d1e6f51db47e0593d8986ba2bf4a..30530afad53f4792a2ba3ed9c9ccc90ee838cedf 100644
--- a/app/models/action_counter.rb
+++ b/app/models/action_counter.rb
@@ -18,11 +18,13 @@
 
 # == Schema Information
 #
-# Table name: action_counter
+# Table name: action_counters
 
 # t.belongs_to      :action, index: true
 # t.belongs_to      :user, index:true
 # t.integer         :counter, default: 0
+# t.datetime "created_at",    null: false
+# t.datetime "updated_at",    null: false
 
 class ActionCounter < ApplicationRecord
   belongs_to :action
diff --git a/app/models/collection.rb b/app/models/collection.rb
index a9a145d26deea2805bfa2992ed663ca823c1ada5..791c58786b639d54ac267ca99b5b69552fbe6837 100644
--- a/app/models/collection.rb
+++ b/app/models/collection.rb
@@ -39,7 +39,8 @@
 #  thumbnail_content_type :string
 #  thumbnail_file_size    :integer
 #  thumbnail_updated_at   :datetime
-#
+#  review_average:        :float            default("0.0")
+#  curator                :string          
 
 class Collection < ApplicationRecord
   include Reviewable
diff --git a/app/models/collection_item.rb b/app/models/collection_item.rb
index 9088f56896955cf4f2ce8d8fcd6ebb0917a2395e..a658e3aa7bbe4ac5e66c7b8a2087140851193f37 100644
--- a/app/models/collection_item.rb
+++ b/app/models/collection_item.rb
@@ -25,7 +25,7 @@
 #  collectionable_id   :integer
 #  collectionable_type :string
 #  collection_id       :integer
-#  order               :integer
+#  position               :integer
 #  created_at          :datetime         not null
 #  updated_at          :datetime         not null
 #
diff --git a/app/models/complaint.rb b/app/models/complaint.rb
index cf318c09b259e7ef97481c07b7d3567b8ecc49e6..e710581ac3c80bafadc3e962ce85111cca0abbd1 100644
--- a/app/models/complaint.rb
+++ b/app/models/complaint.rb
@@ -24,12 +24,12 @@
 #  id                  :integer          not null, primary key
 #  description         :text
 #  user_id             :integer
-#  complainable_id    :integer
-#  complainable_type  :string
+#  complainable_id     :integer
+#  complainable_type   :string
 #  complaint_reason_id :integer
 #  created_at          :datetime         not null
 #  updated_at          :datetime         not null
-#
+#  state               :integer          default("0")
 
 class Complaint < ApplicationRecord
   # *current_user* create complaint about *complaint_reason* for *complaintable*
diff --git a/app/models/complaint_reason.rb b/app/models/complaint_reason.rb
index c5b4e58ce9eac13f35f6bea2e89d78cc3d7d726f..7352be4628014087c73cbea734ce41888052e97d 100644
--- a/app/models/complaint_reason.rb
+++ b/app/models/complaint_reason.rb
@@ -25,7 +25,7 @@
 #  reason     :text
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
-#
+#  status     :integer          default("0")
 
 class ComplaintReason < ApplicationRecord
   # *current_user* create complaint reason
diff --git a/app/mailers/email_mailer.rb b/app/models/complaint_vote.rb
similarity index 72%
rename from app/mailers/email_mailer.rb
rename to app/models/complaint_vote.rb
index 31d8d5bf7972166fa0127edd16684314e0feee73..c1bf5017a484d8b551312efe3318b6e9933c5734 100644
--- a/app/mailers/email_mailer.rb
+++ b/app/models/complaint_vote.rb
@@ -17,11 +17,15 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-class EmailMailer < ApplicationMailer
-  default from: 'integrada.contato@mec.gov.br'
+class ComplaintVote < ApplicationRecord
+    include Trackable
+    belongs_to :complainable, polymorphic: true
+
+    belongs_to :user
+    validates_presence_of :user, :complainable_id
+    validates :user_id, uniqueness: { scope: [:complainable_id, :complainable_type]}
+    
+    acts_as_paranoid
+    has_paper_trail
 
-  def new_email(email, to_address)
-    @email = email
-    mail(subject: @email.subject, to:to_address)
-  end
 end
diff --git a/app/models/contact.rb b/app/models/contact.rb
index 298bab6b27a5f903a850aa83551a00d226a911b5..b0f55bd029f8713497f1a588931e86fa82091890 100644
--- a/app/models/contact.rb
+++ b/app/models/contact.rb
@@ -25,6 +25,8 @@
 #  name                   :string
 #  email                  :string
 #  message                :text
-#
+#  created_at          :datetime         not null
+#  updated_at          :datetime         not null
+
 class Contact < ApplicationRecord
 end
diff --git a/app/models/institution.rb b/app/models/institution.rb
index 7171be3c9768dabc8d03682224ae0dd889812bc4..3e7b2aab51ae78d9cdeb1b13eb9fbde4f40903a4 100644
--- a/app/models/institution.rb
+++ b/app/models/institution.rb
@@ -21,15 +21,19 @@
 #
 # Table name: institutions
 #
-#  id          :integer          not null, primary key
-#  name        :string
-#  address     :string
-#  city        :string
-#  country     :string
-#  description :text
-#  created_at  :datetime         not null
-#  updated_at  :datetime         not null
-#
+#  id                     :integer          not null, primary key
+#  name                   :string
+#  address                :string
+#  city                   :string
+#  country                :string
+#  description            :text
+#  created_at             :datetime         not null
+#  updated_at             :datetime         not null
+#  avatar_file_name       :string
+#  avatar_content_type    :string
+#  avatar_file_size       :integer
+#  avatar_updated_at      :datetime
+#  learning_objects_count :integer          default("0")
 
 class Institution < ApplicationRecord
   include Tagger
diff --git a/app/models/item.rb b/app/models/item.rb
index 51e40f5508cd88b07fe9bbb5df2376ac43334b96..025848cfcef9f33e636aee85c016055acbac1b70 100644
--- a/app/models/item.rb
+++ b/app/models/item.rb
@@ -34,6 +34,8 @@
 # created_at:           datetime
 # updated_at:           datetime
 
+# this table has one foreign key: achievement_id.
+
 class Item < ApplicationRecord
   belongs_to :achievement, optional: true
   has_many :user_items
diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb
index 10451b6f8921f176769180890aa8b6f38b8be3ac..8695fd1cd149e462c15cf3c54fa338aa2c32d1f0 100644
--- a/app/models/learning_object.rb
+++ b/app/models/learning_object.rb
@@ -28,9 +28,7 @@
 #  description            :text
 #  published_at           :datetime
 #  score                  :float            default("0.0")
-#  school_level           :integer
 #  metadata               :jsonb            default("{}")
-#  keywords               :text
 #  publisher_id           :integer
 #  publisher_type         :string
 #  object_type_id         :integer
@@ -40,7 +38,16 @@
 #  downloads_count        :integer          default("0")
 #  likes_count            :integer          default("0")
 #  shares_count           :integer          default("0")
-#  state                  :string           default("published")
+#  state                  :string           default("0")
+#  license_id             :integer
+#  link                   :string 
+#  software               :string
+#  review_average         :float            default("0.0")
+#  curator                :string
+#  magnetlink             :string
+#  terms_of_service       :boolean
+#  submission_id          :integer
+#  legacy_dspace_id       :string
 #  thumbnail_file_name    :string
 #  thumbnail_content_type :string
 #  thumbnail_file_size    :integer
@@ -92,18 +99,10 @@ class LearningObject < ApplicationRecord
   default_scope { includes(:object_type, :attachment, :attachments) }
   scope :missing_thumbnail, ->() { where(thumbnail_file_name: nil) }
 
-  searchkick language: 'brazilian', match: :word_start, searchable: [:name, :description, :author, :object_type, :tags, :subjects, :educational_stages, :languages], callbacks: :async, index_prefix: Socket.gethostname.downcase, merge_mappings: true, mappings: {
-    learning_object: {
-      properties: {
-        published_at: {
-          type: "date"
-        }
-      }
-    }
-  }
+  searchkick language: 'brazilian', match: :word_start, searchable: [:name, :description, :author, :object_type, :tags, :subjects, :educational_stages, :languages], callbacks: :async, index_prefix: Socket.gethostname.downcase, merge_mappings: true
+  {"mappings": {"_doc": {"properties": {"published_at": { "type": "date" }}}}}
 
   acts_as_paranoid
-
   scope :search_import, -> { includes(:object_type, :tags, :subjects, :educational_stages, :publisher) }
 
   def search_data
@@ -220,8 +219,9 @@ class LearningObject < ApplicationRecord
 
   def treat_complaintment
     #Uncomment the line below if an arbitrary number of complaints are necessary to suspend the LO.
-    # if (Complaint.where(complainable_id: @complaint.complainable_id).count < 5)
-    self.suspended!
+    if (Complaint.where(complainable_id: self.complainable_id).count >= 2)
+      LearningObject.find_by_id(self.complainable_id).update(state: 0);
+    end
   end
 
   def complaint_accept(params)
diff --git a/app/models/package.rb b/app/models/package.rb
index 3acede537ab28157d0d02e5236209b37be825c95..b131ff841f4fd51b4d932641c0f44656b75c19c1 100644
--- a/app/models/package.rb
+++ b/app/models/package.rb
@@ -21,6 +21,7 @@
 #
 # Table name: packages
 #
+# id                   :integer          not null, primary key
 # package_items_id      integer
 # created_at            datetime       null: false
 # updated_at            datetime       null: false
diff --git a/app/models/progress.rb b/app/models/progress.rb
index 8370eb4f98d4cdb88afd8fcee00249e4418ca005..3207d2cf44b7105183e0cb8a6e5b1b8dad349400 100644
--- a/app/models/progress.rb
+++ b/app/models/progress.rb
@@ -18,12 +18,14 @@
 
 # == Schema Information
 #
-# Table name: progress
+# Table name: progresses
 
 # t.belongs_to  :user
 # t.belongs_to  :achievement
 # t.belongs_to  :progress_type
 # t.integer     :counter, default: 0
+# t.datetime "created_at",    null: false
+# t.datetime "updated_at",    null: false
 
 class Progress < ApplicationRecord
   belongs_to :requirement
diff --git a/app/models/question.rb b/app/models/question.rb
index 6a4b3c70bfd60b3d603f0f187bb7b9bfc7e1dc6c..13443a9970711ad1d4ef79ebdd18cb34a1dcb610 100644
--- a/app/models/question.rb
+++ b/app/models/question.rb
@@ -21,7 +21,7 @@
 # Table name: questions
 
 # t.string   "description"
-# t.integer  "status",      default: 0
+# t.integer  "status",                  default: 0
 # t.datetime "created_at",              null: false
 # t.datetime "updated_at",              null: false
 
diff --git a/app/models/rate.rb b/app/models/rate.rb
index 52f4af694c5d8cea49c598f4592e4701c2d4b0a9..96c987c1e4a5577632cb8678cb77c1143d63a05e 100644
--- a/app/models/rate.rb
+++ b/app/models/rate.rb
@@ -27,6 +27,7 @@
 #  review_id  :integer
 #  created_at :datetime         not null
 #  updated_at :datetime         not null
+
 class Rate < ApplicationRecord
   # *current_user* rate a review *review*
   include Trackable
diff --git a/app/models/requirement.rb b/app/models/requirement.rb
index 58d1a41b5c95df284bf16efcbda620e86d38681f..80ca577d5719fc039d97b982cab963f009173f0b 100644
--- a/app/models/requirement.rb
+++ b/app/models/requirement.rb
@@ -19,10 +19,10 @@
 
 # == Schema Information
 #
-# Table name: progress_type
+# Table name: requirements
 
 # t.belongs_to  "action"
-# t.belnogs_to  "achievement"
+# t.belongs_to  "achievement"
 # t.string      "description"
 # t.integer     "goal"
 # t.boolean     "repeatable"
diff --git a/app/models/suggestion.rb b/app/models/suggestion.rb
index 82fa9ecc7ff8e119b8a631bc402a34b5e848c890..7a2d67a2155881cca5f0deb065b06ceb0932c4c1 100644
--- a/app/models/suggestion.rb
+++ b/app/models/suggestion.rb
@@ -26,7 +26,9 @@
 #  link                   :string
 #  description            :text
 #  status                 :integer
-#
+#  created_at             :datetime         not null
+#  updated_at             :datetime         not null
+
 class Suggestion < ApplicationRecord
   enum status: { created: 0, accepted: 1, rejected: 2, loadded: 3 }
 end
diff --git a/app/models/unlocked_achievement.rb b/app/models/unlocked_achievement.rb
index 84a33349750dea44d2ae5ae6d60c8ea10323a424..59fff47cf6911e442c345e55a647b0db4e9907ee 100644
--- a/app/models/unlocked_achievement.rb
+++ b/app/models/unlocked_achievement.rb
@@ -20,8 +20,10 @@
 #
 # Table name: unlocked_achievement
 
-# t.belongs_to      :achievement, index: true
-# t.belongs_to      :user, index:true
+# t.belongs_to      :achievement,     index: true
+# t.belongs_to      :user,            index:true
+# created_at        :datetime         not null
+# updated_at        :datetime         not null
 
 class UnlockedAchievement < ApplicationRecord
   belongs_to :achievement
diff --git a/app/models/user.rb b/app/models/user.rb
index 05c0df2fcb1892ab2db2cdcf1d5c4b3f3cb29cdf..4516f5f9fa66d5ab567df5912b70f2fbd3b9b210 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -51,7 +51,34 @@
 #  score                  :float            default("0.0")
 #  follows_count          :integer          default("0")
 #  description            :text
-#
+#  likes_count            :integer
+#  learning_objects_count :integer
+#  collections_count      :integer
+#  nickname               :string
+#  cover_file_name        :string
+#  cover_content_type     :string
+#  cover_file_size        :integer
+#  cover_updated_at       :datetime
+#  education              :string
+#  submitter_request      :integer          default("0")
+#  dspace_handle          :string
+#  dspace_sets            :text             default("{}")
+#  teacher_id             :string
+#  birthday               :datetime
+#  school_id              :integer
+#  terms_accepted_at      :datetime
+#  cpf                    :string
+#  state                  :integer          default("0")
+#  suspended_at           :datetime
+#  reactivated_at         :datetime
+#  times_blocked          :integer
+#  ask_teacher_question   :boolean          default("true")
+#  dspace_collection      :string           default("{}")
+#  allow_experience_change:boolean
+#  experience             :integer          default("0")
+#  level                  :integer          default("1")
+#  points                 :integer          default("0")
+#  last_sign_in_day       :datetime
 
 class User < ApplicationRecord
   include Followable
@@ -61,7 +88,7 @@ class User < ApplicationRecord
   include Complainable
   include Publisher
   include Trackable
-
+  
   # Include default devise modules. Others available are:
   # :confirmable, :lockable, :timeoutable and :omniauthable
   devise :database_authenticatable, :registerable,
@@ -107,9 +134,12 @@ class User < ApplicationRecord
   has_many  :action_counters
   has_many  :actions, through: :action_counters
 
+  before_create :confirmation_token
+
   after_create :default_role
   before_save :verify_teacher_id
   after_save :verify_dspace_info
+  before_create :send_email_confirmation
   before_destroy :delete_index
   after_update :create_actions
 
@@ -138,6 +168,17 @@ class User < ApplicationRecord
   # don't versionate frequently changed fields
   has_paper_trail ignore: [:tokens, :sign_in_count, :current_sign_in_at, :last_sign_in_at]
 
+  def send_email_confirmation
+    UserMailer.email_confirmation(self).deliver_now
+  end
+
+  def email_activate
+    self.email_confirmed = true
+    self.confirm_token = nil
+    self.confirmed_at = Time.now.utc
+    save!(:validate => false)
+  end
+
   def search_data
     {
       name: name,
@@ -159,56 +200,72 @@ class User < ApplicationRecord
 
   def is_admin?
     roles.each do |role|
-      return true if role.name == 'admin'
+      if role.name == 'admin'
+        return true
+      end
     end
     false
   end
 
   def is_moderator?
     roles.each do |role|
-      return true if role.name == 'moderator'
+      if role.name == 'moderator'
+        return true
+      end
     end
     false
   end
 
   def is_curator?
     roles.each do |role|
-      return true if role.name == 'curator'
+      if role.name == 'curator'
+        return true 
+      end
     end
     false
   end
 
   def is_supervisor?
     roles.each do |role|
-      return true if role.name == 'supervisor'
+      if role.name == 'supervisor'
+        return true 
+      end
     end
     false
   end
 
   def is_editor?
     roles.each do |role|
-      return true if role.name == 'editor'
+      if role.name == 'editor'
+        return true 
+      end
     end
     false
   end
 
   def is_submitter?
     roles.each do |role|
-      return true if role.name == 'submitter'
+      if role.name == 'submitter'
+        return true 
+      end
     end
     false
   end
 
   def is_publisher?
     roles.each do |role|
-      return true if role.name == 'publisher'
+      if role.name == 'publisher'
+        return true 
+      end
     end
     false
   end
 
   def is_partner?
     roles.each do |role|
-      return true if role.name == 'partner'
+      if role.name == 'partner'
+        return true 
+      end
     end
     false
   end
@@ -299,6 +356,12 @@ class User < ApplicationRecord
   def experience=(xp)
     new_level, remaining_xp = calculate_level(xp)
     self.level = new_level
+    
+    #if the new level is more than 5, give him curator role
+    if new_level >= 5 && !self.is_curator?
+      self.roles << Role.find_by(name: 'curator')
+    end
+
     super(remaining_xp)
   end
 
@@ -438,6 +501,13 @@ class User < ApplicationRecord
     roles << Role.submitter
   end
 
+  private
+  def confirmation_token
+      if self.confirm_token.blank?
+          self.confirm_token = SecureRandom.urlsafe_base64.to_s
+      end
+  end
+
   def self.from_omniauth(access_token)
     user = User.find_by(email: user_email)
     return nil if user.blank?
@@ -452,7 +522,7 @@ class User < ApplicationRecord
       password: Devise.friendly_token[0, 20]
     )
   end
-
+  
   def verify_dspace_info
     if roles.include?(Role.find_by_name("partner")) && !(changed & ["dspace_url", "dspace_handle", "dspace_sets"]).empty?
       DspaceMailer.dspace_info_updated(self).deliver_now
@@ -512,4 +582,5 @@ class User < ApplicationRecord
 
   def complaint_reject(params)
   end
+
 end
diff --git a/app/models/user_item.rb b/app/models/user_item.rb
index c45cc51626457a215f9cb3fdf430ee0b56474af2..98859f2452f347c67b61106460a468d7875653ff 100644
--- a/app/models/user_item.rb
+++ b/app/models/user_item.rb
@@ -18,7 +18,7 @@
 
 # == Schema Information
 #
-# Table name: inventory
+# Table name: user_items
 
 # t.belongs_to  :user, index: true
 # t.belongs_to  item, index: true
diff --git a/app/services/dspace_service.rb b/app/services/dspace_service.rb
index fd63e62d6f997a3d0aa5afb8d1cbadd91f8f1a6c..cac09e7e692316c5b7143cc9bc391b1707717f81 100644
--- a/app/services/dspace_service.rb
+++ b/app/services/dspace_service.rb
@@ -22,7 +22,7 @@ require 'dspace'
 class DspaceService
 
   # ID's of collections
-  TEST_COLLECTION = 4
+  TEST_COLLECTION = "b1ae8711-bb96-4dd2-945d-ea27ee1141db"
   PORTALMEC_COLLECTION = 3
   PORTALMEC_BETA_COLLECTION = 6
   BD_INT_OBJETOS_COLLECTION = 2
diff --git a/app/views/devise/mailer/reset_password_instructions.html.erb b/app/views/devise/mailer/reset_password_instructions.html.erb
index 0fc308c4049b019e9891e9b5d18826af90dfd145..b0e718069fa8548a529d0621e5c70a90a6270df2 100644
--- a/app/views/devise/mailer/reset_password_instructions.html.erb
+++ b/app/views/devise/mailer/reset_password_instructions.html.erb
@@ -2,6 +2,7 @@
 
 <p><%= t '.request_reset_link_msg' %></p>
 
+<!-- instructions about reset password, it contains the redirect url -->
 <p><%= link_to t('.password_change_link'), edit_password_url(@resource, reset_password_token: @token, config: message['client-config'].to_s, redirect_url: message['redirect-url'].to_s).html_safe %></p>
 
 <p><%= t '.ignore_mail_msg' %></p>
diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb
new file mode 100644
index 0000000000000000000000000000000000000000..37f0bddbd746bc24923ce9a8eb0dae1ca3076284
--- /dev/null
+++ b/app/views/layouts/mailer.text.erb
@@ -0,0 +1 @@
+<%= yield %>
diff --git a/app/views/user_mailer/email_confirmation.html.erb b/app/views/user_mailer/email_confirmation.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..c2fa862dd64dcab4116f202e0c31da84e82416bd
--- /dev/null
+++ b/app/views/user_mailer/email_confirmation.html.erb
@@ -0,0 +1,5 @@
+Olá, <%= @user.name %>,
+
+Seja bem vindo ao PortalMec,
+Confirme seu email abaixo:
+<%= confirm_email_v1_user_url(@user.confirm_token) %>
\ No newline at end of file
diff --git a/app/views/user_mailer/email_confirmation.text.erb b/app/views/user_mailer/email_confirmation.text.erb
new file mode 100644
index 0000000000000000000000000000000000000000..2e5622583f8db032224060835dafcc3ef1042435
--- /dev/null
+++ b/app/views/user_mailer/email_confirmation.text.erb
@@ -0,0 +1 @@
+<%= confirm_email_v1_user_url(@user.confirm_token) %>
\ No newline at end of file
diff --git a/app/views/user_mailer/welcome_email.html.erb b/app/views/user_mailer/welcome_email.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..8d106a84889980b41d1aa453f00e4ef0db2965a2
--- /dev/null
+++ b/app/views/user_mailer/welcome_email.html.erb
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
+  </head>
+  <body>
+    <h1>Bem vindo ao PortalMec!, <%= @user.name %> </h1>
+    <p>
+      Seu cadastro foi realizado com sucesso, agora você pode acessar o PortalMec.
+    </p>
+    <p>Obrigado!</p>
+  </body>
+</html>
diff --git a/app/views/user_mailer/welcome_email.text.erb b/app/views/user_mailer/welcome_email.text.erb
new file mode 100644
index 0000000000000000000000000000000000000000..3daed056d1195fbc2bddcc7ec56b9fc336ad496f
--- /dev/null
+++ b/app/views/user_mailer/welcome_email.text.erb
@@ -0,0 +1,6 @@
+Bem vindo ao PortalMec <%= @user.name %> !
+===============================================
+
+Seu cadastro foi realizado com sucesso.,
+
+Obrigado!
\ No newline at end of file
diff --git a/app/views/users/confirmations/new.html.erb b/app/views/users/confirmations/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..4af186b288328a9af85b3ff88d16c4751516f048
--- /dev/null
+++ b/app/views/users/confirmations/new.html.erb
@@ -0,0 +1,16 @@
+<h2>Resend confirmation instructions</h2>
+
+<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
+  <%= render "users/shared/error_messages", resource: resource %>
+
+  <div class="field">
+    <%= f.label :email %><br />
+    <%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
+  </div>
+
+  <div class="actions">
+    <%= f.submit "Resend confirmation instructions" %>
+  </div>
+<% end %>
+
+<%= render "users/shared/links" %>
diff --git a/app/views/users/mailer/confirmation_instructions.html.erb b/app/views/users/mailer/confirmation_instructions.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..dc55f64f69e2541d12e6ffd6e3f4a413e8b828b2
--- /dev/null
+++ b/app/views/users/mailer/confirmation_instructions.html.erb
@@ -0,0 +1,5 @@
+<p>Welcome <%= @email %>!</p>
+
+<p>You can confirm your account email through the link below:</p>
+
+<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
diff --git a/app/views/users/mailer/email_changed.html.erb b/app/views/users/mailer/email_changed.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..32f4ba8038d81c16f86eab2262a761f56ef656c9
--- /dev/null
+++ b/app/views/users/mailer/email_changed.html.erb
@@ -0,0 +1,7 @@
+<p>Hello <%= @email %>!</p>
+
+<% if @resource.try(:unconfirmed_email?) %>
+  <p>We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.</p>
+<% else %>
+  <p>We're contacting you to notify you that your email has been changed to <%= @resource.email %>.</p>
+<% end %>
diff --git a/app/views/users/mailer/password_change.html.erb b/app/views/users/mailer/password_change.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..b41daf476a35f81702a954445f624b98e15b54f1
--- /dev/null
+++ b/app/views/users/mailer/password_change.html.erb
@@ -0,0 +1,3 @@
+<p>Hello <%= @resource.email %>!</p>
+
+<p>We're contacting you to notify you that your password has been changed.</p>
diff --git a/app/views/users/mailer/reset_password_instructions.html.erb b/app/views/users/mailer/reset_password_instructions.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..f667dc12fe34929983021920c39f4ca061c4fd4f
--- /dev/null
+++ b/app/views/users/mailer/reset_password_instructions.html.erb
@@ -0,0 +1,8 @@
+<p>Hello <%= @resource.email %>!</p>
+
+<p>Someone has requested a link to change your password. You can do this through the link below.</p>
+
+<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>
+
+<p>If you didn't request this, please ignore this email.</p>
+<p>Your password won't change until you access the link above and create a new one.</p>
diff --git a/app/views/users/mailer/unlock_instructions.html.erb b/app/views/users/mailer/unlock_instructions.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..41e148bf2ac2d8b3f108e15c45f8a2e75fb0b07e
--- /dev/null
+++ b/app/views/users/mailer/unlock_instructions.html.erb
@@ -0,0 +1,7 @@
+<p>Hello <%= @resource.email %>!</p>
+
+<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
+
+<p>Click the link below to unlock your account:</p>
+
+<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
diff --git a/app/views/users/passwords/edit.html.erb b/app/views/users/passwords/edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..863ffbb223926b256b54195e0a8b58fe55f82598
--- /dev/null
+++ b/app/views/users/passwords/edit.html.erb
@@ -0,0 +1,25 @@
+<h2>Change your password</h2>
+
+<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
+  <%= render "users/shared/error_messages", resource: resource %>
+  <%= f.hidden_field :reset_password_token %>
+
+  <div class="field">
+    <%= f.label :password, "New password" %><br />
+    <% if @minimum_password_length %>
+      <em>(<%= @minimum_password_length %> characters minimum)</em><br />
+    <% end %>
+    <%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
+  </div>
+
+  <div class="field">
+    <%= f.label :password_confirmation, "Confirm new password" %><br />
+    <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+  </div>
+
+  <div class="actions">
+    <%= f.submit "Change my password" %>
+  </div>
+<% end %>
+
+<%= render "users/shared/links" %>
diff --git a/app/views/users/passwords/new.html.erb b/app/views/users/passwords/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..3b30b06d611d54585f38afbfc9fc8c2ffe96545a
--- /dev/null
+++ b/app/views/users/passwords/new.html.erb
@@ -0,0 +1,16 @@
+<h2>Forgot your password?</h2>
+
+<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
+  <%= render "users/shared/error_messages", resource: resource %>
+
+  <div class="field">
+    <%= f.label :email %><br />
+    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+  </div>
+
+  <div class="actions">
+    <%= f.submit "Send me reset password instructions" %>
+  </div>
+<% end %>
+
+<%= render "users/shared/links" %>
diff --git a/app/views/users/registrations/edit.html.erb b/app/views/users/registrations/edit.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..038cd9459b5d483dd68f79e83011366b412623d3
--- /dev/null
+++ b/app/views/users/registrations/edit.html.erb
@@ -0,0 +1,43 @@
+<h2>Edit <%= resource_name.to_s.humanize %></h2>
+
+<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
+  <%= render "users/shared/error_messages", resource: resource %>
+
+  <div class="field">
+    <%= f.label :email %><br />
+    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+  </div>
+
+  <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
+    <div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
+  <% end %>
+
+  <div class="field">
+    <%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
+    <%= f.password_field :password, autocomplete: "new-password" %>
+    <% if @minimum_password_length %>
+      <br />
+      <em><%= @minimum_password_length %> characters minimum</em>
+    <% end %>
+  </div>
+
+  <div class="field">
+    <%= f.label :password_confirmation %><br />
+    <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+  </div>
+
+  <div class="field">
+    <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
+    <%= f.password_field :current_password, autocomplete: "current-password" %>
+  </div>
+
+  <div class="actions">
+    <%= f.submit "Update" %>
+  </div>
+<% end %>
+
+<h3>Cancel my account</h3>
+
+<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
+
+<%= link_to "Back", :back %>
diff --git a/app/views/users/registrations/new.html.erb b/app/views/users/registrations/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..61d1e4c7a3f24ccd8de063fb07f98f3b9ad65ed9
--- /dev/null
+++ b/app/views/users/registrations/new.html.erb
@@ -0,0 +1,29 @@
+<h2>Sign up</h2>
+
+<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
+  <%= render "users/shared/error_messages", resource: resource %>
+
+  <div class="field">
+    <%= f.label :email %><br />
+    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+  </div>
+
+  <div class="field">
+    <%= f.label :password %>
+    <% if @minimum_password_length %>
+    <em>(<%= @minimum_password_length %> characters minimum)</em>
+    <% end %><br />
+    <%= f.password_field :password, autocomplete: "new-password" %>
+  </div>
+
+  <div class="field">
+    <%= f.label :password_confirmation %><br />
+    <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
+  </div>
+
+  <div class="actions">
+    <%= f.submit "Sign up" %>
+  </div>
+<% end %>
+
+<%= render "users/shared/links" %>
diff --git a/app/views/users/sessions/new.html.erb b/app/views/users/sessions/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..b892c8ac8dd7c245dc4ced158ef9947d30efdd11
--- /dev/null
+++ b/app/views/users/sessions/new.html.erb
@@ -0,0 +1,27 @@
+<div><%=notice%></div>
+<h2>Log in</h2>
+
+<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
+  <div class="field">
+    <%= f.label :email %><br />
+    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+  </div>
+
+  <div class="field">
+    <%= f.label :password %><br />
+    <%= f.password_field :password, autocomplete: "current-password" %>
+  </div>
+
+  <% if devise_mapping.rememberable? %>
+    <div class="field">
+      <%= f.check_box :remember_me %>
+      <%= f.label :remember_me %>
+    </div>
+  <% end %>
+
+  <div class="actions">
+    <%= f.submit "Log in" %>
+  </div>
+<% end %>
+
+<%= render "users/shared/links" %>
diff --git a/app/views/users/shared/_error_messages.html.erb b/app/views/users/shared/_error_messages.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..ba7ab887013255a06523bdee4d19189cb5b59b3c
--- /dev/null
+++ b/app/views/users/shared/_error_messages.html.erb
@@ -0,0 +1,15 @@
+<% if resource.errors.any? %>
+  <div id="error_explanation">
+    <h2>
+      <%= I18n.t("errors.messages.not_saved",
+                 count: resource.errors.count,
+                 resource: resource.class.model_name.human.downcase)
+       %>
+    </h2>
+    <ul>
+      <% resource.errors.full_messages.each do |message| %>
+        <li><%= message %></li>
+      <% end %>
+    </ul>
+  </div>
+<% end %>
diff --git a/app/views/users/shared/_links.html.erb b/app/views/users/shared/_links.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..96a9412417bf51257684ada2d9410c4e98e857ff
--- /dev/null
+++ b/app/views/users/shared/_links.html.erb
@@ -0,0 +1,25 @@
+<%- if controller_name != 'sessions' %>
+  <%= link_to "Log in", new_session_path(resource_name) %><br />
+<% end %>
+
+<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
+  <%= link_to "Sign up", new_registration_path(resource_name) %><br />
+<% end %>
+
+<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
+  <%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
+<% end %>
+
+<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
+  <%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
+<% end %>
+
+<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
+  <%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
+<% end %>
+
+<%- if devise_mapping.omniauthable? %>
+  <%- resource_class.omniauth_providers.each do |provider| %>
+    <%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
+  <% end %>
+<% end %>
diff --git a/app/views/users/unlocks/new.html.erb b/app/views/users/unlocks/new.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..2f4fab8481b3687d2ee0892f63598e6ca590bb44
--- /dev/null
+++ b/app/views/users/unlocks/new.html.erb
@@ -0,0 +1,16 @@
+<h2>Resend unlock instructions</h2>
+
+<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
+  <%= render "users/shared/error_messages", resource: resource %>
+
+  <div class="field">
+    <%= f.label :email %><br />
+    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
+  </div>
+
+  <div class="actions">
+    <%= f.submit "Resend unlock instructions" %>
+  </div>
+<% end %>
+
+<%= render "users/shared/links" %>
diff --git a/config/application.rb b/config/application.rb
index d4b616aa5baf2035898d0afb0305e2ab08d32767..a045b9cacfc052cd12987fb40426fa71096c4a80 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -17,7 +17,6 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-# Here [27/06/2022]
 require_relative 'boot'
 
 require 'rails'
diff --git a/config/database.yml b/config/database.yml
index c36c3441735a6f541e1421c08c120a20285955e4..abafacb352c3997be8b700c0c501d618f1064778 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -5,17 +5,18 @@
 development:
   adapter: postgresql
   encoding: unicode
-  database: portalmec_dev
+  database: portalmecapi
   username: portalmec
   password: 123mudar
+  host: localhost
 
 test:
   adapter: postgresql
   encoding: unicode
-  database: portalmec_test
+  database: portalmecapi
   username: portalmec
   password: 123mudar
-  host: postgres
+  host: localhost
 
 production:
   adapter: postgresql
@@ -26,3 +27,4 @@ production:
   database: <%= ENV['PORTALMEC_DB_NAME'] %>
   username: <%= ENV['PORTALMEC_DB_USERNAME'] %>
   password: <%= ENV['PORTALMEC_DB_PASSWORD'] %>
+  reaping_frequency: 30
diff --git a/config/dspace.yml b/config/dspace.yml
index 6b221dce4cc5a7d67fae114cdd19f9a80d989717..023bdbc731a8277c33c5d9ce95332bfb0bb3fb61 100644
--- a/config/dspace.yml
+++ b/config/dspace.yml
@@ -19,11 +19,11 @@
 development:
   host: mecdb2.c3sl.ufpr.br
   port: 8443
-  login: admin
-  password: password
+  login: admin@mecdb3.c3sl.ufpr.br
+  password: admin
 
 test:
   host: mecdb2.c3sl.ufpr.br
   port: 8443
-  login: admin
-  password: password
\ No newline at end of file
+  login: admin@mecdb3.c3sl.ufpr.br
+  password: admin
diff --git a/config/env_vars.sh b/config/env_vars.sh
index afb846d897c92e66e672810de138cb34f5a95e70..008132b1a20ea9fcc7b4234b4951a6dcfd59b48c 100644
--- a/config/env_vars.sh
+++ b/config/env_vars.sh
@@ -18,35 +18,35 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-export SECRET_TOKEN=$(rake secret)
-export SECRET_KEY_BASE=$(rake secret)
+#export SECRET_TOKEN=$(rake secret)
+#export SECRET_KEY_BASE=$(rake secret)
 
 ### Postgres/Active Record credentials
 export PORTALMEC_DB_HOST=localhost
 export PORTALMEC_DB_POOL=25
-export PORTALMEC_DB_NAME=portalmec
-export PORTALMEC_DB_USERNAME=
-export PORTALMEC_DB_PASSWORD=
+export PORTALMEC_DB_NAME=portalmecapi
+export PORTALMEC_DB_USERNAME=portalmec
+export PORTALMEC_DB_PASSWORD=123mudar
 
 ### Dspace credentials
-export PORTALMEC_DSPACE_LOGIN=
-export PORTALMEC_DSPACE_PASSWORD=
-export PORTALMEC_DSPACE_PORT=
-export PORTALMEC_DSPACE_HOST=
+export PORTALMEC_DSPACE_LOGIN=admin@mecdb3.c3sl.ufpr.br
+export PORTALMEC_DSPACE_PASSWORD=admin
+export PORTALMEC_DSPACE_PORT=8443
+export PORTALMEC_DSPACE_HOST=mecdb4.c3sl.ufpr.br
 
 ### Elasticsearch credentials
-export PORTALMEC_ELASTICSEARCH_LOGIN=
-export PORTALMEC_ELASTICSEARCH_PASSWORD=
-export PORTALMEC_ELASTICSEARCH_PORT=
-export PORTALMEC_ELASTICSEARCH_HOST=
+#export PORTALMEC_ELASTICSEARCH_LOGIN=
+#export PORTALMEC_ELASTICSEARCH_PASSWORD=
+export PORTALMEC_ELASTICSEARCH_PORT=9200
+export PORTALMEC_ELASTICSEARCH_HOST=localhost
 
 ### Cache
 export MEMCACHE_SERVERS=localhost
 
 ### SMTP
-export ACTION_MAILER_HOST=
-export SMTP_ADDRESS=
-export SMTP_PORT=
+export ACTION_MAILER_HOST=api.portalmec.c3sl.ufpr.br
+export SMTP_ADDRESS=urquell.c3sl.ufpr.br
+export SMTP_PORT=587
 
 ### Gitlab
 export GITLAB_PORTALMEC_PRIVATE_TOKEN=
@@ -57,8 +57,13 @@ export RAILS_ENV=production
 
 ### Puma
 export PORT=3000
-export WEB_CONCURRENCY=$(nproc) # workers
-export RAILS_MAX_THREADS=6 # threads per worker
+#export WEB_CONCURRENCY=$(nproc) # workers
+export WEB_CONCURRENCY=8 # workers
+export RAILS_MAX_THREADS=8 # threads per worker
 
 ### Redis
 export REDIS_HOST=localhost:6379
+
+### Google
+export GOOGLE_KEY=288460085642-k4veg4fo8kddvjer8b055n9da5qtgha7.apps.googleusercontent.com
+export GOOGLE_SECRET=C3OFletrmEU3lcY8YOHtnr7z
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 692e9bd414be07a7850b10f578dd7ca728c1cbfb..8fb2c9be8979bb2e0ce7f5495980fdb80e5f0baf 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -99,7 +99,9 @@ Rails.application.configure do
 
   #config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
   # Lets define mailcatcher configs
+  
+
   config.action_mailer.delivery_method = :smtp
   config.action_mailer.smtp_settings = { address: 'localhost', port: 1025 }
-  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
+  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } 
 end
diff --git a/config/initializers/elasticsearch.rb b/config/initializers/elasticsearch.rb
index 2080bde48474465229d2e29d7998d358266d48b9..ca3584792cfacb999d94abb60f7ea67821d2b6d9 100644
--- a/config/initializers/elasticsearch.rb
+++ b/config/initializers/elasticsearch.rb
@@ -26,15 +26,15 @@ if Rails.env.production?
     transport_options: {
       request: {
         timeout: 550
-      },
-      headers: {
-        Authorization: "Basic " + Base64.strict_encode64(login + ":" + pass)
-      }
+      }#,
+      #headers: {
+      #  Authorization: "Basic " + Base64.strict_encode64(login + ":" + pass)
+      #}
     }
   )
 elsif Rails.env.test?
   elasticsearch_client = Elasticsearch::Client.new(
-    url: 'elasticsearch:9200',
+    url: 'localhost:9200',
     transport_options: {request: {timeout: 550}}
   )
 else
@@ -45,3 +45,5 @@ else
 end
 
 Searchkick.client = elasticsearch_client
+#Searchkick.redis = ConnectionPool.new { Redis.new } 
+#Searchkick::ProcessQueueJob.perform_later(class_name: "LearningObject")
diff --git a/config/routes.rb b/config/routes.rb
index d8d97c45cd6ecedd6a68d62fd1a1e209837a7f69..a58747c8ab92da4bc47d19503dd073837e9ec5c2 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -136,6 +136,14 @@ Rails.application.routes.draw do
     resources :actions
     resources :requirements
     
+    resources :users do
+      member do
+        get :confirm_email
+      end
+    end
+    
+    get 'unlocked_achievements/user/:user_id', to: 'unlocked_achievements#show_specific'
+    
     resources :activities, only: [:index, :show] do
       collection do
         get 'me'
@@ -172,7 +180,8 @@ Rails.application.routes.draw do
         get 'completed_achievements'
       end
     end
-
+    
+  
     resources :reviews, only: :show
 
     # search routes
@@ -216,6 +225,8 @@ Rails.application.routes.draw do
       end
     end
     resources :complaints, only: [:index, :show, :create], concerns: [:deletable, :evaluable, :relatable]
+    resources :learning_objects_complaints, only: [:index, :show, :create], concerns: [:deletable, :evaluable, :relatable]
+    resources :complaint_votes, except: [:destroy]
     resources :languages, except: [:new, :edit]
     resources :licenses, except: [:new, :edit]
     resources :mime_types, except: [:new, :edit]
@@ -233,5 +244,8 @@ Rails.application.routes.draw do
     get '/subjects', to: 'subjects#index'
     get '/educational_stages', to: 'educational_stages#index'
     get 'learning_objects/magnetlink/:magnetlink', to: 'learning_objects#magnetlink', as: 'magnetlink_learning_objects'
+    get 'submissions/user_submissions/:user_id', to: 'submissions#user_submissions'
+    get 'submissions/all_users_submissions/:user_id', to: 'submissions#all_users_submissions'
+    get 'learning_objects_complaints/queue_user/:user_id', to: 'learning_objects_complaints#queue_user'
   end
 end
diff --git a/config/secrets.yml b/config/secrets.yml
index 54ab27ce6c449cecfb67120037f739aac1c38cda..0581df59ad70bc1f8652f6ffa39913195be5661d 100644
--- a/config/secrets.yml
+++ b/config/secrets.yml
@@ -38,5 +38,5 @@ test:
 # Do not keep production secrets in the repository,
 # instead read values from the environment.
 production:
-  secret_token: '<%= ENV["SECRET_TOKEN"] %>'
-  secret_key_base: '<%= ENV["SECRET_KEY_BASE"] %>'
+  secret_token: 96d4039aa1f2e9b11cc875a361afc429943f3db44cb31f6b9f6b43db314ba8dc0c7cb0123a1c7dc119f48290aeefd49225ce3dab82aaa3361face59fd0b872ab
+  secret_key_base: 88636022c8af91192474b5c6b0f8334d63261a83a36b564918884b7bb1461b5e82e1d295f9a0014b85b3a82cdaf522e26fe105b9bc81d74ee7277d084594f68f
diff --git a/db/migrate/20150731225848_devise_create_users.rb b/db/migrate/20150731225848_devise_create_users.rb
index 3f42108dc8d9f7efc45e4ea38765db5ce4ec8402..9575cfd31fbd9f984abf42e1f5521c1947d69264 100644
--- a/db/migrate/20150731225848_devise_create_users.rb
+++ b/db/migrate/20150731225848_devise_create_users.rb
@@ -39,15 +39,15 @@ class DeviseCreateUsers < ActiveRecord::Migration[4.2]
       t.string   :last_sign_in_ip
 
       ## Confirmable
-      # t.string   :confirmation_token
-      # t.datetime :confirmed_at
-      # t.datetime :confirmation_sent_at
-      # t.string   :unconfirmed_email # Only if using reconfirmable
+       #t.string   :confirmation_token
+       #t.datetime :confirmed_at
+       #t.datetime :confirmation_sent_at
+       #t.string   :unconfirmed_email # Only if using reconfirmable
 
       ## Lockable
-      # t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
-      # t.string   :unlock_token # Only if unlock strategy is :email or :both
-      # t.datetime :locked_at
+       t.integer  :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
+       t.string   :unlock_token # Only if unlock strategy is :email or :both
+       t.datetime :locked_at
 
 
       t.timestamps null: false
diff --git a/db/migrate/20220714142813_add_email_confirm_column_to_users.rb b/db/migrate/20220714142813_add_email_confirm_column_to_users.rb
new file mode 100644
index 0000000000000000000000000000000000000000..c87dfb6c23464d1589fcb099cd228dfff31e913a
--- /dev/null
+++ b/db/migrate/20220714142813_add_email_confirm_column_to_users.rb
@@ -0,0 +1,6 @@
+class AddEmailConfirmColumnToUsers < ActiveRecord::Migration[7.0]
+  def change
+    add_column :users, :email_confirmed, :boolean, :default => false
+    add_column :users, :confirm_token, :string
+  end
+end
diff --git a/db/migrate/20220808130940_add_priority_to_complaint_reasons.rb b/db/migrate/20220808130940_add_priority_to_complaint_reasons.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0a5fb05c08c3c1f2f54c98649a482b49f07c3a32
--- /dev/null
+++ b/db/migrate/20220808130940_add_priority_to_complaint_reasons.rb
@@ -0,0 +1,5 @@
+class AddPriorityToComplaintReasons < ActiveRecord::Migration[7.0]
+  def change
+    add_column :complaint_reasons, :priority, :integer
+  end
+end
diff --git a/db/migrate/20220815142111_create_complaint_votes.rb b/db/migrate/20220815142111_create_complaint_votes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..f3a069b7c3d093c001a2dc931e42e3c06c13223e
--- /dev/null
+++ b/db/migrate/20220815142111_create_complaint_votes.rb
@@ -0,0 +1,13 @@
+class CreateComplaintVotes < ActiveRecord::Migration[7.0]
+  def change
+    create_table :complaint_votes do |t|
+      t.references :complainable, polymorphic: true, index: true
+      t.integer :pros
+      t.integer :cons
+
+      t.timestamps
+    end
+
+    add_index :complaint_votes, [:complainable_id], name: 'complainable'
+  end
+end
diff --git a/db/migrate/20220921123353_add_deleted_at_to_complaint_votes.rb b/db/migrate/20220921123353_add_deleted_at_to_complaint_votes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6780dc594fa1feed3644d297747d11e481a077a1
--- /dev/null
+++ b/db/migrate/20220921123353_add_deleted_at_to_complaint_votes.rb
@@ -0,0 +1,6 @@
+class AddDeletedAtToComplaintVotes < ActiveRecord::Migration[7.0]
+  def change
+    add_column :complaint_votes, :deleted_at, :datetime
+    add_index :complaint_votes, :deleted_at
+  end
+end
diff --git a/db/migrate/20220921134130_add_user_id_to_complaint_votes.rb b/db/migrate/20220921134130_add_user_id_to_complaint_votes.rb
new file mode 100644
index 0000000000000000000000000000000000000000..e1de3ec4425fc16f3d35e2e253ff00d32aa1b168
--- /dev/null
+++ b/db/migrate/20220921134130_add_user_id_to_complaint_votes.rb
@@ -0,0 +1,10 @@
+class AddUserIdToComplaintVotes < ActiveRecord::Migration[7.0]
+  def change
+
+    add_column :complaint_votes, :user_id, :integer
+    add_foreign_key :complaint_votes, :users
+    add_index :complaint_votes, [:user_id, :complainable_id, :complainable_type], unique: true, name: 'user_and_complainable'
+
+  end
+end
+
diff --git a/db/seeds/complaints.rb b/db/seeds/complaints.rb
index 0fca5079f3f9baf86f7047eaaab18d7cda40138f..52126af608b7f6810dedad2cd3373c1887cd4802 100644
--- a/db/seeds/complaints.rb
+++ b/db/seeds/complaints.rb
@@ -17,9 +17,9 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-ComplaintReason.create(reason: "Objeto viola direitos autorais")
-ComplaintReason.create(reason: "Comtém conteúdo ofensivo/abusivo")
-ComplaintReason.create(reason: "Esta é uma conta falsa")
-ComplaintReason.create(reason: "Isso é um spam")
-ComplaintReason.create(reason: "A descrição não corresponde ao seu conteúdo")
-ComplaintReason.create(reason: "Esta pesssoa está fingindo ser eu ou alguém que eu conheço")
+ComplaintReason.create(reason: "Objeto viola direitos autorais", priority: 4)
+ComplaintReason.create(reason: "Contém conteúdo ofensivo/abusivo", priority: 5)
+ComplaintReason.create(reason: "Esta é uma conta falsa", priority: 3)
+ComplaintReason.create(reason: "Isso é um spam", priority: 1)
+ComplaintReason.create(reason: "A descrição não corresponde ao seu conteúdo", priority: 2)
+ComplaintReason.create(reason: "Esta pesssoa está fingindo ser eu ou alguém que eu conheço", priority: 3)
diff --git a/env b/env
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/lib/tasks/access.rake b/lib/tasks/access.rake
new file mode 100644
index 0000000000000000000000000000000000000000..3bd5d2862835615ea9d5183b0e54292d125c757a
--- /dev/null
+++ b/lib/tasks/access.rake
@@ -0,0 +1,14 @@
+namespace :access do
+    desc 'Check when all users was created, and give access to them if they were created before a certain date'
+    base_date = Date.new(2025, 12, 12)
+    
+    task :confirm_old_emails => :environment do
+        User.all.each do |user|
+            if user.created_at < base_date
+                user.update_attribute(:email_confirmed, true)
+                user.update_attribute(:confirmed_at, Time.now)
+            end
+
+        end
+    end
+end
diff --git a/lib/tasks/achievement_dependency.rake b/lib/tasks/achievement_dependency.rake
new file mode 100644
index 0000000000000000000000000000000000000000..fb732009b6e0abbbb7c550715a219a8547147402
--- /dev/null
+++ b/lib/tasks/achievement_dependency.rake
@@ -0,0 +1,17 @@
+namespace :achievement_dependency do
+    desc "Run the priority queue"
+    base_date = Date.new(2022, 1, 1)
+
+    task :link_achievements => :environment do
+       
+        #create a queue of achievements that need to be linked
+        unlocked_achievements = UnlockedAchievement.joins(:achievement).select("achievements.id, achievements.name, 
+            unlocked_achievements.id, unlocked_achievements.user_id").where("unlocked_achievements.id = achievements.id")
+        
+        puts ("----------------------------------------------------")
+        unlocked_achievements.each do |un_achievement|
+            puts "unlocked_achievement: #{un_achievement.name}"
+        end
+
+    end
+end
diff --git a/lib/tasks/change_priority_old_complaints.rake b/lib/tasks/change_priority_old_complaints.rake
new file mode 100644
index 0000000000000000000000000000000000000000..9a1d1f9cb3eabcffdf55e24f7e70b99181c24436
--- /dev/null
+++ b/lib/tasks/change_priority_old_complaints.rake
@@ -0,0 +1,13 @@
+namespace :change_priority_old_complaints do
+    desc 'Change the priority of old complaints to 25'
+    base_date = Date.new(2022, 3, 20)
+
+    task :change_priority => :environment do
+        Complaint.all.each do |complaint|
+            if (complaint.created_at < base_date)
+                complaint.update_attribute(:complaint_reason_id, 7)
+            end
+        end
+    end
+
+end
\ No newline at end of file
diff --git a/lib/tasks/change_state.rake b/lib/tasks/change_state.rake
new file mode 100644
index 0000000000000000000000000000000000000000..fa6ed3d6483c39f563c8008e2240f332a7cc12f3
--- /dev/null
+++ b/lib/tasks/change_state.rake
@@ -0,0 +1,13 @@
+namespace :change_state do
+    desc 'Check when all lo in Complaints, and change the state to 2 if they count is greater than 2'
+    base_date = Date.new(2022, 3, 20)
+
+    task :change_state_lo => :environment do
+        Complaint.all.each do |complaint|
+            if (Complaint.where(complainable_id: complaint.complainable_id).count >= 2 || complaint.created_at < base_date)
+                LearningObject.where(id: complaint.complainable_id).update_all(state: LearningObject.states[:suspended])
+            end
+        end
+    end
+
+end
\ No newline at end of file
diff --git a/lib/tasks/update_state_complainable_lo.rake b/lib/tasks/update_state_complainable_lo.rake
new file mode 100644
index 0000000000000000000000000000000000000000..c0494e506740c18486f3e6dec6cf8532e33d433f
--- /dev/null
+++ b/lib/tasks/update_state_complainable_lo.rake
@@ -0,0 +1,18 @@
+namespace :update_state_complainable_lo do
+    desc 'Update state of complainable learning objects'   
+    base_date = Date.new(2022, 7, 20)
+
+    task :update_lo => :environment do
+        Complaint.all.each do |complaint|
+            if (complaint.created_at < base_date)
+                # update the state of learning object to 0 (complained)
+                # check first if the lo exist
+                lo = LearningObject.where(id: complaint.complainable_id)
+                if (lo != nil)
+                    LearningObject.where(id: complaint.complainable_id).update(state: 2)    
+                end
+            end
+        end
+    
+    end
+end
\ No newline at end of file
diff --git a/public/attachments/16179/Dorwin_BL2.zip b/public/attachments/16179/Dorwin_BL2.zip
new file mode 100644
index 0000000000000000000000000000000000000000..9628a1431da2d94f9594d1a1b3e081e078be6f34
Binary files /dev/null and b/public/attachments/16179/Dorwin_BL2.zip differ
diff --git a/public/attachments/17505/Darwin_BL1.zip b/public/attachments/17505/Darwin_BL1.zip
new file mode 100644
index 0000000000000000000000000000000000000000..d00d054e00bf11af0c327939d047436eb5d11412
Binary files /dev/null and b/public/attachments/17505/Darwin_BL1.zip differ
diff --git a/public/attachments/23892/DOMINIO_EM_HIS_0146.wmv b/public/attachments/23892/DOMINIO_EM_HIS_0146.wmv
new file mode 100644
index 0000000000000000000000000000000000000000..26011a8d6bba99e22edcc7bb04374eb8a8a57bd9
Binary files /dev/null and b/public/attachments/23892/DOMINIO_EM_HIS_0146.wmv differ
diff --git a/public/attachments/23893/DOMINIO_EM_HIS_0146.mp4 b/public/attachments/23893/DOMINIO_EM_HIS_0146.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..2a4db961927582f681b1fdbb9840b4da65dcefbe
Binary files /dev/null and b/public/attachments/23893/DOMINIO_EM_HIS_0146.mp4 differ
diff --git a/public/attachments/27305/1421.torrent b/public/attachments/27305/1421.torrent
new file mode 100644
index 0000000000000000000000000000000000000000..78b72cecebb632170bde5551186d67d3dd75acdb
Binary files /dev/null and b/public/attachments/27305/1421.torrent differ
diff --git a/public/attachments/39961/15788.torrent b/public/attachments/39961/15788.torrent
new file mode 100644
index 0000000000000000000000000000000000000000..58010593cd2db332cf8ecc3a4925936db3a9ede5
--- /dev/null
+++ b/public/attachments/39961/15788.torrent
@@ -0,0 +1 @@
+<!doctype html><html lang="en"><head><title>HTTP Status 500 – Internal Server Error</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 – Internal Server Error</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Message</b> Internal Server Error</p><p><b>Description</b> The server encountered an unexpected condition that prevented it from fulfilling the request.</p><hr class="line" /><h3>Apache Tomcat/8.5.50 (Debian)</h3></body></html>
\ No newline at end of file
diff --git a/public/attachments/42061/19284.torrent b/public/attachments/42061/19284.torrent
new file mode 100644
index 0000000000000000000000000000000000000000..6570453075e51cd906d6a16694c364a584e1deab
Binary files /dev/null and b/public/attachments/42061/19284.torrent differ
diff --git a/public/attachments/44357/21974.torrent b/public/attachments/44357/21974.torrent
new file mode 100644
index 0000000000000000000000000000000000000000..491468f4e4e64753878cf6e0dbd883e6f9d842df
Binary files /dev/null and b/public/attachments/44357/21974.torrent differ
diff --git a/public/attachments/815/Construtores_-_Getulio_Vargas.avi b/public/attachments/815/Construtores_-_Getulio_Vargas.avi
new file mode 100644
index 0000000000000000000000000000000000000000..1760a72659f2bf1be372d75ec5d78aae9d9732f2
Binary files /dev/null and b/public/attachments/815/Construtores_-_Getulio_Vargas.avi differ
diff --git a/public/packages/020c4189ae59ad14acd33009.zip b/public/packages/020c4189ae59ad14acd33009.zip
new file mode 100644
index 0000000000000000000000000000000000000000..15cb0ecb3e219d1701294bfdf0fe3f5cb5d208e7
Binary files /dev/null and b/public/packages/020c4189ae59ad14acd33009.zip differ
diff --git a/public/packages/7807a34ad6716436c8aaad70.zip b/public/packages/7807a34ad6716436c8aaad70.zip
new file mode 100644
index 0000000000000000000000000000000000000000..15cb0ecb3e219d1701294bfdf0fe3f5cb5d208e7
Binary files /dev/null and b/public/packages/7807a34ad6716436c8aaad70.zip differ
diff --git a/public/packages/a4797832e60a51bafc3d1649.zip b/public/packages/a4797832e60a51bafc3d1649.zip
new file mode 100644
index 0000000000000000000000000000000000000000..15cb0ecb3e219d1701294bfdf0fe3f5cb5d208e7
Binary files /dev/null and b/public/packages/a4797832e60a51bafc3d1649.zip differ
diff --git a/public/packages/b17311d42455ec40ced445b4.zip b/public/packages/b17311d42455ec40ced445b4.zip
new file mode 100644
index 0000000000000000000000000000000000000000..368d1506b48cf3e32d3a3bd3514391d2956044c8
Binary files /dev/null and b/public/packages/b17311d42455ec40ced445b4.zip differ
diff --git a/public/packages/b46308de62f04b8f26dcd4fa.zip b/public/packages/b46308de62f04b8f26dcd4fa.zip
new file mode 100644
index 0000000000000000000000000000000000000000..141b5fb74f7af36b0614da86b29f6b2035524e45
Binary files /dev/null and b/public/packages/b46308de62f04b8f26dcd4fa.zip differ
diff --git a/public/packages/e7b7b7514f0511057033a8f9.zip b/public/packages/e7b7b7514f0511057033a8f9.zip
new file mode 100644
index 0000000000000000000000000000000000000000..d2edaa53201eb56afd416d8e16361b72cc9c1702
Binary files /dev/null and b/public/packages/e7b7b7514f0511057033a8f9.zip differ
diff --git a/public/packages/ec6842374053676f0039da44.zip b/public/packages/ec6842374053676f0039da44.zip
new file mode 100644
index 0000000000000000000000000000000000000000..73be0cd35e1a8cfb90ff044fa8a1709a8e49b80d
Binary files /dev/null and b/public/packages/ec6842374053676f0039da44.zip differ
diff --git a/puma.sh b/puma.sh
old mode 100644
new mode 100755
index a84c29d7235f8f9f7a51edd316e17d422b390b0d..1ea6eb158e166cf671c45f9ed02dad51143760ca
--- a/puma.sh
+++ b/puma.sh
@@ -18,9 +18,9 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
-source /home/.rvm/scripts/rvm
+source /home/portalmec/.rvm/scripts/rvm
 
-export PUMA_APP_DIR=/portalmec
+export PUMA_APP_DIR=/home/portalmec/portalmec-update/cleanning-portalmec
 
 source $PUMA_APP_DIR/config/env_vars.sh 2>/dev/null
 
@@ -28,10 +28,10 @@ option="${1}"
 
 case ${option} in
    start)
-      source start_puma.sh
+      source $PUMA_APP_DIR/start_puma.sh
       ;;
    stop)
-      source stop_puma.sh
+      source $PUMA_APP_DIR/stop_puma.sh
       ;;
    *)
       echo "`basename ${0}`:usage: [start] | [stop]"
diff --git a/spec/mailers/previews/user_preview.rb b/spec/mailers/previews/user_preview.rb
new file mode 100644
index 0000000000000000000000000000000000000000..61f7cff238934b146ca2d40285eb29a8e442d002
--- /dev/null
+++ b/spec/mailers/previews/user_preview.rb
@@ -0,0 +1,4 @@
+# Preview all emails at http://localhost:3000/rails/mailers/user
+class UserPreview < ActionMailer::Preview
+
+end
diff --git a/spec/mailers/user_spec.rb b/spec/mailers/user_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4a78b857a4acb52736297bb50d729b25a0612a42
--- /dev/null
+++ b/spec/mailers/user_spec.rb
@@ -0,0 +1,5 @@
+require "rails_helper"
+
+RSpec.describe UserMailer, type: :mailer do
+  pending "add some examples to (or delete) #{__FILE__}"
+end
diff --git a/start_puma.sh b/start_puma.sh
old mode 100644
new mode 100755
index 3cbfc0cfa935311bc9d5bb2bfb78fad8e60022aa..26f18d9f1eb16ba631557ef672022839c6b2e53d
--- a/start_puma.sh
+++ b/start_puma.sh
@@ -19,6 +19,7 @@
 # along with portalmec.  If not, see <http://www.gnu.org/licenses/>.
 
 source $PUMA_APP_DIR/config/env_vars.sh
+source /home/portalmec/.rvm/scripts/rvm
 
 cd $PUMA_APP_DIR
 #rake assets:precompile
diff --git a/stop_puma.sh b/stop_puma.sh
old mode 100644
new mode 100755