diff --git a/Gemfile b/Gemfile index 4a19fefb..62c0f7f8 100644 --- a/Gemfile +++ b/Gemfile @@ -63,6 +63,9 @@ gem 'http_accept_language' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development +# Markdown parsing. +gem 'redcarpet' + group :production do # Use a postgres database in production. gem 'pg', '~> 0.18' diff --git a/Gemfile.lock b/Gemfile.lock index 21744073..daafd4ef 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -189,6 +189,7 @@ GEM rb-fsevent (0.10.3) rb-inotify (0.9.10) ffi (>= 0.5.0, < 2) + redcarpet (3.4.0) redis (3.3.5) ref (2.0.0) rspec-core (3.7.1) @@ -296,6 +297,7 @@ DEPENDENCIES puma (~> 3.0) rails (~> 5.0.7) rails-controller-testing + redcarpet redis (~> 3.0) rspec-rails (~> 3.7) rubocop diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 60b489b9..fadc0d35 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -51,10 +51,6 @@ a { min-height: calc(100% - #{$header-height} - #{$footer-height}); } -.flex-center { - transform: translateY(25%); -} - .footer { height: $footer-height; width: 100%; @@ -103,5 +99,4 @@ a { .terms { overflow: scroll; height: 55vh; - white-space: pre-line; } diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 877cc49e..198ae8b7 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class UsersController < ApplicationController - before_action :find_user, only: [:edit, :update] + before_action :find_user, only: [:edit, :update, :destroy] before_action :ensure_unauthenticated, only: [:new, :create] # POST /u @@ -72,6 +72,15 @@ class UsersController < ApplicationController end end + # DELETE /u/:user_uid + def destroy + if current_user && current_user == @user + @user.destroy + session.delete(:user_id) + end + redirect_to root_path + end + # GET /u/terms def terms redirect_to root_path unless current_user diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 85a8a4fa..dc932263 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -25,7 +25,22 @@ module ApplicationHelper Rails.configuration.allow_user_signup end + # Determines if the BigBlueButton endpoint is the default. def bigbluebutton_endpoint_default? Rails.configuration.bigbluebutton_endpoint_default == Rails.configuration.bigbluebutton_endpoint end + + # Parses markdown for rendering. + def markdown(text) + markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML, + no_intra_emphasis: true, + fenced_code_blocks: true, + disable_indented_code_blocks: true, + autolink: true, + tables: true, + underline: true, + highlight: true) + + markdown.render(text).html_safe + end end diff --git a/app/models/room.rb b/app/models/room.rb index bc439f8a..10370c66 100644 --- a/app/models/room.rb +++ b/app/models/room.rb @@ -3,6 +3,8 @@ class Room < ApplicationRecord before_create :setup + before_destroy :delete_all_recordings + validates :name, presence: true belongs_to :owner, class_name: 'User', foreign_key: :user_id @@ -155,6 +157,12 @@ class Room < ApplicationRecord self.bbb_id = Digest::SHA1.hexdigest(Rails.application.secrets[:secret_key_base] + Time.now.to_i.to_s).to_s end + # Deletes all recordings associated with the room. + def delete_all_recordings + record_ids = recordings.map { |r| r[:recordID] } + delete_recording(record_ids) unless record_ids.empty? + end + # Generates a three character uid chunk. def uid_chunk charset = ("a".."z").to_a - %w(b i l o s) + ("2".."9").to_a - %w(5 8) diff --git a/app/models/user.rb b/app/models/user.rb index 88f253a3..4f1b31ac 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -4,6 +4,8 @@ class User < ApplicationRecord after_create :initialize_main_room before_save { email.try(:downcase!) } + before_destroy :destroy_rooms + has_many :rooms belongs_to :main_room, class_name: 'Room', foreign_key: :room_id, required: false @@ -83,6 +85,11 @@ class User < ApplicationRecord private + # Destory a users rooms when they are removed. + def destroy_rooms + 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 { (65 + rand(26)).chr }.join.downcase}" diff --git a/app/views/application/migration_error.html.erb b/app/views/application/migration_error.html.erb index 06d9d420..b1e90fc1 100644 --- a/app/views/application/migration_error.html.erb +++ b/app/views/application/migration_error.html.erb @@ -1,16 +1,12 @@ -
-
-
- -

<%= t("errors.migration_error.notice") %>

-

<%= t("errors.migration_error.contact_admin") %>

-

<%= t("errors.migration_error.version") %>

- - <%= t("errors.migration_error.upgrade") %> - - - <%= t("errors.migration_error.continue") %> - -
-
+
+ +

<%= t("errors.migration_error.notice").html_safe %>

+

<%= t("errors.migration_error.contact_admin") %>

+

<%= t("errors.migration_error.version") %>

+ + <%= t("errors.migration_error.upgrade") %> + + + <%= t("errors.migration_error.continue") %> +
diff --git a/app/views/errors/internal_error.html.erb b/app/views/errors/internal_error.html.erb index ddf4c539..32419b57 100644 --- a/app/views/errors/internal_error.html.erb +++ b/app/views/errors/internal_error.html.erb @@ -1,12 +1,8 @@ -
-
-
-
500
-

<%= t("errors.internal.message") %>

-

<%= t("errors.internal.help") %>

- - <%= t("go_back") %> - -
-
+
+
500
+

<%= t("errors.internal.message") %>

+

<%= t("errors.internal.help") %>

+ + <%= t("go_back") %> +
diff --git a/app/views/errors/not_found.html.erb b/app/views/errors/not_found.html.erb index 82f6b7f1..fae449dc 100644 --- a/app/views/errors/not_found.html.erb +++ b/app/views/errors/not_found.html.erb @@ -1,12 +1,8 @@ -
-
-
-
404
-

<%= t("errors.not_found.message") %>

-

<%= t("errors.not_found.help") %>

- - <%= t("go_back") %> - -
-
+
+
404
+

<%= t("errors.not_found.message") %>

+

<%= t("errors.not_found.help") %>

+ + <%= t("go_back") %> +
diff --git a/app/views/errors/unprocessable.html.erb b/app/views/errors/unprocessable.html.erb index 67958f07..9aac5bd7 100644 --- a/app/views/errors/unprocessable.html.erb +++ b/app/views/errors/unprocessable.html.erb @@ -1,12 +1,8 @@ -
-
-
-
422
-

<%= t("errors.unprocessable.message") %>

-

<%= t("errors.unprocessable.help") %>

- - <%= t("go_back") %> - -
-
+
+
422
+

<%= t("errors.unprocessable.message") %>

+

<%= t("errors.unprocessable.help") %>

+ + <%= t("go_back") %> +
diff --git a/app/views/shared/modals/_delete_account_modal.html.erb b/app/views/shared/modals/_delete_account_modal.html.erb new file mode 100644 index 00000000..90b60174 --- /dev/null +++ b/app/views/shared/modals/_delete_account_modal.html.erb @@ -0,0 +1,25 @@ + diff --git a/app/views/shared/settings/_delete.html.erb b/app/views/shared/settings/_delete.html.erb new file mode 100644 index 00000000..9412eb0d --- /dev/null +++ b/app/views/shared/settings/_delete.html.erb @@ -0,0 +1,15 @@ +
+
+
+
+ <%= t("settings.delete.disclaimer").html_safe %> +
+ + <%= t("settings.delete.button") %> + +
+
+
+
+ +<%= render "shared/modals/delete_account_modal" %> diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index 11854729..797d99b3 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -1,4 +1,4 @@ -
+
<%= render "shared/components/subtitle", subtitle: t("settings.title"), search: false %>
@@ -17,6 +17,10 @@ + +
<% if @user.errors.any? %> @@ -42,6 +46,8 @@ <% end %> <%= render "shared/settings/setting_view", setting_id: "design", setting_title: t("settings.design.subtitle") %> + + <%= render "shared/settings/setting_view", setting_id: "delete", setting_title: t("settings.delete.subtitle") %>
diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index 3e477cca..ec65b481 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -1,5 +1,5 @@
-
+
diff --git a/app/views/users/terms.html.erb b/app/views/users/terms.html.erb index a0220725..521cee63 100644 --- a/app/views/users/terms.html.erb +++ b/app/views/users/terms.html.erb @@ -1,4 +1,4 @@ -
+
@@ -6,9 +6,9 @@
-

<%= Rails.configuration.terms %>

+ <%= markdown(Rails.configuration.terms) %>
-
+
<%= button_to t("terms.accept"), terms_path, params: {accept: true}, class: "btn btn-primary btn-space" %>
diff --git a/config/initializers/terms.rb b/config/initializers/terms.rb index 26e5da70..15e278cb 100644 --- a/config/initializers/terms.rb +++ b/config/initializers/terms.rb @@ -2,7 +2,7 @@ # Load terms and conditions. -terms = "#{Rails.root}/config/terms.txt" +terms = "#{Rails.root}/config/terms.md" Rails.configuration.terms = if File.exist?(terms) File.read(terms) diff --git a/config/locales/en.yml b/config/locales/en.yml index edd5cedf..ae3c6332 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -18,6 +18,8 @@ en: notice: > Greenlight encountered a database migration error.
This may be because you haven't updated to Greenlight 2.0. + upgrade: Show me how to upgrade to 2.0! + version: We've released a new version of Greenlight, but your database isn't compatible. not_found: message: Whoops! Looks like we can't find that. help: Is it possible its been removed? @@ -61,6 +63,11 @@ en: name_placeholder: Enter a room name... not_blank: Room name cannot be blank. title: Create New Room + delete_account: + confirm: Are you sure you want to delete your account? + delete: I'm sure, delete my account. + keep: Actually, I'll keep it. + warning: This decision is final. You will not be able to recover associated data. delete_room: confirm: Are you sure you want to delete %{room}? delete: I'm sure, delete this room. @@ -106,7 +113,12 @@ en: image: Image image_url: Profile Image URL subtitle: Update your Account Info - title: Account + title: Account Info + delete: + button: Yes, I would like to delete my account. + disclaimer: If you choose to delete your account, it will NOT be recoverable. All information regarding your account, including settings, rooms, and recording will be removed. + subtitle: Permanently Delete your Account + title: Delete Account design: not_supported: Customization not currently supported. subtitle: Customize Greenlight diff --git a/config/routes.rb b/config/routes.rb index bc3f4b98..c8d4d65e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,8 +20,10 @@ Rails.application.routes.draw do # Log the user out of the session. get '/logout', to: 'sessions#destroy' + # Account management. get '/:user_uid/edit', to: 'users#edit', as: :edit_user patch '/:user_uid/edit', to: 'users#update', as: :update_user + delete '/:user_uid', to: 'users#destroy', as: :delete_user end # Handles Omniauth authentication.