diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index b7565e04659c45c3045746841eacfac34d7a18fe..28d9fa8002870cc7f2c8d8e6a02af47dcca6733d 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -97,13 +97,11 @@ class UsersController < ApplicationController
     redirect_to root_path
   end
 
-  # GET /u/terms
+  # GET /terms
   def terms
-    redirect_to root_path unless current_user
-
     if params[:accept] == "true"
-      current_user.update_attribute(accepted_terms: true)
-      redirect_to current_user.main_room
+      current_user.update_attributes(accepted_terms: true)
+      redirect_to current_user.main_room if current_user
     end
   end
 
@@ -118,6 +116,7 @@ class UsersController < ApplicationController
   end
 
   def user_params
-    params.require(:user).permit(:name, :email, :image, :password, :password_confirmation, :new_password, :provider)
+    params.require(:user).permit(:name, :email, :image, :password, :password_confirmation,
+      :new_password, :provider, :accepted_terms)
   end
 end
diff --git a/app/models/user.rb b/app/models/user.rb
index f71699a836ffc4b28eb11916c3ae50e736b105c7..06b2b81a809e49739ddf27b903ff6bd2695d8f06 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -34,6 +34,9 @@ class User < ApplicationRecord
 
   validates :password, length: { minimum: 6 }, confirmation: true, if: :greenlight_account?, on: :create
 
+  # Bypass validation if omniauth
+  validates :accepted_terms, acceptance: true, unless: proc { !greenlight_account? }
+
   # We don't want to require password validations on all accounts.
   has_secure_password(validations: false)
 
diff --git a/app/views/shared/components/_terms_button.html.erb b/app/views/shared/components/_terms_button.html.erb
new file mode 100644
index 0000000000000000000000000000000000000000..de46d3909239b3fa4a2196268bcfc1b479204245
--- /dev/null
+++ b/app/views/shared/components/_terms_button.html.erb
@@ -0,0 +1,18 @@
+<%
+# 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 <http://www.gnu.org/licenses/>.
+%>
+
+<div class="btn-list text-right pt-8">
+    <%= button_to t("terms.accept_existing"), terms_path, params: { accept: true }, class: "btn btn-primary btn-space" %>
+</div>
\ No newline at end of file
diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb
index b2c3a48e50e83f6c2e71f8a1415b2bd7e2f7e38f..52fe644e43077f468b83f0b67226805e63b75b62 100644
--- a/app/views/users/new.html.erb
+++ b/app/views/users/new.html.erb
@@ -57,6 +57,11 @@
               <%= f.password_field :password_confirmation, class: "form-control #{form_is_invalid?(@user, :password_confirmation)}", placeholder: t("signup.password_confirm") %>
               <div class="invalid-feedback d-block"><%= @user.errors.full_messages_for(:password_confirmation).first %></div>
             </div>
+            <div class="form-inline">
+              <%= f.check_box :accepted_terms, class: "form-control #{form_is_invalid?(@user, :accepted_terms)}", placeholder: t("signup.password_confirm") %>
+              <%= f.label :accepted_terms, t("terms.accept", href: link_to(t("terms.title"), terms_path, target: "_blank", class: "ml-1 text-blue")).html_safe, class: "ml-1" %>
+              <div class="invalid-feedback d-block"><%= @user.errors.full_messages_for(:accepted_terms).first %></div>
+            </div>
             <div class="card-footer">
               <%= f.submit t("signup.title"), class: "btn btn-primary float-right ml-2" %>
               <%= link_to t("cancel"), root_path, class: "btn btn-secondary float-right ml-2" %>
diff --git a/app/views/users/terms.html.erb b/app/views/users/terms.html.erb
index c8ff6e8a41db4466454c62e5f37e69cf201c1db2..488d30098e6420c05fcc5a228fedaf114e2c98b2 100644
--- a/app/views/users/terms.html.erb
+++ b/app/views/users/terms.html.erb
@@ -23,9 +23,9 @@
           <div class="terms">
             <%= markdown(Rails.configuration.terms) %>
           </div>
-          <div class="btn-list text-right pt-8">
-            <%= button_to t("terms.accept"), terms_path, params: {accept: true}, class: "btn btn-primary btn-space" %>
-          </div>
+          <% if Rails.configuration.terms && current_user && !current_user.accepted_terms %>
+            <%= render "/shared/components/terms_button" %>
+          <% end %>
         </form>
       </div>
     </div>
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 0d9af608a76cef16d07f37c6e4873749b5801f62..fecb64dc45ea48462a9e9e2159ab2e0c9fe05967 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -17,6 +17,10 @@
 # English (en) locale.
 
 en:
+  activerecord:
+    attributes:
+      user:
+        accepted_terms: "Terms and Conditions"
   bigbluebutton: BigBlueButton
   cancel: Cancel
   copy: Copy
@@ -152,7 +156,8 @@ en:
     title: Signup
     with: Signup with %{provider}
   terms:
-    accept: I accept the terms and conditions.
+    accept: I accept the %{href}
+    accept_existing: I accept the terms and conditions
     title: Terms and Conditions
   test_install: >
     This deployment is using a pre-configured testing server, you should replace this with your own.
diff --git a/config/routes.rb b/config/routes.rb
index 87fbd34eaaddf6d3e90a80f0019bd2d68c42b66e..66b7d111b93733ca5f88935f1450c14df6dabed6 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -26,12 +26,13 @@ Rails.application.routes.draw do
   get '/signup', to: 'users#new', as: :signup
   post '/signup', to: 'users#create', as: :create_user
 
+  # Redirect to terms page
+  match '/terms', to: 'users#terms', via: [:get, :post]
+
   # User resources.
   scope '/u' do
-    match '/terms', to: 'users#terms', via: [:get, :post]
-
     # Handles login of greenlight provider accounts.
-    post '/login',  to: 'sessions#create', as: :create_session
+    post '/login', to: 'sessions#create', as: :create_session
 
     # Log the user out of the session.
     get '/logout', to: 'sessions#destroy'
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index e546903fee734ee95c9512f01976decb00d52b35..fd1c18b287bd01f118f07d98301843504fd2aa82 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -26,6 +26,7 @@ def random_valid_user_params
       email: Faker::Internet.email,
       password: pass,
       password_confirmation: pass,
+      accepted_terms: true,
     },
   }
 end
@@ -37,7 +38,8 @@ describe UsersController, type: :controller do
         name: "Invalid",
         email: "example.com",
         password: "pass",
-        passwrd_confirmation: "invalid",
+        password_confirmation: "invalid",
+        accepted_terms: false,
       },
     }
   end
diff --git a/spec/factories.rb b/spec/factories.rb
index 54bc95866a3a613aec5c2b68b25a461a00610a7b..7d4cd00ce816c16d7fca4489b9bec273dc691bee 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -27,6 +27,7 @@ FactoryBot.define do
     email { Faker::Internet.email }
     password { password }
     password_confirmation { password }
+    accepted_terms { true }
   end
 
   factory :room do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 6677a740cf94dc3b8e2e30647cffc87da118d4ee..33fffc0457e4408e09a177e4353b3426e56c5cfb 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -34,6 +34,8 @@ describe User, type: :model do
     it { should allow_value("", nil).for(:email) }
     it { should allow_value("valid@email.com").for(:email) }
     it { should_not allow_value("invalid_email").for(:email) }
+    it { should allow_value(true).for(:accepted_terms) }
+    it { should allow_value(false).for(:accepted_terms) }
 
     it { should allow_value("valid.jpg").for(:image) }
     it { should allow_value("valid.png").for(:image) }