diff --git a/app/views/admins/components/_users.html.erb b/app/views/admins/components/_users.html.erb
index 21946232..aa0a6a3c 100644
--- a/app/views/admins/components/_users.html.erb
+++ b/app/views/admins/components/_users.html.erb
@@ -29,7 +29,7 @@
 %>
 
 <% unless @role.nil? %>
-  <%= render "shared/components/admins_tags" %>
+  <%= render "admins/components/admins_tags" %>
 <% end %>
 
 
@@ -88,7 +88,7 @@
                     
<%= user.provider %> | 
                     
                       <% roles = user.roles().pluck(:name) %>
-                      <%= render "shared/components/admins_role", role: user.highest_priority_role %>
+                      <%= render "admins/components/admins_role", role: user.highest_priority_role %>
                      | 
                     
                       <% if roles.include?("pending") %>
diff --git a/app/views/admins/edit_user.html.erb b/app/views/admins/edit_user.html.erb
index 54beeb8e..2b8f39ed 100644
--- a/app/views/admins/edit_user.html.erb
+++ b/app/views/admins/edit_user.html.erb
@@ -21,7 +21,7 @@
       <%= render "admins/components/menu_buttons" %>
     
      
-      <%= render "shared/settings/setting_view", setting_id: "account", setting_title: t("settings.account.subtitle") %>
+      <%= render "users/components/setting_view", setting_id: "account", setting_title: t("settings.account.subtitle") %>
      
   
 
diff --git a/app/views/shared/_features.html.erb b/app/views/main/components/_features.html.erb
similarity index 100%
rename from app/views/shared/_features.html.erb
rename to app/views/main/components/_features.html.erb
diff --git a/app/views/main/index.html.erb b/app/views/main/index.html.erb
index 6ecab633..d33db5be 100755
--- a/app/views/main/index.html.erb
+++ b/app/views/main/index.html.erb
@@ -28,4 +28,4 @@
   
 
 
-<%= render "shared/features" %>
+<%= render "main/components/features" %>
diff --git a/app/views/shared/components/_create_room_block.html.erb b/app/views/rooms/components/_create_room_block.html.erb
similarity index 100%
rename from app/views/shared/components/_create_room_block.html.erb
rename to app/views/rooms/components/_create_room_block.html.erb
diff --git a/app/views/shared/components/_room_block.html.erb b/app/views/rooms/components/_room_block.html.erb
similarity index 100%
rename from app/views/shared/components/_room_block.html.erb
rename to app/views/rooms/components/_room_block.html.erb
diff --git a/app/views/shared/_room_event.html.erb b/app/views/rooms/components/_room_event.html.erb
similarity index 100%
rename from app/views/shared/_room_event.html.erb
rename to app/views/rooms/components/_room_event.html.erb
diff --git a/app/views/rooms/join.html.erb b/app/views/rooms/join.html.erb
index 1e8496a4..84cb6e88 100644
--- a/app/views/rooms/join.html.erb
+++ b/app/views/rooms/join.html.erb
@@ -14,7 +14,7 @@
 %>
 
 <% valid_access_code = @room.access_code.nil? || @room.access_code.empty? || @room.access_code == session[:access_code] %>
-<%= render 'shared/room_event', render_recordings: valid_access_code do %>
+<%= render 'rooms/components/room_event', render_recordings: valid_access_code do %>
   <% if room_authentication_required %>
     <%= t("administrator.site_settings.authentication.user-info") %>
   <% elsif !valid_access_code %>
@@ -43,7 +43,7 @@
             readonly: !current_user.nil?, 
             autofocus: true
             %>
-        <%= f.submit (!@is_running && @anyone_can_start)? t("room.start") : t("room.join"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %>
+        <%= f.submit (!@room_running && @anyone_can_start)? t("room.start") : t("room.join"), class: "btn btn-primary btn-sm col-sm-3 form-control join-form" %>
       
     <% end %>
   <% end %>
diff --git a/app/views/rooms/show.html.erb b/app/views/rooms/show.html.erb
index 484b9f87..c8e55845 100644
--- a/app/views/rooms/show.html.erb
+++ b/app/views/rooms/show.html.erb
@@ -66,7 +66,7 @@
         <% end %>
       
       
-        <% if @is_running %>
+        <% if @room_running %>
           <%= button_to t("room.join"), room_path(@room), class: "btn btn-primary btn-block px-7 start-button float-right" %>
         <% else %>
           <% unless exceeds_limit %>
@@ -80,20 +80,20 @@
       <% if current_user.rooms.length > 1 %>
          
           <%= link_to current_user.main_room do %>
-            <%= render "shared/components/room_block", room: current_user.main_room %>
+            <%= render "rooms/components/room_block", room: current_user.main_room %>
           <% end %>
          
         <% current_user.secondary_rooms.each do |room| %>
            
             <%= link_to room do %>
-              <%= render "shared/components/room_block", room: room %>
+              <%= render "rooms/components/room_block", room: room %>
             <% end %>
            
-          <%= render "shared/modals/delete_room_modal", recording_count: room.recording_count, room: room %>
+          <%= render "shared/modals/delete_room_modal", room: room %>
         <% end %>
       <% end %>
       <% unless room_limit_exceeded %>
-        <%= render "shared/components/create_room_block"%>
+        <%= render "rooms/components/create_room_block"%>
       <% end %>
       
   
diff --git a/app/views/rooms/wait.html.erb b/app/views/rooms/wait.html.erb
index e93f153c..39171fbf 100644
--- a/app/views/rooms/wait.html.erb
+++ b/app/views/rooms/wait.html.erb
@@ -13,7 +13,7 @@
 # with BigBlueButton; if not, see .
 %>
 
-<%= render 'shared/room_event', render_recordings: true do %>
+<%= render 'rooms/components/room_event', render_recordings: true do %>
   
     
       <%= t("room.wait.message") %>
diff --git a/app/views/shared/components/_resend_button.html.erb b/app/views/shared/components/_resend_button.html.erb
deleted file mode 100644
index 368b347f..00000000
--- a/app/views/shared/components/_resend_button.html.erb
+++ /dev/null
@@ -1,18 +0,0 @@
-<%
-# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
-# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
-# This program is free software; you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free Software
-# Foundation; either version 3.0 of the License, or (at your option) any later
-# version.
-#
-# BigBlueButton 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 Lesser General Public License for more details.
-# You should have received a copy of the GNU Lesser General Public License along
-# with BigBlueButton; if not, see  .
-%>
-
- 
-    <%= button_to t("verify.resend"), resend_email_path, params: { email: params['email'], email_verified: false }, class: "btn btn-primary btn-space" %>
- 
diff --git a/app/views/shared/components/_subtitle.html.erb b/app/views/shared/components/_subtitle.html.erb
index f051494a..c959035a 100644
--- a/app/views/shared/components/_subtitle.html.erb
+++ b/app/views/shared/components/_subtitle.html.erb
@@ -14,12 +14,13 @@
 %>
 
  
-   
   <% if search %>
+     
+
      
-      <% if display_invite %>
+      <% if invite_registration %>
          
           <%= link_to "#inviteModal", :class => "btn btn-primary", "data-toggle": "modal" do %>
             <%= t("administrator.users.invite") %> 
@@ -43,6 +44,10 @@
          
        
     
+  <% else %>
+     
   <% end %>
   
 
diff --git a/app/views/shared/components/_terms_button.html.erb b/app/views/shared/components/_terms_button.html.erb
deleted file mode 100644
index de46d390..00000000
--- a/app/views/shared/components/_terms_button.html.erb
+++ /dev/null
@@ -1,18 +0,0 @@
-<%
-# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
-# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
-# This program is free software; you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free Software
-# Foundation; either version 3.0 of the License, or (at your option) any later
-# version.
-#
-# BigBlueButton 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 Lesser General Public License for more details.
-# You should have received a copy of the GNU Lesser General Public License along
-# with BigBlueButton; if not, see  .
-%>
-
- 
-    <%= button_to t("terms.accept_existing"), terms_path, params: { accept: true }, class: "btn btn-primary btn-space" %>
- 
\ No newline at end of file
diff --git a/app/views/shared/modals/_delete_room_modal.html.erb b/app/views/shared/modals/_delete_room_modal.html.erb
index 3b7a1d8d..1bc42949 100644
--- a/app/views/shared/modals/_delete_room_modal.html.erb
+++ b/app/views/shared/modals/_delete_room_modal.html.erb
@@ -34,8 +34,8 @@
         
diff --git a/app/views/shared/components/_confirm_button.html.erb b/app/views/users/change_password.html.erb
similarity index 67%
rename from app/views/shared/components/_confirm_button.html.erb
rename to app/views/users/change_password.html.erb
index 8fdba35b..a06f02b7 100644
--- a/app/views/shared/components/_confirm_button.html.erb
+++ b/app/views/users/change_password.html.erb
@@ -12,7 +12,15 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with BigBlueButton; if not, see  .
 %>
+ 
+  <%= render "shared/components/subtitle", subtitle: t("settings.title"), search: false %>
 
- 
-    <%= button_to t("verify.accept"), confirm_path, params: { user_uid: params[:user_uid], email_verified: true }, class: "btn btn-primary btn-space" %>
+   
+     
+      <%= render "users/components/menu_buttons" %>
+     
+     
+      <%= render "users/components/setting_view", setting_id: "password", setting_title: t("settings.password.subtitle") %>
+     
+    
 
diff --git a/app/views/shared/settings/_account.html.erb b/app/views/users/components/_account.html.erb
similarity index 100%
rename from app/views/shared/settings/_account.html.erb
rename to app/views/users/components/_account.html.erb
diff --git a/app/views/shared/settings/_delete.html.erb b/app/views/users/components/_delete.html.erb
similarity index 100%
rename from app/views/shared/settings/_delete.html.erb
rename to app/views/users/components/_delete.html.erb
diff --git a/app/views/users/components/_menu_buttons.html.erb b/app/views/users/components/_menu_buttons.html.erb
new file mode 100644
index 00000000..860aa86d
--- /dev/null
+++ b/app/views/users/components/_menu_buttons.html.erb
@@ -0,0 +1,26 @@
+<%
+# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
+# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
+# This program is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free Software
+# Foundation; either version 3.0 of the License, or (at your option) any later
+# version.
+#
+# BigBlueButton 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 Lesser General Public License for more details.
+# You should have received a copy of the GNU Lesser General Public License along
+# with BigBlueButton; if not, see  .
+%>
+
+ 
+  <%= link_to edit_user_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "edit"}" do %>
+    <%= t("settings.account.title") %>
+  <% end %>
+  <%= link_to change_password_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "change_password"}" do %>
+    <%= t("settings.password.title") %>
+  <% end %>
+  <%= link_to delete_account_path, class: "list-group-item list-group-item-action dropdown-item #{"active" if active_page == "delete_account"}" do %>
+    <%= t("settings.delete.title") %>
+  <% end %>
+ 
\ No newline at end of file
diff --git a/app/views/shared/settings/_password.html.erb b/app/views/users/components/_password.html.erb
similarity index 100%
rename from app/views/shared/settings/_password.html.erb
rename to app/views/users/components/_password.html.erb
diff --git a/app/views/shared/settings/_setting_view.html.erb b/app/views/users/components/_setting_view.html.erb
similarity index 92%
rename from app/views/shared/settings/_setting_view.html.erb
rename to app/views/users/components/_setting_view.html.erb
index 4c8b8bd2..915cdb06 100644
--- a/app/views/shared/settings/_setting_view.html.erb
+++ b/app/views/users/components/_setting_view.html.erb
@@ -17,10 +17,10 @@
    
     
       
-        <%= render "shared/components/subtitle", subtitle: setting_title, search: setting_id == "users" %>
+        <%= render "shared/components/subtitle", subtitle: setting_title, search: false %>
        
      
 
-    <%= render "shared/settings/#{setting_id}" %>
+    <%= render "users/components/#{setting_id}" %>
     
 <% end %>
diff --git a/app/views/shared/settings/_design.html.erb b/app/views/users/delete_account.html.erb
similarity index 70%
rename from app/views/shared/settings/_design.html.erb
rename to app/views/users/delete_account.html.erb
index e4f794c4..c05727cf 100644
--- a/app/views/shared/settings/_design.html.erb
+++ b/app/views/users/delete_account.html.erb
@@ -12,11 +12,15 @@
 # You should have received a copy of the GNU Lesser General Public License along
 # with BigBlueButton; if not, see  .
 %>
+ 
+  <%= render "shared/components/subtitle", subtitle: t("settings.title"), search: false %>
 
- 
           <% if Rails.configuration.terms && current_user && !current_user.accepted_terms %>
-            <%= render "/shared/components/terms_button" %>
+             
+              <%= button_to t("terms.accept_existing"), terms_path, params: { accept: true }, class: "btn btn-primary btn-space" %>
+             
           <% end %>
         
        
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index d6f059f0..2f4b4f6b 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -1,6 +1,9 @@
 # frozen_string_literal: true
 
 require 'office365'
+require 'omniauth_options'
+
+include OmniauthOptions
 
 # List of supported Omniauth providers.
 Rails.application.config.providers = []
@@ -16,7 +19,7 @@ Rails.application.config.omniauth_office365 = ENV['OFFICE365_KEY'].present? &&
                                               ENV['OFFICE365_SECRET'].present?
 
 SETUP_PROC = lambda do |env|
-  SessionsController.helpers.omniauth_options env
+  OmniauthOptions.omniauth_options env
 end
 
 OmniAuth.config.logger = Rails.logger
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 9966b463..0c5c68f2 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -88,10 +88,9 @@ en:
     roles:
       can_create_rooms: Can create rooms
       delete: Delete the role
-      duplicate_name: The role name you provided was a duplicate. All role names must be unique
-      empty_name: All roles must have a non empty name
-      invalid_order: The user role must be the lowest priority role and the admin role must be the highest priority role
-      invalid_update: You can't update a role with a higher priority than your own role
+      invalid_create: There was a problem creating a new role. Please check the role values and try again
+      invalid_order: There was a problem updating the priority of the role. Please check the values and try again
+      invalid_update: There was a problem updating the permissions of the role. Please check the values and try again
       name: Role Name
       new_role: Create a new role
       role_has_users: This role is assigned to %{user_count} accounts. Please remove all accounts from this role before deleting it.
@@ -101,8 +100,7 @@ en:
       edit_site_settings: Allow users with this role to edit site settings
       edit_roles: Allow users with this role to edit other roles
       manage_users: Allow users with this role to manage users
-      invalid_assignment: You can't assign a role with a higher priority than your own to a user
-      invalid_removal: You can't remove a role with a higher priority than your own
+      invalid_assignment: There was a problem assigning the roles to the user. Please check the values and try again 
       colour:
         title: Role Colour
         info: Set the colour that will be associated with the role
diff --git a/config/routes.rb b/config/routes.rb
index 49b80ce3..850c5266 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -37,25 +37,23 @@ Rails.application.routes.draw do
   resources :admins, only: [:index]
 
   scope '/admins' do
-    get '/site_settings', to: 'admins#site_settings', as: :admin_site_settings
+    # Panel Tabs
     get '/recordings', to: 'admins#server_recordings', as: :admin_recordings
-    post '/branding', to: 'admins#branding', as: :admin_branding
-    post '/coloring', to: 'admins#coloring', as: :admin_coloring
-    post '/room_authentication', to: 'admins#room_authentication', as: :admin_room_authentication
-    post '/coloring_lighten', to: 'admins#coloring_lighten', as: :admin_coloring_lighten
-    post '/coloring_darken', to: 'admins#coloring_darken', as: :admin_coloring_darken
-    post '/signup', to: 'admins#signup', as: :admin_signup
+    get '/site_settings', to: 'admins#site_settings', as: :admin_site_settings
+    get '/roles', to: 'admins#roles', as: :admin_roles
+    # Manage Users
     get '/edit/:user_uid', to: 'admins#edit_user', as: :admin_edit_user
     post '/ban/:user_uid', to: 'admins#ban_user', as: :admin_ban
     post '/unban/:user_uid', to: 'admins#unban_user', as: :admin_unban
     post '/invite', to: 'admins#invite', as: :invite_user
-    post '/registration_method/:method', to: 'admins#registration_method', as: :admin_change_registration
     post '/approve/:user_uid', to: 'admins#approve', as: :admin_approve
     get '/reset', to: 'admins#reset', as: :admin_reset
-    post '/room_limit', to: 'admins#room_limit', as: :admin_room_limit
-    post '/default_recording_visibility', to: 'admins#default_recording_visibility', as: :admin_recording_visibility
+    # Site Settings
+    post '/update_settings', to: 'admins#update_settings', as: :admin_update_settings
+    post '/registration_method', to: 'admins#registration_method', as: :admin_change_registration
+    post '/coloring', to: 'admins#coloring', as: :admin_coloring
     post '/clear_cache', to: 'admins#clear_cache', as: :admin_clear_cache
-    get '/roles', to: 'admins#roles', as: :admin_roles
+    # Roles
     post '/role', to: 'admins#new_role', as: :admin_new_role
     patch 'roles/order', to: 'admins#change_role_order', as: :admin_roles_order
     post '/role/:role_id', to: 'admins#update_role', as: :admin_update_role
@@ -86,6 +84,8 @@ Rails.application.routes.draw do
 
     # Account management.
     get '/:user_uid/edit', to: 'users#edit', as: :edit_user
+    get '/:user_uid/change_password', to: 'users#change_password', as: :change_password
+    get '/:user_uid/delete_account', to: 'users#delete_account', as: :delete_account
     patch '/:user_uid/edit', to: 'users#update', as: :update_user
     delete '/:user_uid', to: 'users#destroy', as: :delete_user
 
@@ -118,8 +118,8 @@ Rails.application.routes.draw do
   scope '/:meetingID' do
     # Manage recordings
     scope '/:record_id' do
-      post '/', to: 'recordings#update_recording', as: :update_recording
-      delete '/', to: 'recordings#delete_recording', as: :delete_recording
+      post '/', to: 'recordings#update', as: :update_recording
+      delete '/', to: 'recordings#delete', as: :delete_recording
     end
   end
 
diff --git a/lib/omniauth_options.rb b/lib/omniauth_options.rb
new file mode 100644
index 00000000..0440f527
--- /dev/null
+++ b/lib/omniauth_options.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
+#
+# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
+#
+# This program is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free Software
+# Foundation; either version 3.0 of the License, or (at your option) any later
+# version.
+#
+# BigBlueButton 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with BigBlueButton; if not, see  .
+
+module OmniauthOptions
+  module_function
+
+  def omniauth_options(env)
+    if env['omniauth.strategy'].options[:name] == "bn_launcher"
+      protocol = Rails.env.production? ? "https" : env["rack.url_scheme"]
+
+      customer_redirect_url = protocol + "://" + env["SERVER_NAME"] + ":" +
+                              env["SERVER_PORT"]
+      user_domain = parse_user_domain(env["SERVER_NAME"])
+      env['omniauth.strategy'].options[:customer] = user_domain
+      env['omniauth.strategy'].options[:customer_redirect_url] = customer_redirect_url
+      env['omniauth.strategy'].options[:default_callback_url] = Rails.configuration.gl_callback_url
+
+      # This is only used in the old launcher and should eventually be removed
+      env['omniauth.strategy'].options[:checksum] = generate_checksum(user_domain, customer_redirect_url,
+        Rails.configuration.launcher_secret)
+    elsif env['omniauth.strategy'].options[:name] == "google"
+      set_hd(env, ENV['GOOGLE_OAUTH2_HD'])
+    elsif env['omniauth.strategy'].options[:name] == "office365"
+      set_hd(env, ENV['OFFICE365_HD'])
+    end
+  end
+
+  # Limits the domain that can be used with the provider
+  def set_hd(env, hd)
+    if hd
+      hd_opts = hd.split(',')
+      env['omniauth.strategy'].options[:hd] = if hd_opts.empty?
+        nil
+      elsif hd_opts.length == 1
+        hd_opts[0]
+      else
+        hd_opts
+      end
+    end
+  end
+
+  # Parses the url for the user domain
+  def parse_user_domain(hostname)
+    return hostname.split('.').first if Rails.configuration.url_host.empty?
+    Rails.configuration.url_host.split(',').each do |url_host|
+      return hostname.chomp(url_host).chomp('.') if hostname.include?(url_host)
+    end
+    ''
+  end
+
+  # Generates a checksum to use alongside the omniauth request
+  def generate_checksum(user_domain, redirect_url, secret)
+    string = user_domain + redirect_url + secret
+    OpenSSL::Digest.digest('sha1', string).unpack1("H*")
+  end
+end
diff --git a/spec/concerns/bbb_server_spec.rb b/spec/concerns/bbb_server_spec.rb
new file mode 100644
index 00000000..350bcee0
--- /dev/null
+++ b/spec/concerns/bbb_server_spec.rb
@@ -0,0 +1,88 @@
+# frozen_string_literal: true
+
+# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
+#
+# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
+#
+# This program is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free Software
+# Foundation; either version 3.0 of the License, or (at your option) any later
+# version.
+#
+# BigBlueButton 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with BigBlueButton; if not, see  .
+
+require "rails_helper"
+require 'bigbluebutton_api'
+
+describe BbbServer do
+  include BbbServer
+
+  let(:bbb_server) { BigBlueButton::BigBlueButtonApi.new("http://bbb.example.com/bigbluebutton/api", "secret", "0.8") }
+
+  before do
+    @user = create(:user)
+    @room = @user.main_room
+  end
+
+  context "#running?" do
+    it "should return false when not running" do
+      expect(room_running?(@room.bbb_id)).to be false
+    end
+
+    it "should return true when running" do
+      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
+      expect(room_running?(@room.bbb_id)).to be true
+    end
+  end
+
+  context "#start_session" do
+    it "should update latest session info" do
+      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:create_meeting).and_return(
+        messageKey: ""
+      )
+
+      expect do
+        start_session(@room)
+      end.to change { @room.sessions }.by(1)
+
+      expect(@room.last_session).not_to be nil
+    end
+  end
+
+  context "#join_path" do
+    it "should return correct join URL for user" do
+      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
+        attendeePW: @room.attendee_pw
+      )
+
+      endpoint = Rails.configuration.bigbluebutton_endpoint
+      secret = Rails.configuration.bigbluebutton_secret
+      fullname = "fullName=Example"
+      join_via_html5 = "&join_via_html5=true"
+      meeting_id = "&meetingID=#{@room.bbb_id}"
+      password = "&password=#{@room.attendee_pw}"
+
+      query = fullname + join_via_html5 + meeting_id + password
+      checksum_string = "join#{query + secret}"
+
+      checksum = OpenSSL::Digest.digest('sha1', checksum_string).unpack1("H*")
+      expect(join_path(@room, "Example")).to eql("#{endpoint}join?#{query}&checksum=#{checksum}")
+    end
+  end
+
+  context "#recordings" do
+    it "deletes the recording" do
+      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:delete_recordings).and_return(
+        returncode: true, deleted: true
+      )
+
+      expect(delete_recording(Faker::IDNumber.valid))
+        .to contain_exactly([:returncode, true], [:deleted, true])
+    end
+  end
+end
diff --git a/spec/concerns/recorder_spec.rb b/spec/concerns/recorder_spec.rb
index 7e082e1f..1a740a24 100644
--- a/spec/concerns/recorder_spec.rb
+++ b/spec/concerns/recorder_spec.rb
@@ -19,13 +19,15 @@
 require "rails_helper"
 require 'bigbluebutton_api'
 
-shared_examples_for "recorder" do
-  let(:controller) { described_class } # the class that includes the concern
+describe Recorder do
+  include Recorder
+  include BbbServer
+
+  let(:bbb_server) { BigBlueButton::BigBlueButtonApi.new("http://bbb.example.com/bigbluebutton/api", "secret", "0.8") }
 
   before do
     @user = create(:user)
     @room = @user.main_room
-
     allow_any_instance_of(Room).to receive(:owner).and_return(@user)
   end
 
@@ -44,7 +46,7 @@ shared_examples_for "recorder" do
       ]
     )
 
-    expect(recordings(@room.bbb_id, @room.owner.provider)).to contain_exactly(
+    expect(recordings(@room.bbb_id)).to contain_exactly(
       name: "Example",
       playbacks:
       [
@@ -118,7 +120,7 @@ shared_examples_for "recorder" do
       ]
     )
 
-    expect(all_recordings(@user.rooms.pluck(:bbb_id), @user.provider, search: "Exam", column: "name",
+    expect(all_recordings(@user.rooms.pluck(:bbb_id), search: "Exam", column: "name",
       direction: "desc")).to eq(
         [
           {
@@ -219,7 +221,7 @@ shared_examples_for "recorder" do
     end
 
     it "should filter recordings on name" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, search: "Exam")).to contain_exactly(
+      expect(recordings(@room.bbb_id, search: "Exam")).to contain_exactly(
         {
           meetingID: @room.bbb_id,
           name: "aExamaaa",
@@ -250,7 +252,7 @@ shared_examples_for "recorder" do
     end
 
     it "should filter recordings on participants" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, search: "5")).to contain_exactly(
+      expect(recordings(@room.bbb_id, search: "5")).to contain_exactly(
         meetingID: @room.bbb_id,
         name: "aExamaaa",
         participants: "5",
@@ -267,7 +269,7 @@ shared_examples_for "recorder" do
     end
 
     it "should filter recordings on format" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, search: "presentation")).to contain_exactly(
+      expect(recordings(@room.bbb_id, search: "presentation")).to contain_exactly(
         {
           meetingID: @room.bbb_id,
           name: "test",
@@ -298,7 +300,7 @@ shared_examples_for "recorder" do
     end
 
     it "should filter recordings on visibility" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, search: "public")).to contain_exactly(
+      expect(recordings(@room.bbb_id, search: "public")).to contain_exactly(
         {
           meetingID: @room.bbb_id,
           name: "test",
@@ -329,7 +331,7 @@ shared_examples_for "recorder" do
     end
 
     it "should filter recordings on metadata name by default" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, search: "metadata")).to contain_exactly(
+      expect(recordings(@room.bbb_id, search: "metadata")).to contain_exactly(
         meetingID: @room.bbb_id,
         name: "Exam",
         participants: "1",
@@ -385,7 +387,7 @@ shared_examples_for "recorder" do
     end
 
     it "should sort recordings on name" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, column: "name", direction: "asc")).to eq(
+      expect(recordings(@room.bbb_id, column: "name", direction: "asc")).to eq(
         [
           {
             meetingID: @room.bbb_id,
@@ -421,7 +423,7 @@ shared_examples_for "recorder" do
     end
 
     it "should sort recordings on participants" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, column: "users", direction: "desc")).to eq(
+      expect(recordings(@room.bbb_id, column: "users", direction: "desc")).to eq(
         [
           {
             meetingID: @room.bbb_id,
@@ -457,7 +459,7 @@ shared_examples_for "recorder" do
     end
 
     it "should sort recordings on visibility" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, column: "visibility", direction: "desc")).to eq(
+      expect(recordings(@room.bbb_id, column: "visibility", direction: "desc")).to eq(
         [
           {
             meetingID: @room.bbb_id,
@@ -493,7 +495,7 @@ shared_examples_for "recorder" do
     end
 
     it "should sort recordings on length" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, column: "length", direction: "asc")).to eq(
+      expect(recordings(@room.bbb_id, column: "length", direction: "asc")).to eq(
         [
           {
             meetingID: @room.bbb_id,
@@ -529,7 +531,7 @@ shared_examples_for "recorder" do
     end
 
     it "should sort recordings on format" do
-      expect(recordings(@room.bbb_id, @room.owner.provider, column: "formats", direction: "desc")).to eq(
+      expect(recordings(@room.bbb_id, column: "formats", direction: "desc")).to eq(
         [
           {
             meetingID: @room.bbb_id,
diff --git a/spec/controllers/account_activations_controller_spec.rb b/spec/controllers/account_activations_controller_spec.rb
index 9c5c5632..7fb4fcbd 100644
--- a/spec/controllers/account_activations_controller_spec.rb
+++ b/spec/controllers/account_activations_controller_spec.rb
@@ -37,7 +37,7 @@ describe AccountActivationsController, type: :controller do
 
       get :show, params: { email: user.email }
 
-      expect(response).to render_template(:verify)
+      expect(response).to render_template(:show)
     end
   end
 
diff --git a/spec/controllers/admins_controller_spec.rb b/spec/controllers/admins_controller_spec.rb
index 8a9d73f9..8f440df0 100644
--- a/spec/controllers/admins_controller_spec.rb
+++ b/spec/controllers/admins_controller_spec.rb
@@ -91,7 +91,7 @@ describe AdminsController, type: :controller do
     context "POST #invite" do
       before do
         allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
-        allow_any_instance_of(ApplicationController).to receive(:allow_greenlight_users?).and_return(true)
+        allow_any_instance_of(ApplicationController).to receive(:allow_greenlight_accounts?).and_return(true)
         allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
       end
 
@@ -177,7 +177,7 @@ describe AdminsController, type: :controller do
         @request.session[:user_id] = @admin.id
         fake_image_url = "example.com"
 
-        post :branding, params: { url: fake_image_url }
+        post :update_settings, params: { setting: "Branding Image", value: fake_image_url }
 
         feature = Setting.find_by(provider: "provider1").features.find_by(name: "Branding Image")
 
@@ -194,7 +194,7 @@ describe AdminsController, type: :controller do
         @request.session[:user_id] = @admin.id
         primary_color = Faker::Color.hex_color
 
-        post :coloring, params: { color: primary_color }
+        post :coloring, params: { value: primary_color }
 
         feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color")
 
@@ -209,7 +209,7 @@ describe AdminsController, type: :controller do
         @request.session[:user_id] = @admin.id
         primary_color = Faker::Color.hex_color
 
-        post :coloring_lighten, params: { color: primary_color }
+        post :update_settings, params: { setting: "Primary Color Lighten", value: primary_color }
 
         feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Lighten")
 
@@ -224,7 +224,7 @@ describe AdminsController, type: :controller do
         @request.session[:user_id] = @admin.id
         primary_color = Faker::Color.hex_color
 
-        post :coloring_darken, params: { color: primary_color }
+        post :update_settings, params: { setting: "Primary Color Darken", value: primary_color }
 
         feature = Setting.find_by(provider: "provider1").features.find_by(name: "Primary Color Darken")
 
@@ -243,7 +243,7 @@ describe AdminsController, type: :controller do
 
         @request.session[:user_id] = @admin.id
 
-        post :registration_method, params: { method: "invite" }
+        post :registration_method, params: { value: "invite" }
 
         feature = Setting.find_by(provider: "provider1").features.find_by(name: "Registration Method")
 
@@ -259,7 +259,7 @@ describe AdminsController, type: :controller do
 
         @request.session[:user_id] = @admin.id
 
-        post :registration_method, params: { method: "invite" }
+        post :registration_method, params: { value: "invite" }
 
         expect(flash[:alert]).to be_present
         expect(response).to redirect_to(admin_site_settings_path)
@@ -273,7 +273,7 @@ describe AdminsController, type: :controller do
 
         @request.session[:user_id] = @admin.id
 
-        post :room_authentication, params: { value: "true" }
+        post :update_settings, params: { setting: "Room Authentication", value: "true" }
 
         feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Authentication")
 
@@ -289,7 +289,7 @@ describe AdminsController, type: :controller do
 
         @request.session[:user_id] = @admin.id
 
-        post :room_limit, params: { limit: 5 }
+        post :update_settings, params: { setting: "Room Limit", value: 5 }
 
         feature = Setting.find_by(provider: "provider1").features.find_by(name: "Room Limit")
 
@@ -305,7 +305,7 @@ describe AdminsController, type: :controller do
 
         @request.session[:user_id] = @admin.id
 
-        post :default_recording_visibility, params: { visibility: "public" }
+        post :update_settings, params: { setting: "Default Recording Visibility", value: "public" }
 
         feature = Setting.find_by(provider: "provider1").features.find_by(name: "Default Recording Visibility")
 
@@ -353,7 +353,7 @@ describe AdminsController, type: :controller do
         post :new_role, params: { role: { name: "admin" } }
 
         expect(response).to redirect_to admin_roles_path
-        expect(flash[:alert]).to eq(I18n.t("administrator.roles.duplicate_name"))
+        expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_create"))
       end
 
       it "should fail with empty role name" do
@@ -362,7 +362,7 @@ describe AdminsController, type: :controller do
         post :new_role, params: { role: { name: "    " } }
 
         expect(response).to redirect_to admin_roles_path
-        expect(flash[:alert]).to eq(I18n.t("administrator.roles.empty_name"))
+        expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_create"))
       end
 
       it "should create new role and increase user role priority" do
@@ -412,7 +412,7 @@ describe AdminsController, type: :controller do
 
         patch :change_role_order, params: { role: [new_role3.id, new_role2.id] }
 
-        expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update"))
+        expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_order"))
         expect(response).to redirect_to admin_roles_path
       end
 
@@ -432,7 +432,7 @@ describe AdminsController, type: :controller do
 
         patch :change_role_order, params: { role: [new_role3.id, new_role2.id] }
 
-        expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update"))
+        expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_order"))
         expect(response).to redirect_to admin_roles_path
       end
 
@@ -489,7 +489,7 @@ describe AdminsController, type: :controller do
 
         patch :update_role, params: { role_id: new_role.id, role: { name: "admin" } }
 
-        expect(flash[:alert]).to eq(I18n.t("administrator.roles.duplicate_name"))
+        expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_update"))
         expect(response).to redirect_to admin_roles_path(selected_role: new_role.id)
       end
 
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 0085a6e7..ff05ea6d 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -63,6 +63,64 @@ describe ApplicationController do
     end
   end
 
+  context "getters" do
+    it "returns whether user signup is allowed" do
+      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
+
+      expect(controller.allow_user_signup?).to eql(true)
+    end
+
+    it "returns whether the default bbb endpoint is being used" do
+      allow(Rails.configuration).to receive(:bigbluebutton_endpoint)
+        .and_return("http://test-install.blindsidenetworks.com/bigbluebutton/api/")
+      allow(Rails.configuration).to receive(:bigbluebutton_endpoint_default)
+        .and_return("http://test-install.blindsidenetworks.com/bigbluebutton/api/")
+
+      expect(controller.bigbluebutton_endpoint_default?).to eql(true)
+    end
+  end
+
+  context "allow_greenlight_accounts" do
+    it "allows if user sign up is turned on" do
+      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(false)
+      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
+
+      expect(controller.allow_greenlight_accounts?).to eql(true)
+    end
+
+    it "doesn't allow if user sign up is turned off" do
+      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(false)
+      allow(Rails.configuration).to receive(:allow_user_signup).and_return(false)
+
+      expect(controller.allow_greenlight_accounts?).to eql(false)
+    end
+
+    it "doesn't allow if user_domain is blank" do
+      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
+      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
+
+      expect(controller.allow_greenlight_accounts?).to eql(false)
+    end
+
+    it "allows if user provider is set to greenlight" do
+      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
+      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
+      allow(controller).to receive(:retrieve_provider_info).and_return("provider" => "greenlight")
+      controller.instance_variable_set(:@user_domain, "provider1")
+
+      expect(controller.allow_greenlight_accounts?).to eql(true)
+    end
+
+    it "doesnt allow if user provider is not set to greenlight" do
+      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
+      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
+      allow(controller).to receive(:retrieve_provider_info).and_return("provider" => "google")
+      controller.instance_variable_set(:@user_domain, "provider1")
+
+      expect(controller.allow_greenlight_accounts?).to eql(false)
+    end
+  end
+
   context "errors" do
     it "renders a BigBlueButton error if a BigBlueButtonException occurrs" do
       routes.draw { get "error" => "anonymous#error" }
@@ -74,7 +132,7 @@ describe ApplicationController do
     it "renders a 404 error if user is not found" do
       allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
       allow(Rails.env).to receive(:test?).and_return(false)
-      allow_any_instance_of(SessionsHelper).to receive(:parse_user_domain).and_return("fake_provider")
+      allow_any_instance_of(ApplicationController).to receive(:parse_user_domain).and_return("fake_provider")
       allow_any_instance_of(BbbApi).to receive(:retrieve_provider_info).and_raise("No user with that id exists")
 
       routes.draw { get "user_not_found" => "anonymous#user_not_found" }
@@ -86,7 +144,7 @@ describe ApplicationController do
     it "renders a 404 error if user is not given" do
       allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
       allow(Rails.env).to receive(:test?).and_return(false)
-      allow_any_instance_of(SessionsHelper).to receive(:parse_user_domain).and_return("")
+      allow_any_instance_of(ApplicationController).to receive(:parse_user_domain).and_return("")
       allow_any_instance_of(BbbApi).to receive(:retrieve_provider_info).and_raise("Provider not included.")
 
       routes.draw { get "user_not_found" => "anonymous#user_not_found" }
@@ -98,7 +156,7 @@ describe ApplicationController do
     it "renders a 500 error if any other error related to bbb api" do
       allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
       allow(Rails.env).to receive(:test?).and_return(false)
-      allow_any_instance_of(SessionsHelper).to receive(:parse_user_domain).and_return("")
+      allow_any_instance_of(ApplicationController).to receive(:parse_user_domain).and_return("")
       allow_any_instance_of(BbbApi).to receive(:retrieve_provider_info).and_raise("Other error")
 
       routes.draw { get "user_not_found" => "anonymous#user_not_found" }
diff --git a/spec/controllers/password_resets_controller_spec.rb b/spec/controllers/password_resets_controller_spec.rb
index 5fedb819..82ae4475 100644
--- a/spec/controllers/password_resets_controller_spec.rb
+++ b/spec/controllers/password_resets_controller_spec.rb
@@ -73,7 +73,9 @@ describe PasswordResetsController, type: :controller do
   end
 
   describe "PATCH #update" do
-    before { allow(Rails.configuration).to receive(:enable_email_verification).and_return(true) }
+    before do
+      allow(Rails.configuration).to receive(:enable_email_verification).and_return(true)
+    end
 
     context "valid user" do
       it "reloads page with notice if password is empty" do
@@ -120,7 +122,7 @@ describe PasswordResetsController, type: :controller do
 
         allow(controller).to receive(:valid_user).and_return(nil)
         allow(controller).to receive(:check_expiration).and_return(nil)
-        allow(controller).to receive(:current_user).and_return(user)
+        controller.instance_variable_set(:@user, user)
 
         params = {
           id: token,
diff --git a/spec/controllers/recordings_controller_spec.rb b/spec/controllers/recordings_controller_spec.rb
index c66764e6..f7f23b14 100644
--- a/spec/controllers/recordings_controller_spec.rb
+++ b/spec/controllers/recordings_controller_spec.rb
@@ -27,10 +27,10 @@ describe RecordingsController, type: :controller do
 
   context "POST #update_recording" do
     it "updates the recordings details" do
-      allow_any_instance_of(Room).to receive(:update_recording).and_return(updated: true)
+      allow_any_instance_of(BbbServer).to receive(:update_recording).and_return(updated: true)
       @request.session[:user_id] = @user.uid
 
-      post :update_recording, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
+      post :update, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
 
       expect(response).to have_http_status(302)
     end
@@ -38,7 +38,7 @@ describe RecordingsController, type: :controller do
     it "redirects to root if not the room owner" do
       @request.session[:user_id] = @secondary_user.uid
 
-      post :update_recording, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
+      post :update, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
 
       expect(response).to redirect_to(root_path)
     end
@@ -46,10 +46,10 @@ describe RecordingsController, type: :controller do
 
   context "DELETE #delete_recording" do
     it "deletes the recording" do
-      allow_any_instance_of(Room).to receive(:delete_recording).and_return(true)
+      allow_any_instance_of(BbbServer).to receive(:delete_recording).and_return(true)
       @request.session[:user_id] = @user.uid
 
-      post :delete_recording, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
+      post :delete, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
 
       expect(response).to have_http_status(302)
     end
@@ -57,7 +57,7 @@ describe RecordingsController, type: :controller do
     it "redirects to root if not the room owner" do
       @request.session[:user_id] = @secondary_user.uid
 
-      post :delete_recording, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
+      post :delete, params: { meetingID: @room.bbb_id, record_id: Faker::IDNumber.valid, state: "public" }
 
       expect(response).to redirect_to(root_path)
     end
diff --git a/spec/controllers/rooms_controller_spec.rb b/spec/controllers/rooms_controller_spec.rb
index 1424ab66..e3062ed9 100644
--- a/spec/controllers/rooms_controller_spec.rb
+++ b/spec/controllers/rooms_controller_spec.rb
@@ -28,8 +28,11 @@ def random_valid_room_params
 end
 
 describe RoomsController, type: :controller do
-  it_behaves_like "recorder"
   include Recorder
+  include BbbServer
+
+  let(:bbb_server) { BigBlueButton::BigBlueButtonApi.new("http://bbb.example.com/bigbluebutton/api", "secret", "0.8") }
+
   describe "GET #show" do
     before do
       @user = create(:user)
@@ -41,8 +44,7 @@ describe RoomsController, type: :controller do
 
       get :show, params: { room_uid: @owner.main_room }
 
-      expect(assigns(:recordings)).to eql(recordings(@owner.main_room.bbb_id, @owner.provider))
-      expect(assigns(:is_running)).to eql(@owner.main_room.running?)
+      expect(assigns(:recordings)).to eql(recordings(@owner.main_room.bbb_id))
     end
 
     it "should be able to search recordings if user is owner" do
@@ -199,11 +201,6 @@ describe RoomsController, type: :controller do
       @user = create(:user)
       @owner = create(:user)
       @room = @owner.main_room
-
-      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
-        moderatorPW: "modpass",
-        attendeePW: "attpass",
-      )
     end
 
     it "should use account name if user is logged in and meeting running" do
@@ -212,7 +209,7 @@ describe RoomsController, type: :controller do
       @request.session[:user_id] = @user.id
       post :join, params: { room_uid: @room, join_name: @user.name }
 
-      expect(response).to redirect_to(@owner.main_room.join_path(@user.name, {}, @user.uid))
+      expect(response).to redirect_to(join_path(@owner.main_room, @user.name, {}, @user.uid))
     end
 
     it "should use join name if user is not logged in and meeting running" do
@@ -220,7 +217,7 @@ describe RoomsController, type: :controller do
 
       post :join, params: { room_uid: @room, join_name: "Join Name" }
 
-      expect(response).to redirect_to(@owner.main_room.join_path("Join Name", {}))
+      expect(response).to redirect_to(join_path(@owner.main_room, "Join Name", {}))
     end
 
     it "should render wait if meeting isn't running" do
@@ -243,7 +240,7 @@ describe RoomsController, type: :controller do
       @request.session[:user_id] = @user.id
       post :join, params: { room_uid: room, join_name: @user.name }
 
-      expect(response).to redirect_to(room.join_path(@user.name, { user_is_moderator: false }, @user.uid))
+      expect(response).to redirect_to(join_path(room, @user.name, { user_is_moderator: false }, @user.uid))
     end
 
     it "should join the room as moderator if room has the all_join_moderator setting" do
@@ -257,7 +254,7 @@ describe RoomsController, type: :controller do
       @request.session[:user_id] = @user.id
       post :join, params: { room_uid: room, join_name: @user.name }
 
-      expect(response).to redirect_to(room.join_path(@user.name, { user_is_moderator: true }, @user.uid))
+      expect(response).to redirect_to(join_path(room, @user.name, { user_is_moderator: true }, @user.uid))
     end
 
     it "should render wait if the correct access code is supplied" do
@@ -292,7 +289,7 @@ describe RoomsController, type: :controller do
       @request.session[:user_id] = @owner.id
       post :join, params: { room_uid: @room, join_name: @owner.name }
 
-      expect(response).to redirect_to(@owner.main_room.join_path(@owner.name, { user_is_moderator: true }, @owner.uid))
+      expect(response).to redirect_to(join_path(@owner.main_room, @owner.name, { user_is_moderator: true }, @owner.uid))
     end
 
     it "redirects to root if owner of room is not verified" do
@@ -362,7 +359,7 @@ describe RoomsController, type: :controller do
       @request.session[:user_id] = @user.id
       post :start, params: { room_uid: @user.main_room }
 
-      expect(response).to redirect_to(@user.main_room.join_path(@user.name, { user_is_moderator: true }, @user.uid))
+      expect(response).to redirect_to(join_path(@user.main_room, @user.name, { user_is_moderator: true }, @user.uid))
     end
 
     it "should bring to room if not owner" do
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 97c71ce5..1a603aac 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -373,7 +373,7 @@ describe UsersController, type: :controller do
 
         user.reload
 
-        expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_removal"))
+        expect(flash[:alert]).to eq(I18n.t("administrator.roles.invalid_assignment"))
         expect(response).to render_template(:edit)
       end
 
@@ -439,7 +439,6 @@ describe UsersController, type: :controller do
     it "allows admins to delete users" do
       allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
       allow_any_instance_of(User).to receive(:greenlight_account?).and_return(true)
-      allow_any_instance_of(Room).to receive(:delete_all_recordings).and_return('')
       allow_any_instance_of(ApplicationController).to receive(:set_user_domain).and_return("provider1")
       controller.instance_variable_set(:@user_domain, "provider1")
 
diff --git a/spec/helpers/admins_helper_spec.rb b/spec/helpers/admins_helper_spec.rb
deleted file mode 100644
index e690bd35..00000000
--- a/spec/helpers/admins_helper_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
-#
-# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
-#
-# This program is free software; you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free Software
-# Foundation; either version 3.0 of the License, or (at your option) any later
-# version.
-#
-# BigBlueButton 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with BigBlueButton; if not, see  .
-
-require "rails_helper"
-
-describe AdminsHelper do
-  describe "edit_disabled" do
-    it "should disable inputs for roles with a higher priority" do
-        user = create(:user)
-        admin_role = Role.find_by(name: "admin", provider: "greenlight")
-        helper.instance_variable_set(:@selected_role, admin_role)
-
-        allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(user)
-
-        expect(helper.edit_disabled).to eq(true)
-    end
-
-    it "should enable inputs for roles with a lower priority" do
-        user = create(:user)
-        user.roles << Role.find_by(name: "admin", provider: "greenlight")
-        user_role = Role.find_by(name: "user", provider: "greenlight")
-        helper.instance_variable_set(:@selected_role, user_role)
-
-        allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(user)
-
-        expect(helper.edit_disabled).to eq(false)
-    end
-  end
-end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index d3514529..fe473c6d 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -20,21 +20,6 @@ require "rails_helper"
 
 describe ApplicationHelper do
   describe "#getter functions" do
-    it "returns whether user signup is allowed" do
-      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
-
-      expect(helper.allow_user_signup?).to eql(true)
-    end
-
-    it "returns whether the default bbb endpoint is being used" do
-      allow(Rails.configuration).to receive(:bigbluebutton_endpoint)
-        .and_return("http://test-install.blindsidenetworks.com/bigbluebutton/api/")
-      allow(Rails.configuration).to receive(:bigbluebutton_endpoint_default)
-        .and_return("http://test-install.blindsidenetworks.com/bigbluebutton/api/")
-
-      expect(helper.bigbluebutton_endpoint_default?).to eql(true)
-    end
-
     it "returns the correct omniauth login url" do
       allow(Rails.configuration).to receive(:relative_url_root).and_return("/b")
       provider = Faker::Company.name
@@ -43,51 +28,8 @@ describe ApplicationHelper do
     end
   end
 
-  describe "#allow_greenlight_accounts" do
-    it "allows if user sign up is turned on" do
-      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(false)
-      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
-
-      expect(helper.allow_greenlight_accounts?).to eql(true)
-    end
-
-    it "doesn't allow if user sign up is turned off" do
-      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(false)
-      allow(Rails.configuration).to receive(:allow_user_signup).and_return(false)
-
-      expect(helper.allow_greenlight_accounts?).to eql(false)
-    end
-
-    it "doesn't allow if user_domain is blank" do
-      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
-      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
-
-      expect(helper.allow_greenlight_accounts?).to eql(false)
-    end
-
-    it "allows if user provider is set to greenlight" do
-      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
-      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
-      allow(helper).to receive(:retrieve_provider_info).and_return("provider" => "greenlight")
-
-      @user_domain = "provider1"
-
-      expect(helper.allow_greenlight_accounts?).to eql(true)
-    end
-
-    it "doesnt allow if user provider is not set to greenlight" do
-      allow(Rails.configuration).to receive(:loadbalanced_configuration).and_return(true)
-      allow(Rails.configuration).to receive(:allow_user_signup).and_return(true)
-      allow(helper).to receive(:retrieve_provider_info).and_return("provider" => "google")
-
-      @user_domain = "provider1"
-
-      expect(helper.allow_greenlight_accounts?).to eql(false)
-    end
-  end
-
-  describe "role_clour" do
-    it "should use default if the user doens't have a role" do
+  describe "role_colur" do
+    it "should use default if the user doesn't have a role" do
       expect(helper.role_colour(Role.create(name: "test"))).to eq(Rails.configuration.primary_color_default)
     end
 
diff --git a/spec/helpers/users_helper_spec.rb b/spec/helpers/users_helper_spec.rb
deleted file mode 100644
index eabe2661..00000000
--- a/spec/helpers/users_helper_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
-#
-# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
-#
-# This program is free software; you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free Software
-# Foundation; either version 3.0 of the License, or (at your option) any later
-# version.
-#
-# BigBlueButton 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 Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with BigBlueButton; if not, see  .
-
-require "rails_helper"
-
-describe UsersHelper do
-    describe "disabled roles" do
-        it "should return roles with a less than or equal to priority for non admins" do
-            user = create(:user)
-            allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(user)
-
-            disabled_roles = helper.disabled_roles(user)
-
-            expect(disabled_roles.count).to eq(1)
-        end
-
-        it "should return roles with a lesser priority for admins" do
-            admin = create(:user)
-            admin.add_role :admin
-            user = create(:user)
-
-            allow_any_instance_of(SessionsHelper).to receive(:current_user).and_return(admin)
-
-            disabled_roles = helper.disabled_roles(user)
-
-            expect(disabled_roles.count).to eq(1)
-        end
-    end
-end
diff --git a/spec/models/room_spec.rb b/spec/models/room_spec.rb
index ab02bb5e..af49df8e 100644
--- a/spec/models/room_spec.rb
+++ b/spec/models/room_spec.rb
@@ -62,52 +62,6 @@ describe Room, type: :model do
     end
   end
 
-  context "#running?" do
-    it "should return false when not running" do
-      expect(@room.running?).to be false
-    end
-
-    it "should return true when running" do
-      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:is_meeting_running?).and_return(true)
-      expect(@room.running?).to be true
-    end
-  end
-
-  context "#start_session" do
-    it "should update latest session info" do
-      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:create_meeting).and_return(
-        messageKey: ""
-      )
-
-      expect do
-        @room.start_session
-      end.to change { @room.sessions }.by(1)
-
-      expect(@room.last_session).not_to be nil
-    end
-  end
-
-  context "#join_path" do
-    it "should return correct join URL for user" do
-      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
-        attendeePW: "testpass"
-      )
-
-      endpoint = Rails.configuration.bigbluebutton_endpoint
-      secret = Rails.configuration.bigbluebutton_secret
-      fullname = "fullName=Example"
-      join_via_html5 = "&join_via_html5=true"
-      meeting_id = "&meetingID=#{@room.bbb_id}"
-      password = "&password=testpass"
-
-      query = fullname + join_via_html5 + meeting_id + password
-      checksum_string = "join#{query + secret}"
-
-      checksum = OpenSSL::Digest.digest('sha1', checksum_string).unpack1("H*")
-      expect(@room.join_path("Example")).to eql("#{endpoint}join?#{query}&checksum=#{checksum}")
-    end
-  end
-
   context "#notify_waiting" do
     it "should broadcast to waiting channel with started action" do
       expect do
@@ -115,32 +69,4 @@ describe Room, type: :model do
       end.to have_broadcasted_to("#{@room.uid}_waiting_channel").with(a_hash_including(action: "started"))
     end
   end
-
-  context "#participants" do
-    it "should link participants to accounts" do
-      user1 = create(:user)
-      user2 = create(:user)
-
-      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:get_meeting_info).and_return(
-        attendees: [
-          { userID: user1.uid, fullName: user1.name },
-          { userID: "non-matching-uid", fullName: "Guest User" },
-          { userID: user2.uid, fullName: user2.name },
-        ],
-      )
-
-      expect(@room.participants).to contain_exactly(user1, nil, user2)
-    end
-  end
-
-  context "#recordings" do
-    it "deletes the recording" do
-      allow_any_instance_of(BigBlueButton::BigBlueButtonApi).to receive(:delete_recordings).and_return(
-        returncode: true, deleted: true
-      )
-
-      expect(@room.delete_recording(Faker::IDNumber.valid))
-        .to contain_exactly([:returncode, true], [:deleted, true])
-    end
-  end
 end
From 01b8dbbd0e344e3df4a3ff4ff87ca467a8377634 Mon Sep 17 00:00:00 2001
From: farhatahmad <35435341+farhatahmad@users.noreply.github.com>
Date: Tue, 27 Aug 2019 11:08:58 -0400
Subject: [PATCH 2/9] GRN2-196: Fixed issues that scrutinizer is complaining
 about (#765)
* Refactored code to improve scrutinizer score
* Bug fixes
---
 app/assets/javascripts/rename.js              |   8 +-
 app/assets/javascripts/search.js              |  54 +++----
 app/controllers/application_controller.rb     |  45 +++---
 app/controllers/concerns/authenticator.rb     |   4 +
 app/controllers/concerns/joiner.rb            |  94 ++++++++++++
 app/controllers/concerns/registrar.rb         |  29 ++++
 app/controllers/concerns/themer.rb            |  18 +--
 app/controllers/password_resets_controller.rb |   2 +-
 app/controllers/recordings_controller.rb      |   7 +
 app/controllers/rooms_controller.rb           | 139 +++++-------------
 app/controllers/sessions_controller.rb        |  46 ++++++
 app/controllers/themes_controller.rb          |   3 +-
 app/controllers/users_controller.rb           | 122 ++++-----------
 app/helpers/admins_helper.rb                  |   5 +-
 app/models/concerns/auth_values.rb            |  67 +++++++++
 app/models/user.rb                            |  82 ++---------
 .../components/_server_recording_row.html.erb |   2 +-
 app/views/rooms/show.html.erb                 |   2 +-
 .../{users => sessions}/ldap_signin.html.erb  |   0
 app/views/{users => sessions}/new.html.erb    |   0
 app/views/{users => sessions}/signin.html.erb |   0
 .../components/_public_recording_row.html.erb |   2 +-
 .../shared/components/_recording_row.html.erb |   2 +-
 .../shared/components/_subtitle.html.erb      |   2 +-
 app/views/users/change_password.html.erb      |   9 ++
 .../users/components/_menu_buttons.html.erb   |   6 +-
 app/views/users/components/_password.html.erb |   6 +-
 config/routes.rb                              |   7 +-
 .../password_resets_controller_spec.rb        |   5 +-
 .../controllers/recordings_controller_spec.rb |  13 ++
 spec/controllers/rooms_controller_spec.rb     |  30 +---
 spec/controllers/sessions_controller_spec.rb  |  44 ++++++
 spec/controllers/users_controller_spec.rb     |  41 ------
 33 files changed, 462 insertions(+), 434 deletions(-)
 create mode 100644 app/controllers/concerns/joiner.rb
 create mode 100644 app/models/concerns/auth_values.rb
 rename app/views/{users => sessions}/ldap_signin.html.erb (100%)
 rename app/views/{users => sessions}/new.html.erb (100%)
 rename app/views/{users => sessions}/signin.html.erb (100%)
diff --git a/app/assets/javascripts/rename.js b/app/assets/javascripts/rename.js
index a8f32c6a..49ddbce0 100644
--- a/app/assets/javascripts/rename.js
+++ b/app/assets/javascripts/rename.js
@@ -124,7 +124,7 @@ $(document).on('turbolinks:load', function(){
         submit_update_request({
           setting: "rename_header",
           room_name: element.find('#user-text').text(),
-        }, element.data('path'));
+        }, element.data('path'), "POST");
       }
       else if(element.is('#recording-title')){
         submit_update_request({
@@ -132,16 +132,16 @@ $(document).on('turbolinks:load', function(){
           record_id: element.data('recordid'),
           record_name: element.find('text').text(),
           room_uid: element.data('room-uid'),
-        }, element.data('path'));
+        }, element.data('path'), "PATCH");
       }
     }
 
     // Helper for submitting ajax requests
-    var submit_update_request = function(data, path){
+    var submit_update_request = function(data, path, action){
       // Send ajax request for update
       $.ajax({
         url: path,
-        type: "PATCH",
+        type: action,
         data: data,
       });
     }
diff --git a/app/assets/javascripts/search.js b/app/assets/javascripts/search.js
index 6869ebb5..9c8e0c5c 100644
--- a/app/assets/javascripts/search.js
+++ b/app/assets/javascripts/search.js
@@ -26,8 +26,7 @@ $(document).on('turbolinks:load', function(){
       (controller == "admins" && action == "server_recordings")) {
     // Submit search if the user hits enter
     $("#search-input").keypress(function(key) {
-      var keyPressed = key.which
-      if (keyPressed == 13) {
+      if (key.which == 13) {
         searchPage()
       }
     })
@@ -35,8 +34,6 @@ $(document).on('turbolinks:load', function(){
     // Add listeners for sort
     $("th[data-order]").click(function(data){
       var header_elem = $(data.target)
-      var controller = $("body").data('controller');
-      var action = $("body").data('action');
 
       if(header_elem.data('order') === 'asc'){ // asc
         header_elem.data('order', 'desc');
@@ -50,15 +47,10 @@ $(document).on('turbolinks:load', function(){
 
       var search = $("#search-input").val();
 
-      if(controller === "rooms" && action === "show"){
-        window.location.replace(window.location.pathname + "?page=1&search=" + search + 
-          "&column=" + header_elem.data("header") + "&direction="+ header_elem.data('order') + 
-          "#recordings-table");
-      }
-      else{
-        window.location.replace(window.location.pathname + "?page=1&search=" + search + 
-          "&column=" + header_elem.data("header") + "&direction="+ header_elem.data('order'));
-      }
+      var url = window.location.pathname + "?page=1&search=" + search + "&column=" + header_elem.data("header") +
+       "&direction=" + header_elem.data('order')
+
+      window.location.replace(addRecordingTable(url))
     })
 
     if(controller === "rooms" && action === "show"){
@@ -75,42 +67,30 @@ $(document).on('turbolinks:load', function(){
 function searchPage() {
   var search = $("#search-input").val();
 
-  var controller = $("body").data('controller');
-  var action = $("body").data('action');
-
   // Check if the user filtered by role
   var role = new URL(location.href).searchParams.get('role')
 
   var url = window.location.pathname + "?page=1&search=" + search
 
-  if (role) {
-    url += "&role=" + role
-  }  
+  if (role) { url += "&role=" + role } 
 
-  if(controller === "rooms" && action === "show"){
-    window.location.replace(url + "#recordings-table");
-  } else{
-    window.location.replace(url);
-  }
-  
+  window.location.replace(addRecordingTable(url));
 }
 
 // Clears the search bar
 function clearSearch() {
-  var controller = $("body").data('controller');
-  var action = $("body").data('action');
-
   var role = new URL(location.href).searchParams.get('role')
 
   var url = window.location.pathname + "?page=1"
 
-  if (role) {
-    url += "&role=" + role
-  }  
-
-  if(controller === "rooms" && action === "show"){
-    window.location.replace(url + "#recordings-table");
-  } else{
-    window.location.replace(url);
-  }
+  if (role) { url += "&role=" + role } 
+  
+  window.location.replace(addRecordingTable(url));
+}
+
+function addRecordingTable(url) {
+  if($("body").data('controller') === "rooms" && $("body").data('action') === "show") { 
+    url += "#recordings-table"
+  }
+  return url
 }
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 2b46e004..cc8e01ec 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -18,16 +18,9 @@
 
 class ApplicationController < ActionController::Base
   include BbbServer
-  include ThemingHelper
 
-  before_action :redirect_to_https
-  before_action :set_user_domain
-  before_action :set_user_settings
-  before_action :maintenance_mode?
-  before_action :migration_error?
-  before_action :user_locale
-  before_action :check_admin_password
-  before_action :check_user_role
+  before_action :redirect_to_https, :set_user_domain, :set_user_settings, :maintenance_mode?, :migration_error?,
+    :user_locale, :check_admin_password, :check_user_role
 
   # Manually handle BigBlueButton errors
   rescue_from BigBlueButton::BigBlueButtonException, with: :handle_bigbluebutton_error
@@ -77,6 +70,23 @@ class ApplicationController < ActionController::Base
     @settings = Setting.find_or_create_by(provider: @user_domain)
   end
 
+  # Redirects the user to a Maintenance page if turned on
+  def maintenance_mode?
+    if ENV["MAINTENANCE_MODE"] == "true"
+      render "errors/greenlight_error", status: 503, formats: :html,
+        locals: {
+          status_code: 503,
+          message: I18n.t("errors.maintenance.message"),
+          help: I18n.t("errors.maintenance.help"),
+        }
+    end
+    if Rails.configuration.maintenance_window.present?
+      unless cookies[:maintenance_window] == Rails.configuration.maintenance_window
+        flash.now[:maintenance] = I18n.t("maintenance.window_alert", date: Rails.configuration.maintenance_window)
+      end
+    end
+  end
+
   # Show an information page when migration fails and there is a version error.
   def migration_error?
     render :migration_error, status: 500 unless ENV["DB_MIGRATE_FAILED"].blank?
@@ -113,23 +123,6 @@ class ApplicationController < ActionController::Base
     end
   end
 
-  # Redirects the user to a Maintenance page if turned on
-  def maintenance_mode?
-    if ENV["MAINTENANCE_MODE"] == "true"
-      render "errors/greenlight_error", status: 503, formats: :html,
-        locals: {
-          status_code: 503,
-          message: I18n.t("errors.maintenance.message"),
-          help: I18n.t("errors.maintenance.help"),
-        }
-    end
-    if Rails.configuration.maintenance_window.present?
-      unless cookies[:maintenance_window] == Rails.configuration.maintenance_window
-        flash.now[:maintenance] = I18n.t("maintenance.window_alert", date: Rails.configuration.maintenance_window)
-      end
-    end
-  end
-
   # Relative root helper (when deploying to subdirectory).
   def relative_root
     Rails.configuration.relative_url_root || ""
diff --git a/app/controllers/concerns/authenticator.rb b/app/controllers/concerns/authenticator.rb
index e4ba2c04..3a8c1202 100644
--- a/app/controllers/concerns/authenticator.rb
+++ b/app/controllers/concerns/authenticator.rb
@@ -56,6 +56,10 @@ module Authenticator
     end
   end
 
+  def ensure_unauthenticated_except_twitter
+    redirect_to current_user.main_room if current_user && params[:old_twitter_user_id].nil?
+  end
+
   # Logs current user out of GreenLight.
   def logout
     session.delete(:user_id) if current_user
diff --git a/app/controllers/concerns/joiner.rb b/app/controllers/concerns/joiner.rb
new file mode 100644
index 00000000..e554d631
--- /dev/null
+++ b/app/controllers/concerns/joiner.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
+#
+# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
+#
+# This program is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free Software
+# Foundation; either version 3.0 of the License, or (at your option) any later
+# version.
+#
+# BigBlueButton 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with BigBlueButton; if not, see  .
+
+module Joiner
+  extend ActiveSupport::Concern
+
+  # Displays the join room page to the user
+  def show_user_join
+    # Get users name
+    @name = if current_user
+      current_user.name
+    elsif cookies.encrypted[:greenlight_name]
+      cookies.encrypted[:greenlight_name]
+    else
+      ""
+    end
+
+    @search, @order_column, @order_direction, pub_recs =
+      public_recordings(@room.bbb_id, params.permit(:search, :column, :direction), true)
+
+    @pagy, @public_recordings = pagy_array(pub_recs)
+
+    render :join
+  end
+
+  # create or update cookie to track the three most recent rooms a user joined
+  def save_recent_rooms
+    if current_user
+      recently_joined_rooms = cookies.encrypted["#{current_user.uid}_recently_joined_rooms"].to_a
+      cookies.encrypted["#{current_user.uid}_recently_joined_rooms"] =
+        recently_joined_rooms.prepend(@room.id).uniq[0..2]
+    end
+  end
+
+  def join_room(opts)
+    room_settings = JSON.parse(@room[:room_settings])
+
+    if room_running?(@room.bbb_id) || @room.owned_by?(current_user) || room_settings["anyoneCanStart"]
+
+      # Determine if the user needs to join as a moderator.
+      opts[:user_is_moderator] = @room.owned_by?(current_user) || room_settings["joinModerator"]
+
+      opts[:require_moderator_approval] = room_settings["requireModeratorApproval"]
+
+      if current_user
+        redirect_to join_path(@room, current_user.name, opts, current_user.uid)
+      else
+        join_name = params[:join_name] || params[@room.invite_path][:join_name]
+        redirect_to join_path(@room, join_name, opts)
+      end
+    else
+      search_params = params[@room.invite_path] || params
+      @search, @order_column, @order_direction, pub_recs =
+        public_recordings(@room.bbb_id, search_params.permit(:search, :column, :direction), true)
+
+      @pagy, @public_recordings = pagy_array(pub_recs)
+
+      # They need to wait until the meeting begins.
+      render :wait
+    end
+  end
+
+  def incorrect_user_domain
+    Rails.configuration.loadbalanced_configuration && @room.owner.provider != @user_domain
+  end
+
+  # Default, unconfigured meeting options.
+  def default_meeting_options
+    invite_msg = I18n.t("invite_message")
+    {
+      user_is_moderator: false,
+      meeting_logout_url: request.base_url + logout_room_path(@room),
+      meeting_recorded: true,
+      moderator_message: "#{invite_msg}\n\n#{request.base_url + room_path(@room)}",
+      host: request.host,
+      recording_default_visibility: @settings.get_value("Default Recording Visibility") == "public"
+    }
+  end
+end
diff --git a/app/controllers/concerns/registrar.rb b/app/controllers/concerns/registrar.rb
index 34a77286..98c38a08 100644
--- a/app/controllers/concerns/registrar.rb
+++ b/app/controllers/concerns/registrar.rb
@@ -43,4 +43,33 @@ module Registrar
       { present: false, verified: false }
     end
   end
+
+  # Checks if the user passes the requirements to be invited
+  def passes_invite_reqs
+    # check if user needs to be invited and IS invited
+    invitation = check_user_invited(@user.email, session[:invite_token], @user_domain)
+
+    @user.email_verified = true if invitation[:verified]
+
+    invitation[:present]
+  end
+
+  # Add validation errors to model if they exist
+  def valid_user_or_captcha
+    valid_user = @user.valid?
+    valid_captcha = Rails.configuration.recaptcha_enabled ? verify_recaptcha(model: @user) : true
+
+    logger.error("Support: #{@user.email} creation failed: User params are not valid.") unless valid_user
+
+    valid_user && valid_captcha
+  end
+
+  # Checks if the user trying to sign in with twitter account
+  def check_if_twitter_account(log_out = false)
+    unless params[:old_twitter_user_id].nil? && session[:old_twitter_user_id].nil?
+      logout if log_out
+      flash.now[:alert] = I18n.t("registration.deprecated.new_signin")
+      session[:old_twitter_user_id] = params[:old_twitter_user_id] unless params[:old_twitter_user_id].nil?
+    end
+  end
 end
diff --git a/app/controllers/concerns/themer.rb b/app/controllers/concerns/themer.rb
index 2893ea27..132e3bbf 100644
--- a/app/controllers/concerns/themer.rb
+++ b/app/controllers/concerns/themer.rb
@@ -22,22 +22,20 @@ module Themer
   # Lightens a color by 40%
   def color_lighten(color)
     # Uses the built in Sass Engine to lighten the color
-
-    dummy_scss = "h1 { color: $lighten; }"
-    compiled = SassC::Engine.new("$lighten:lighten(#{color}, 40%);" + dummy_scss, syntax: :scss).render
-
-    string_locater = 'color: '
-    color_start = compiled.index(string_locater) + string_locater.length
-
-    compiled[color_start..color_start + 6]
+    generate_sass("lighten", color, "40%")
   end
 
   # Darkens a color by 10%
   def color_darken(color)
     # Uses the built in Sass Engine to darken the color
+    generate_sass("darken", color, "10%")
+  end
 
-    dummy_scss = "h1 { color: $darken; }"
-    compiled = SassC::Engine.new("$darken:darken(#{color}, 10%);" + dummy_scss, syntax: :scss).render
+  private
+
+  def generate_sass(action, color, percentage)
+    dummy_scss = "h1 { color: $#{action}; }"
+    compiled = SassC::Engine.new("$#{action}:#{action}(#{color}, #{percentage});" + dummy_scss, syntax: :scss).render
 
     string_locater = 'color: '
     color_start = compiled.index(string_locater) + string_locater.length
diff --git a/app/controllers/password_resets_controller.rb b/app/controllers/password_resets_controller.rb
index 9c77194b..3c22a43e 100644
--- a/app/controllers/password_resets_controller.rb
+++ b/app/controllers/password_resets_controller.rb
@@ -39,7 +39,7 @@ class PasswordResetsController < ApplicationController
       redirect_to root_path
     rescue
       # User doesn't exist
-      redirect_to new_password_reset_path, flash: { alert: I18n.t("no_user_email_exists") }
+      redirect_to root_path, flash: { success: I18n.t("email_sent", email_type: t("reset_password.subtitle")) }
     end
   end
 
diff --git a/app/controllers/recordings_controller.rb b/app/controllers/recordings_controller.rb
index d9e7f9e8..b002c918 100644
--- a/app/controllers/recordings_controller.rb
+++ b/app/controllers/recordings_controller.rb
@@ -34,6 +34,13 @@ class RecordingsController < ApplicationController
     redirect_back fallback_location: root_path if res[:updated]
   end
 
+  # PATCH /:meetingID/:record_id
+  def rename
+    update_recording(params[:record_id], "meta_name" => params[:record_name])
+
+    redirect_back fallback_location: room_path(@room)
+  end
+
   # DELETE /:meetingID/:record_id
   def delete
     delete_recording(params[:record_id])
diff --git a/app/controllers/rooms_controller.rb b/app/controllers/rooms_controller.rb
index 1aee8f00..9d9b14dd 100644
--- a/app/controllers/rooms_controller.rb
+++ b/app/controllers/rooms_controller.rb
@@ -19,12 +19,13 @@
 class RoomsController < ApplicationController
   include Pagy::Backend
   include Recorder
+  include Joiner
 
   before_action :validate_accepted_terms, unless: -> { !Rails.configuration.terms }
   before_action :validate_verified_email, except: [:show, :join],
                 unless: -> { !Rails.configuration.enable_email_verification }
   before_action :find_room, except: [:create, :join_specific_room]
-  before_action :verify_room_ownership, except: [:create, :show, :join, :logout, :login, :join_specific_room]
+  before_action :verify_room_ownership, only: [:destroy, :start, :update_settings]
   before_action :verify_room_owner_verified, only: [:show, :join],
                 unless: -> { !Rails.configuration.enable_email_verification }
   before_action :verify_user_not_admin, only: [:show]
@@ -42,19 +43,17 @@ class RoomsController < ApplicationController
     @room.owner = current_user
     @room.room_settings = create_room_settings_string(room_params)
 
-    # Save the room
-    if @room.save
-      logger.info "Support: #{current_user.email} has created a new room #{@room.uid}."
+    # Save the room and redirect if it fails
+    return redirect_to current_user.main_room, flash: { alert: I18n.t("room.create_room_error") } unless @room.save
 
-      # Start the room if auto join was turned on
-      if room_params[:auto_join] == "1"
-        start
-      else
-        redirect_to @room, flash: { success: I18n.t("room.create_room_success") }
-      end
-    else
-      redirect_to current_user.main_room, flash: { alert: I18n.t("room.create_room_error") }
-    end
+    logger.info "Support: #{current_user.email} has created a new room #{@room.uid}."
+
+    # Redirect to room is auto join was not turned on
+    return redirect_to @room,
+      flash: { success: I18n.t("room.create_room_success") } unless room_params[:auto_join] == "1"
+
+    # Start the room if auto join was turned on
+    start
   end
 
   # GET /:room_uid
@@ -76,6 +75,7 @@ class RoomsController < ApplicationController
         render :cant_create_rooms
       end
     else
+<<<<<<< HEAD
       return redirect_to root_path, flash: { alert: I18n.t("room.invalid_provider") } if incorrect_user_domain
 
       # Get users name
@@ -102,9 +102,10 @@ class RoomsController < ApplicationController
       update_room_attributes("name")
     elsif params[:setting] == "rename_recording"
       update_recording(params[:record_id], "meta_name" => params[:record_name])
+=======
+      show_user_join
+>>>>>>> GRN2-196: Fixed issues that scrutinizer is complaining about (#765)
     end
-
-    redirect_back fallback_location: room_path
   end
 
   # POST /:room_uid
@@ -123,19 +124,14 @@ class RoomsController < ApplicationController
         @join_name = params[@room.invite_path][:join_name]
       elsif !params[:join_name]
         # Join name not passed.
-        return
+        return redirect_to root_path
       end
     end
 
     # create or update cookie with join name
     cookies.encrypted[:greenlight_name] = @join_name unless cookies.encrypted[:greenlight_name] == @join_name
 
-    if current_user
-      # create or update cookie to track the three most recent rooms a user joined
-      recently_joined_rooms = cookies.encrypted["#{current_user.uid}_recently_joined_rooms"].to_a
-      cookies.encrypted["#{current_user.uid}_recently_joined_rooms"] =
-        recently_joined_rooms.prepend(@room.id).uniq[0..2]
-    end
+    save_recent_rooms
 
     logger.info "Support: #{current_user.present? ? current_user.email : @join_name} is joining room #{@room.uid}"
     join_room(default_meeting_options)
@@ -195,20 +191,25 @@ class RoomsController < ApplicationController
   def update_settings
     begin
       raise "Room name can't be blank" if room_params[:name].empty?
+      raise "Unauthorized Request" if !@room.owned_by?(current_user) || @room == current_user.main_room
 
-      @room = Room.find_by!(uid: params[:room_uid])
       # Update the rooms settings
-      update_room_attributes("settings")
+      if room_params
+        room_settings_string = create_room_settings_string(room_params)
+        @room.update_attributes(room_settings: room_settings_string)
+      end
+
       # Update the rooms name if it has been changed
-      update_room_attributes("name") if @room.name != room_params[:name]
+      @room.update_attributes(name: params[:room_name] || room_params[:name]) if @room.name != room_params[:name]
       # Update the room's access code if it has changed
-      update_room_attributes("access_code") if @room.access_code != room_params[:access_code]
-    rescue => e
-      logger.error "Error in updating room settings: #{e}"
-      flash[:alert] = I18n.t("room.update_settings_error")
-    else
+      @room.update_attributes(access_code: room_params[:access_code]) if @room.access_code != room_params[:access_code]
+
       flash[:success] = I18n.t("room.update_settings_success")
+    rescue => e
+      logger.error "Support: Error in updating room settings: #{e}"
+      flash[:alert] = I18n.t("room.update_settings_error")
     end
+
     redirect_to room_path
   end
 
@@ -231,19 +232,6 @@ class RoomsController < ApplicationController
 
   private
 
-  def update_room_attributes(update_type)
-    if @room.owned_by?(current_user) && @room != current_user.main_room
-      if update_type.eql? "name"
-        @room.update_attributes(name: params[:room_name] || room_params[:name])
-      elsif update_type.eql? "settings"
-        room_settings_string = create_room_settings_string(room_params)
-        @room.update_attributes(room_settings: room_settings_string)
-      elsif update_type.eql? "access_code"
-        @room.update_attributes(access_code: room_params[:access_code])
-      end
-    end
-  end
-
   def create_room_settings_string(options)
     room_settings = {}
     room_settings["muteOnStart"] = options[:mute_on_join] == "1"
@@ -269,18 +257,7 @@ class RoomsController < ApplicationController
 
   # Ensure the user is logged into the room they are accessing.
   def verify_room_ownership
-    bring_to_room unless @room.owned_by?(current_user)
-  end
-
-  # Redirects a user to their room.
-  def bring_to_room
-    if current_user
-      # Redirect authenticated users to their room.
-      redirect_to room_path(current_user.main_room)
-    else
-      # Redirect unauthenticated users to root.
-      redirect_to root_path
-    end
+    return redirect_to root_path unless @room.owned_by?(current_user)
   end
 
   def validate_accepted_terms
@@ -294,12 +271,7 @@ class RoomsController < ApplicationController
   def verify_room_owner_verified
     unless @room.owner.activated?
       flash[:alert] = t("room.unavailable")
-
-      if current_user && !@room.owned_by?(current_user)
-        redirect_to current_user.main_room
-      else
-        redirect_to root_path
-      end
+      redirect_to root_path
     end
   end
 
@@ -321,49 +293,4 @@ class RoomsController < ApplicationController
     current_user.rooms.length >= limit
   end
   helper_method :room_limit_exceeded
-
-  def join_room(opts)
-    room_settings = JSON.parse(@room[:room_settings])
-
-    if room_running?(@room.bbb_id) || @room.owned_by?(current_user) || room_settings["anyoneCanStart"]
-
-      # Determine if the user needs to join as a moderator.
-      opts[:user_is_moderator] = @room.owned_by?(current_user) || room_settings["joinModerator"]
-
-      opts[:require_moderator_approval] = room_settings["requireModeratorApproval"]
-
-      if current_user
-        redirect_to join_path(@room, current_user.name, opts, current_user.uid)
-      else
-        join_name = params[:join_name] || params[@room.invite_path][:join_name]
-        redirect_to join_path(@room, join_name, opts)
-      end
-    else
-      search_params = params[@room.invite_path] || params
-      @search, @order_column, @order_direction, pub_recs =
-        public_recordings(@room.bbb_id, search_params.permit(:search, :column, :direction), true)
-
-      @pagy, @public_recordings = pagy_array(pub_recs)
-
-      # They need to wait until the meeting begins.
-      render :wait
-    end
-  end
-
-  def incorrect_user_domain
-    Rails.configuration.loadbalanced_configuration && @room.owner.provider != @user_domain
-  end
-  
-  # Default, unconfigured meeting options.
-  def default_meeting_options
-    invite_msg = I18n.t("invite_message")
-    {
-      user_is_moderator: false,
-      meeting_logout_url: request.base_url + logout_room_path(@room),
-      meeting_recorded: true,
-      moderator_message: "#{invite_msg}\n\n#{request.base_url + room_path(@room)}",
-      host: request.host,
-      recording_default_visibility: @settings.get_value("Default Recording Visibility") == "public"
-    }
-  end
 end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 22c7f396..09eec68e 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -23,6 +23,42 @@ class SessionsController < ApplicationController
   include LdapAuthenticator
 
   skip_before_action :verify_authenticity_token, only: [:omniauth, :fail]
+  before_action :check_user_signup_allowed, only: [:new]
+  before_action :ensure_unauthenticated_except_twitter, only: [:new, :signin]
+
+  # GET /signin
+  def signin
+    check_if_twitter_account
+
+    providers = configured_providers
+    if one_provider
+      provider_path = if Rails.configuration.omniauth_ldap
+        ldap_signin_path
+      else
+        "#{Rails.configuration.relative_url_root}/auth/#{providers.first}"
+      end
+
+      return redirect_to provider_path
+    end
+  end
+
+  # GET /ldap_signin
+  def ldap_signin
+  end
+
+  # GET /signup
+  def new
+    # Check if the user needs to be invited
+    if invite_registration
+      redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless params[:invite_token]
+
+      session[:invite_token] = params[:invite_token]
+    end
+
+    check_if_twitter_account(true)
+
+    @user = User.new
+  end
 
   # POST /users/login
   def create
@@ -101,10 +137,20 @@ class SessionsController < ApplicationController
 
   private
 
+  # Verify that GreenLight is configured to allow user signup.
+  def check_user_signup_allowed
+    redirect_to root_path unless Rails.configuration.allow_user_signup
+  end
+
   def session_params
     params.require(:session).permit(:email, :password)
   end
 
+  def one_provider
+    (!allow_user_signup? || !allow_greenlight_accounts?) && providers.count == 1 &&
+      !Rails.configuration.loadbalanced_configuration
+  end
+
   def check_user_exists
     provider = @auth['provider'] == "bn_launcher" ? @auth['info']['customer'] : @auth['provider']
     User.exists?(social_uid: @auth['uid'], provider: provider)
diff --git a/app/controllers/themes_controller.rb b/app/controllers/themes_controller.rb
index bfbfeb56..f5c32eb2 100644
--- a/app/controllers/themes_controller.rb
+++ b/app/controllers/themes_controller.rb
@@ -17,7 +17,8 @@
 # with BigBlueButton; if not, see  .
 
 class ThemesController < ApplicationController
-  skip_before_action :maintenance_mode?
+  skip_before_action :redirect_to_https, :maintenance_mode?, :migration_error?, :user_locale,
+    :check_admin_password, :check_user_role
 
   # GET /primary
   def index
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index a38f85fb..6bffe8ad 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -25,19 +25,17 @@ class UsersController < ApplicationController
   include Rolify
 
   before_action :find_user, only: [:edit, :change_password, :delete_account, :update, :destroy]
-  before_action :ensure_unauthenticated, only: [:new, :create, :signin]
+  before_action :ensure_unauthenticated_except_twitter, only: [:create]
+  before_action :check_user_signup_allowed, only: [:create]
   before_action :check_admin_of, only: [:edit, :change_password, :delete_account]
 
   # POST /u
   def create
-    # Verify that GreenLight is configured to allow user signup.
-    return unless Rails.configuration.allow_user_signup
-
     @user = User.new(user_params)
     @user.provider = @user_domain
 
     # User or recpatcha is not valid
-    render(:new) && return unless valid_user_or_captcha
+    render("sessions/new") && return unless valid_user_or_captcha
 
     # Redirect to root if user token is either invalid or expired
     return redirect_to root_path, flash: { alert: I18n.t("registration.invite.fail") } unless passes_invite_reqs
@@ -65,50 +63,6 @@ class UsersController < ApplicationController
     redirect_to root_path
   end
 
-  # GET /signin
-  def signin
-    unless params[:old_twitter_user_id].nil? && session[:old_twitter_user_id].nil?
-      flash[:alert] = I18n.t("registration.deprecated.new_signin")
-      session[:old_twitter_user_id] = params[:old_twitter_user_id] unless params[:old_twitter_user_id].nil?
-    end
-
-    providers = configured_providers
-    if (!allow_user_signup? || !allow_greenlight_accounts?) && providers.count == 1 &&
-       !Rails.configuration.loadbalanced_configuration
-      provider_path = if Rails.configuration.omniauth_ldap
-        ldap_signin_path
-      else
-        "#{Rails.configuration.relative_url_root}/auth/#{providers.first}"
-      end
-
-      return redirect_to provider_path
-    end
-  end
-
-  # GET /ldap_signin
-  def ldap_signin
-  end
-
-  # GET /signup
-  def new
-    return redirect_to root_path unless Rails.configuration.allow_user_signup
-
-    # Check if the user needs to be invited
-    if invite_registration
-      redirect_to root_path, flash: { alert: I18n.t("registration.invite.no_invite") } unless params[:invite_token]
-
-      session[:invite_token] = params[:invite_token]
-    end
-
-    unless params[:old_twitter_user_id].nil? && session[:old_twitter_user_id].nil?
-      logout
-      flash.now[:alert] = I18n.t("registration.deprecated.new_signin")
-      session[:old_twitter_user_id] = params[:old_twitter_user_id] unless params[:old_twitter_user_id].nil?
-    end
-
-    @user = User.new
-  end
-
   # GET /u/:user_uid/edit
   def edit
     redirect_to root_path unless current_user
@@ -116,6 +70,7 @@ class UsersController < ApplicationController
 
   # GET /u/:user_uid/change_password
   def change_password
+    redirect_to edit_user_path unless current_user.greenlight_account?
   end
 
   # GET /u/:user_uid/delete_account
@@ -124,11 +79,11 @@ class UsersController < ApplicationController
 
   # PATCH /u/:user_uid/edit
   def update
-    redirect_path = current_user.admin_of?(@user) ? admins_path : edit_user_path(@user)
+    profile = params[:setting] == "password" ? change_password_path(@user) : edit_user_path(@user)
+    redirect_path = current_user.admin_of?(@user) ? admins_path : profile
 
     if params[:setting] == "password"
       # Update the users password.
-      errors = {}
 
       if @user.authenticate(user_params[:password])
         # Verify that the new passwords match.
@@ -136,21 +91,18 @@ class UsersController < ApplicationController
           @user.password = user_params[:new_password]
         else
           # New passwords don't match.
-          errors[:password_confirmation] = "doesn't match"
+          @user.errors.add(:password_confirmation, "doesn't match")
         end
       else
         # Original password is incorrect, can't update.
-        errors[:password] = "is incorrect"
+        @user.errors.add(:password, "is incorrect")
       end
 
-      if errors.empty? && @user.save
-        # Notify the user that their account has been updated.
-        redirect_to redirect_path, flash: { success: I18n.t("info_update_success") }
-      else
-        # Append custom errors.
-        errors.each { |k, v| @user.errors.add(k, v) }
-        render :edit, params: { settings: params[:settings] }
-      end
+      # Notify the user that their account has been updated.
+      return redirect_to redirect_path,
+        flash: { success: I18n.t("info_update_success") } if @user.errors.empty? && @user.save
+
+      render :change_password
     else
       if @user.update_attributes(user_params)
         @user.update_attributes(email_verified: false) if user_params[:email] != @user.email
@@ -164,7 +116,7 @@ class UsersController < ApplicationController
         end
       end
 
-      render :edit, params: { settings: params[:settings] }
+      render :edit
     end
   end
 
@@ -172,20 +124,19 @@ class UsersController < ApplicationController
   def destroy
     logger.info "Support: #{current_user.email} is deleting #{@user.email}."
 
-    if current_user && current_user == @user
-      @user.destroy
-      session.delete(:user_id)
-    elsif current_user.admin_of?(@user)
-      begin
+    self_delete = current_user == @user
+    begin
+      if current_user && (self_delete || current_user.admin_of?(@user))
         @user.destroy
-      rescue => e
-        logger.error "Support: Error in user deletion: #{e}"
-        flash[:alert] = I18n.t(params[:message], default: I18n.t("administrator.flash.delete_fail"))
-      else
-        flash[:success] = I18n.t("administrator.flash.delete")
+        session.delete(:user_id) if self_delete
+
+        return redirect_to admins_path, flash: { success: I18n.t("administrator.flash.delete") } unless self_delete
       end
-      redirect_to(admins_path) && return
+    rescue => e
+      logger.error "Support: Error in user deletion: #{e}"
+      flash[:alert] = I18n.t(params[:message], default: I18n.t("administrator.flash.delete_fail"))
     end
+
     redirect_to root_path
   end
 
@@ -216,8 +167,9 @@ class UsersController < ApplicationController
     @user = User.where(uid: params[:user_uid]).includes(:roles).first
   end
 
-  def ensure_unauthenticated
-    redirect_to current_user.main_room if current_user && params[:old_twitter_user_id].nil?
+  # Verify that GreenLight is configured to allow user signup.
+  def check_user_signup_allowed
+    redirect_to root_path unless Rails.configuration.allow_user_signup
   end
 
   def user_params
@@ -233,26 +185,6 @@ class UsersController < ApplicationController
     end
   end
 
-  # Add validation errors to model if they exist
-  def valid_user_or_captcha
-    valid_user = @user.valid?
-    valid_captcha = Rails.configuration.recaptcha_enabled ? verify_recaptcha(model: @user) : true
-
-    logger.error("Support: #{@user.email} creation failed: User params are not valid.") unless valid_user
-
-    valid_user && valid_captcha
-  end
-
-  # Checks if the user passes the requirements to be invited
-  def passes_invite_reqs
-    # check if user needs to be invited and IS invited
-    invitation = check_user_invited(@user.email, session[:invite_token], @user_domain)
-
-    @user.email_verified = true if invitation[:verified]
-
-    invitation[:present]
-  end
-
   # Checks that the user is allowed to edit this user
   def check_admin_of
     redirect_to current_user.main_room if current_user && @user != current_user && !current_user.admin_of?(@user)
diff --git a/app/helpers/admins_helper.rb b/app/helpers/admins_helper.rb
index 7dd762e6..aff41f2a 100644
--- a/app/helpers/admins_helper.rb
+++ b/app/helpers/admins_helper.rb
@@ -24,8 +24,9 @@ module AdminsHelper
     Room.find_by(bbb_id: room_id).owner.email
   end
 
-  def invite_registration
-    @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:invite]
+  def admin_invite_registration
+    controller_name == "admins" && action_name == "index" &&
+      @settings.get_value("Registration Method") == Rails.configuration.registration_methods[:invite]
   end
 
   def room_authentication_string
diff --git a/app/models/concerns/auth_values.rb b/app/models/concerns/auth_values.rb
new file mode 100644
index 00000000..06681f9d
--- /dev/null
+++ b/app/models/concerns/auth_values.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+
+# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/.
+#
+# Copyright (c) 2018 BigBlueButton Inc. and by respective authors (see below).
+#
+# This program is free software; you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free Software
+# Foundation; either version 3.0 of the License, or (at your option) any later
+# version.
+#
+# BigBlueButton 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License along
+# with BigBlueButton; if not, see  .
+
+module AuthValues
+  extend ActiveSupport::Concern
+
+  # Provider attributes.
+  def auth_name(auth)
+    case auth['provider']
+    when :office365
+      auth['info']['display_name']
+    else
+      auth['info']['name']
+    end
+  end
+
+  def auth_username(auth)
+    case auth['provider']
+    when :google
+      auth['info']['email'].split('@').first
+    when :bn_launcher
+      auth['info']['username']
+    else
+      auth['info']['nickname']
+    end
+  end
+
+  def auth_email(auth)
+    auth['info']['email']
+  end
+
+  def auth_image(auth)
+    case auth['provider']
+    when :twitter
+      auth['info']['image'].gsub("http", "https").gsub("_normal", "")
+    else
+      auth['info']['image']
+    end
+  end
+
+  def auth_roles(user, auth)
+    unless auth['info']['roles'].nil?
+      roles = auth['info']['roles'].split(',')
+
+      role_provider = auth['provider'] == "bn_launcher" ? auth['info']['customer'] : "greenlight"
+      roles.each do |role_name|
+        role = Role.where(provider: role_provider, name: role_name).first
+        user.roles << role unless role.nil?
+      end
+    end
+  end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 90c1f9b2..d24997d9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -20,8 +20,7 @@ require 'bbb_api'
 
 class User < ApplicationRecord
   attr_accessor :reset_token
-  after_create :assign_default_role
-  after_create :initialize_main_room
+  after_create :setup_user
 
   before_save { email.try(:downcase!) }
 
@@ -49,6 +48,8 @@ class User < ApplicationRecord
   has_secure_password(validations: false)
 
   class << self
+    include AuthValues
+
     # Generates a user from omniauth.
     def from_omniauth(auth)
       # Provider is the customer name if in loadbalanced config mode
@@ -63,54 +64,6 @@ class User < ApplicationRecord
         u.save!
       end
     end
-
-    private
-
-    # Provider attributes.
-    def auth_name(auth)
-      case auth['provider']
-      when :office365
-        auth['info']['display_name']
-      else
-        auth['info']['name']
-      end
-    end
-
-    def auth_username(auth)
-      case auth['provider']
-      when :google
-        auth['info']['email'].split('@').first
-      when :bn_launcher
-        auth['info']['username']
-      else
-        auth['info']['nickname']
-      end
-    end
-
-    def auth_email(auth)
-      auth['info']['email']
-    end
-
-    def auth_image(auth)
-      case auth['provider']
-      when :twitter
-        auth['info']['image'].gsub("http", "https").gsub("_normal", "")
-      else
-        auth['info']['image']
-      end
-    end
-
-    def auth_roles(user, auth)
-      unless auth['info']['roles'].nil?
-        roles = auth['info']['roles'].split(',')
-
-        role_provider = auth['provider'] == "bn_launcher" ? auth['info']['customer'] : "greenlight"
-        roles.each do |role_name|
-          role = Role.where(provider: role_provider, name: role_name).first
-          user.roles << role unless role.nil?
-        end
-      end
-    end
   end
 
   def self.admins_search(string, role)
@@ -149,21 +102,17 @@ class User < ApplicationRecord
 
   # Activates an account and initialize a users main room
   def activate
-    update_attribute(:email_verified, true)
-    update_attribute(:activated_at, Time.zone.now)
-    save
+    update_attributes(email_verified: true, activated_at: Time.zone.now)
   end
 
   def activated?
-    return true unless Rails.configuration.enable_email_verification
-    email_verified
+    Rails.configuration.enable_email_verification ? email_verified : true
   end
 
   # Sets the password reset attributes.
   def create_reset_digest
     self.reset_token = User.new_token
-    update_attribute(:reset_digest,  User.digest(reset_token))
-    update_attribute(:reset_sent_at, Time.zone.now)
+    update_attributes(reset_digest: User.digest(reset_token), reset_sent_at: Time.zone.now)
   end
 
   # Returns true if the given token matches the digest.
@@ -288,8 +237,7 @@ class User < ApplicationRecord
 
   def create_reset_activation_digest(token)
     # Create the digest and persist it.
-    self.activation_digest = User.digest(token)
-    save
+    update_attribute(:activation_digest, User.digest(token))
     token
   end
 
@@ -298,19 +246,17 @@ class User < ApplicationRecord
     rooms.destroy_all
   end
 
-  # Initializes a room for the user and assign a BigBlueButton user id.
-  def initialize_main_room
-    self.uid = "gl-#{(0...12).map { rand(65..90).chr }.join.downcase}"
-    self.main_room = Room.create!(owner: self, name: I18n.t("home_room"))
-    save
-  end
+  def setup_user
+    # Initializes a room for the user and assign a BigBlueButton user id.
+    id = "gl-#{(0...12).map { rand(65..90).chr }.join.downcase}"
+    room = Room.create!(owner: self, name: I18n.t("home_room"))
 
-  # Initialize the user to use the default user role
-  def assign_default_role
+    update_attributes(uid: id, main_room: room)
+
+    # Initialize the user to use the default user role
     role_provider = Rails.configuration.loadbalanced_configuration ? provider : "greenlight"
 
     Role.create_default_roles(role_provider) if Role.where(provider: role_provider).count.zero?
-
     add_role(:user) if roles.blank?
   end
 
diff --git a/app/views/admins/components/_server_recording_row.html.erb b/app/views/admins/components/_server_recording_row.html.erb
index 1bfd3767..128a4d7f 100644
--- a/app/views/admins/components/_server_recording_row.html.erb
+++ b/app/views/admins/components/_server_recording_row.html.erb
@@ -15,7 +15,7 @@
 
  
   | 
-     |    |