Compare commits
3 Commits
01c0ab9cc0
...
2f940fab13
Author | SHA1 | Date |
---|---|---|
Trevor Vallender | 2f940fab13 | |
Trevor Vallender | f17b5046c4 | |
Trevor Vallender | ac0f759a4a |
3
Gemfile
3
Gemfile
|
@ -20,11 +20,14 @@ gem "image_processing", "~> 1.2"
|
||||||
gem "solid_queue"
|
gem "solid_queue"
|
||||||
gem "mission_control-jobs"
|
gem "mission_control-jobs"
|
||||||
|
|
||||||
|
gem "active_storage_validations"
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem "debug", platforms: %i[ mri windows ]
|
gem "debug", platforms: %i[ mri windows ]
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
gem "letter_opener"
|
||||||
gem "rubocop-rails-omakase"
|
gem "rubocop-rails-omakase"
|
||||||
gem "web-console"
|
gem "web-console"
|
||||||
end
|
end
|
||||||
|
|
13
Gemfile.lock
13
Gemfile.lock
|
@ -50,6 +50,11 @@ GEM
|
||||||
erubi (~> 1.11)
|
erubi (~> 1.11)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
|
active_storage_validations (1.1.4)
|
||||||
|
activejob (>= 5.2.0)
|
||||||
|
activemodel (>= 5.2.0)
|
||||||
|
activestorage (>= 5.2.0)
|
||||||
|
activesupport (>= 5.2.0)
|
||||||
activejob (7.1.3.3)
|
activejob (7.1.3.3)
|
||||||
activesupport (= 7.1.3.3)
|
activesupport (= 7.1.3.3)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
|
@ -94,6 +99,7 @@ GEM
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
regexp_parser (>= 1.5, < 3.0)
|
regexp_parser (>= 1.5, < 3.0)
|
||||||
xpath (~> 3.2)
|
xpath (~> 3.2)
|
||||||
|
childprocess (5.0.0)
|
||||||
concurrent-ruby (1.2.3)
|
concurrent-ruby (1.2.3)
|
||||||
connection_pool (2.4.1)
|
connection_pool (2.4.1)
|
||||||
crass (1.0.6)
|
crass (1.0.6)
|
||||||
|
@ -129,6 +135,11 @@ GEM
|
||||||
activesupport (>= 5.0.0)
|
activesupport (>= 5.0.0)
|
||||||
json (2.7.2)
|
json (2.7.2)
|
||||||
language_server-protocol (3.17.0.3)
|
language_server-protocol (3.17.0.3)
|
||||||
|
launchy (3.0.1)
|
||||||
|
addressable (~> 2.8)
|
||||||
|
childprocess (~> 5.0)
|
||||||
|
letter_opener (1.10.0)
|
||||||
|
launchy (>= 2.2, < 4)
|
||||||
loofah (2.22.0)
|
loofah (2.22.0)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.12.0)
|
nokogiri (>= 1.12.0)
|
||||||
|
@ -314,6 +325,7 @@ PLATFORMS
|
||||||
x86_64-linux
|
x86_64-linux
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
active_storage_validations
|
||||||
bcrypt (~> 3.1.7)
|
bcrypt (~> 3.1.7)
|
||||||
bootsnap
|
bootsnap
|
||||||
capybara
|
capybara
|
||||||
|
@ -321,6 +333,7 @@ DEPENDENCIES
|
||||||
image_processing (~> 1.2)
|
image_processing (~> 1.2)
|
||||||
importmap-rails
|
importmap-rails
|
||||||
jbuilder
|
jbuilder
|
||||||
|
letter_opener
|
||||||
mission_control-jobs
|
mission_control-jobs
|
||||||
pg
|
pg
|
||||||
propshaft
|
propshaft
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
:root {
|
:root {
|
||||||
|
--background-color: #333;
|
||||||
|
--main-background-color:
|
||||||
|
--header-color: #15345b;
|
||||||
|
--header-text-color: #fff;
|
||||||
|
--header-height: 200px;
|
||||||
|
|
||||||
--inset-bg-color: #eee;
|
--inset-bg-color: #eee;
|
||||||
|
|
||||||
--border-radius: .5em;
|
--border-radius: .5em;
|
||||||
|
|
|
@ -32,7 +32,7 @@ form, fieldset {
|
||||||
font-size: .8em;
|
font-size: .8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset, p, trix-editor {
|
fieldset, p, trix-editor, hr {
|
||||||
grid-column: 1/3;
|
grid-column: 1/3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,18 @@
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
margin: 0 auto;
|
background-color: var(--background-color);
|
||||||
max-width: 80em;
|
min-width: 30em;
|
||||||
padding: 1em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
background: linear-gradient(180deg, rgba(227,220,190,1) 0%, rgba(255,248,238,1) 100%);
|
||||||
|
max-width: 80vw;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
padding: 1em;
|
||||||
|
margin: 0 auto;
|
||||||
|
min-height: calc(100vh - var(--header-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
aside.flash {
|
aside.flash {
|
||||||
|
@ -38,6 +42,35 @@ h1, h2 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
background: linear-gradient(180deg, rgba(34,45,113,1) 0%, rgba(22,90,157,1) 100%);
|
||||||
|
position: relative;
|
||||||
|
padding: 0 50px;
|
||||||
|
margin-right: 2em;
|
||||||
|
height: var(--header-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Angled banner end */
|
||||||
|
header:before {
|
||||||
|
content: "";
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-top: calc(var(--header-height) / 2) solid transparent;
|
||||||
|
border-bottom: calc(var(--header-height) / 2) solid transparent;
|
||||||
|
border-right: calc(var(--header-height) / 2) solid var(--background-color);
|
||||||
|
position: absolute;
|
||||||
|
right:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 {
|
||||||
|
padding: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
header h1 a:link, header h1 a:visited {
|
||||||
|
color: var(--header-text-color);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
header nav {
|
header nav {
|
||||||
ul {
|
ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -59,3 +92,7 @@ header nav {
|
||||||
color: var(--button-hover-text-color);
|
color: var(--button-hover-text-color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class PasswordResetsController < ApplicationController
|
||||||
|
skip_before_action :authenticate
|
||||||
|
|
||||||
|
def new
|
||||||
|
reset_session
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
user = User.find_by(username: params[:username])
|
||||||
|
if user
|
||||||
|
token = user.generate_token_for(:password_reset)
|
||||||
|
UserMailer.with(user: user, token: token).password_reset.deliver_later
|
||||||
|
redirect_to new_session_path, notice: t(".success") and return
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to :root, notice: t(".error")
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
reset_session
|
||||||
|
@user = User.find_by(username: params[:id])
|
||||||
|
@token = params[:token]
|
||||||
|
unless @user == User.find_by_token_for(:password_reset, params[:token])
|
||||||
|
redirect_to :root, notice: t(".invalid_token") and return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
user = User.find_by(username: params[:id])
|
||||||
|
unless user == User.find_by_token_for(:password_reset, params[:token])
|
||||||
|
redirect_to :root, notice: t(".invalid_token") and return
|
||||||
|
end
|
||||||
|
|
||||||
|
if user.update(password: params[:password], password_confirmation: params[:password_confirmation])
|
||||||
|
redirect_to new_session_path, notice: t(".success")
|
||||||
|
else
|
||||||
|
redirect_to :root, notice: t(".error")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -4,7 +4,7 @@ class TablesController < ApplicationController
|
||||||
before_action :set_table, only: [ :show, :edit, :update, :destroy ]
|
before_action :set_table, only: [ :show, :edit, :update, :destroy ]
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@owned_tables = Current.user.owned_tables
|
@tables = Current.user.tables
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
|
|
@ -61,6 +61,7 @@ class UsersController < ApplicationController
|
||||||
:first_name,
|
:first_name,
|
||||||
:last_name,
|
:last_name,
|
||||||
:profile,
|
:profile,
|
||||||
|
:avatar,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,12 @@ class TableInviteMailer < ApplicationMailer
|
||||||
def invite_user
|
def invite_user
|
||||||
@table_invite = params[:table_invite]
|
@table_invite = params[:table_invite]
|
||||||
|
|
||||||
mail(to: @table_invite.email, subject: "[Tabletop Companion] Invite to join a table")
|
mail(to: @table_invite.email, subject: t(".invite_user.subject"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def invite_new_user
|
def invite_new_user
|
||||||
@table_invite = params[:table_invite]
|
@table_invite = params[:table_invite]
|
||||||
|
|
||||||
mail(to: @table_invite.email, subject: "[Tabletop Companion] You’ve been invited to a game!")
|
mail(to: @table_invite.email, subject: t(".invite_new_user.subject"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,12 +7,19 @@ class UserMailer < ApplicationMailer
|
||||||
@user = params[:user]
|
@user = params[:user]
|
||||||
@token = params[:token]
|
@token = params[:token]
|
||||||
|
|
||||||
mail(to: @user.email, subject: "[Tabletop Companion] Verify your email")
|
mail(to: @user.email, subject: t(".email_verification.subject"))
|
||||||
end
|
end
|
||||||
|
|
||||||
def email_verified
|
def email_verified
|
||||||
@user = params[:user]
|
@user = params[:user]
|
||||||
|
|
||||||
mail(to: @user.email, subject: "[Tabletop Companion] Your email has been verified")
|
mail(to: @user.email, subject: t(".email_verified.subject"))
|
||||||
|
end
|
||||||
|
|
||||||
|
def password_reset
|
||||||
|
@user = params[:user]
|
||||||
|
@token = params[:token]
|
||||||
|
|
||||||
|
mail(to: @user.email, subject: t(".password_reset.subject"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,11 @@ class User < ApplicationRecord
|
||||||
has_many :players, dependent: :destroy
|
has_many :players, dependent: :destroy
|
||||||
has_many :tables, through: :players
|
has_many :tables, through: :players
|
||||||
has_rich_text :profile
|
has_rich_text :profile
|
||||||
|
has_one_attached :avatar do |attachable|
|
||||||
|
attachable.variant :standard, resize_to_limit: [ 100, 100 ], preprocessed: true
|
||||||
|
end
|
||||||
|
validates :avatar, content_type: /\Aimage\/.*\z/,
|
||||||
|
dimension: { width: { in: 10..1000 }, height: { in: 10..1000 } }
|
||||||
|
|
||||||
has_secure_password
|
has_secure_password
|
||||||
generates_token_for :password_reset, expires_in: 4.hours do
|
generates_token_for :password_reset, expires_in: 4.hours do
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
<%= render partial: "shared/flash_messages" %>
|
|
||||||
<main>
|
<main>
|
||||||
|
<%= render partial: "shared/flash_messages" %>
|
||||||
<%= yield(:submenu) if content_for?(:submenu) %>
|
<%= yield(:submenu) if content_for?(:submenu) %>
|
||||||
<%= yield %>
|
<%= yield %>
|
||||||
</main>
|
</main>
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
<%= content_for :title, t(".reset_password") %>
|
||||||
|
|
||||||
|
<h2><%= t(".reset_password") %></h2>
|
||||||
|
|
||||||
|
<section class="inset">
|
||||||
|
<%= form_with url: password_reset_path(id: @user.username), method: :patch do |f| %>
|
||||||
|
<%= f.hidden_field :token, value: @token %>
|
||||||
|
|
||||||
|
<%= f.label :password %>
|
||||||
|
<%= f.password_field :password %>
|
||||||
|
|
||||||
|
<%= f.label :password_confirmation %>
|
||||||
|
<%= f.password_field :password_confirmation %>
|
||||||
|
|
||||||
|
<%= f.submit t(".reset_password_button") %>
|
||||||
|
<% end %>
|
||||||
|
</section>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<%= content_for :title, t(".reset_password") %>
|
||||||
|
|
||||||
|
<h2><%= t(".reset_password") %></h2>
|
||||||
|
<section class="inset">
|
||||||
|
<p><%= t(".forgotten_password_intro") %></p>
|
||||||
|
|
||||||
|
<%= form_with url: password_resets_path do |f| %>
|
||||||
|
<%= f.label :username %>
|
||||||
|
<%= f.text_field :username %>
|
||||||
|
|
||||||
|
<%= f.submit t(".reset_password_button") %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
|
@ -14,3 +14,4 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<%= link_to(t(".forgot_password"), new_password_reset_path) %>
|
||||||
|
|
|
@ -2,4 +2,7 @@
|
||||||
|
|
||||||
<div id="<%= dom_id(table) %>" class="table">
|
<div id="<%= dom_id(table) %>" class="table">
|
||||||
<h4><%= link_to table.name, table %></h4>
|
<h4><%= link_to table.name, table %></h4>
|
||||||
|
<% if table.owner == Current.user %>
|
||||||
|
OWNER
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
<% content_for :title, t(".tables") %>
|
<% content_for :title, t(".tables") %>
|
||||||
|
|
||||||
|
<h2><%= t(".tables") %></h2>
|
||||||
|
|
||||||
<%= link_to t(".new_table"), new_table_path %>
|
<%= link_to t(".new_table"), new_table_path %>
|
||||||
|
|
||||||
<h2>Tables you own</h2>
|
<% if @tables.any? %>
|
||||||
<% if @owned_tables.any? %>
|
<%= render @tables %>
|
||||||
<%= render @owned_tables %>
|
|
||||||
<% else %>
|
<% else %>
|
||||||
<p>You do not own any tables.</p>
|
<p><%= t(".no_tables") %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
<%= htmlify_email(t(".content")) %>
|
||||||
|
|
||||||
|
<%= link_to t(".reset_password"), edit_password_reset_url(id: @user, token: @token) %>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<%= t(".content") %>
|
||||||
|
|
||||||
|
<%= edit_password_reset_url(id: @user, token: @token) %>
|
|
@ -38,7 +38,13 @@
|
||||||
<%= display_form_errors(user, :password_confirmation) %>
|
<%= display_form_errors(user, :password_confirmation) %>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
<% if user.persisted? %>
|
<% if user.persisted? %>
|
||||||
|
<%= f.label :avatar %>
|
||||||
|
<%= f.file_field :avatar %>
|
||||||
|
<%= display_form_errors(user, :avatar) %>
|
||||||
|
|
||||||
<%= f.label :profile %>
|
<%= f.label :profile %>
|
||||||
<%= f.rich_text_area :profile %>
|
<%= f.rich_text_area :profile %>
|
||||||
<%= display_form_errors(user, :profile) %>
|
<%= display_form_errors(user, :profile) %>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<%= content_for :title, @user.username %>
|
<%= content_for :title, @user.username %>
|
||||||
|
|
||||||
<h2><%= @user.username %></h2>
|
<h2><%= @user.username %></h2>
|
||||||
|
<%= image_tag(url_for(@user.avatar.variant(:standard)), width: "100px", height: "100px") if @user.avatar.attached? %>
|
||||||
|
|
||||||
<aside>
|
<aside>
|
||||||
<% if @user == Current.user %>
|
<% if @user == Current.user %>
|
||||||
|
|
|
@ -40,6 +40,7 @@ Rails.application.configure do
|
||||||
|
|
||||||
# Don't care if the mailer can't send.
|
# Don't care if the mailer can't send.
|
||||||
config.action_mailer.raise_delivery_errors = false
|
config.action_mailer.raise_delivery_errors = false
|
||||||
|
config.action_mailer.delivery_method = :letter_opener
|
||||||
|
|
||||||
config.action_mailer.perform_caching = false
|
config.action_mailer.perform_caching = false
|
||||||
|
|
||||||
|
|
|
@ -54,22 +54,42 @@ en:
|
||||||
destroy:
|
destroy:
|
||||||
success: Successfully deleted “%{name}”.
|
success: Successfully deleted “%{name}”.
|
||||||
error: “%{name}” could not be deleted.
|
error: “%{name}” could not be deleted.
|
||||||
|
password_resets:
|
||||||
|
new:
|
||||||
|
reset_password: Reset your password
|
||||||
|
forgotten_password_intro: |-
|
||||||
|
If you have forgotten your password, enter your information below to reset it.
|
||||||
|
reset_password_button: Reset password
|
||||||
|
create:
|
||||||
|
success: Please check your email to reset your password.
|
||||||
|
error: Could not reset your password.
|
||||||
|
edit:
|
||||||
|
reset_password: Reset your password
|
||||||
|
invalid_token: That token seems to have expired, please try resettting your password again.
|
||||||
|
reset_password_button: Update password
|
||||||
|
update:
|
||||||
|
invalid_token: That token seems to have expired, please try resettting your password again.
|
||||||
|
success: Your password has been reset, you may now log in.
|
||||||
|
error: Failed to reset password. Please try again or contact us for help.
|
||||||
sessions:
|
sessions:
|
||||||
create:
|
create:
|
||||||
success: "Hello, %{name}!"
|
success: "Hello, %{name}!"
|
||||||
error: "Could not sign in. Please check your username and password."
|
error: "Could not sign in. Please check your username and password."
|
||||||
new:
|
new:
|
||||||
log_in: Log in
|
log_in: Log in
|
||||||
|
forgot_password: Forgotten your password?
|
||||||
destroy:
|
destroy:
|
||||||
log_out: Log out
|
log_out: Log out
|
||||||
success: "You have signed out."
|
success: "You have signed out."
|
||||||
table_invite_mailer:
|
table_invite_mailer:
|
||||||
invite_new_user:
|
invite_new_user:
|
||||||
|
subject: You’ve been invited to join a game on Tabletop Companion!
|
||||||
content: |-
|
content: |-
|
||||||
You’ve been invited to join a game on Tabletop Companion. To start playing, sign up at the
|
You’ve been invited to join a game on Tabletop Companion. To start playing, sign up at the
|
||||||
link below and accept your invitation!
|
link below and accept your invitation!
|
||||||
sign_up: Sign up now
|
sign_up: Sign up now
|
||||||
invite_user:
|
invite_user:
|
||||||
|
subject: You’ve been invited to a new game!
|
||||||
content: |-
|
content: |-
|
||||||
You have been invited to join the table “%{table_name}” on Tabletop Companion. To
|
You have been invited to join the table “%{table_name}” on Tabletop Companion. To
|
||||||
respond, visit the link below.
|
respond, visit the link below.
|
||||||
|
@ -99,6 +119,7 @@ en:
|
||||||
index:
|
index:
|
||||||
new_table: Create a table
|
new_table: Create a table
|
||||||
tables: Tables
|
tables: Tables
|
||||||
|
no_tables: You are currently not at any tables. Why not create one?
|
||||||
show:
|
show:
|
||||||
edit_table: Edit table
|
edit_table: Edit table
|
||||||
game_system: Game system
|
game_system: Game system
|
||||||
|
@ -144,13 +165,22 @@ en:
|
||||||
error: Failed to update profile
|
error: Failed to update profile
|
||||||
user_mailer:
|
user_mailer:
|
||||||
email_verified:
|
email_verified:
|
||||||
|
subject: Email verified on Tabletop Companion
|
||||||
content: |-
|
content: |-
|
||||||
Thanks for verifying your email address, and welcome to Tabletop Companion!
|
Thanks for verifying your email address, and welcome to Tabletop Companion!
|
||||||
|
|
||||||
You can now go ahead and log in. Enjoy!
|
You can now go ahead and log in. Enjoy!
|
||||||
email_verification:
|
email_verification:
|
||||||
|
subject: Verify your email on Tabletop Companion
|
||||||
content: |-
|
content: |-
|
||||||
If you did not sign up for Tabletop Companion, please ignore this email.
|
If you did not sign up for Tabletop Companion, please ignore this email.
|
||||||
|
|
||||||
Otherwise, please visit the link below to verify your email address.
|
Otherwise, please visit the link below to verify your email address.
|
||||||
|
password_reset:
|
||||||
|
subject: Reset your password on Tabletop Companion
|
||||||
|
reset_password: Reset your password
|
||||||
|
content: |-
|
||||||
|
If you did not request a password reset, please ignore this email.
|
||||||
|
|
||||||
|
Otherwise, please visit the link below to reset your password.
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ Rails.application.routes.draw do
|
||||||
|
|
||||||
resources :users, only: [ :new, :create, :show, :edit, :update ]
|
resources :users, only: [ :new, :create, :show, :edit, :update ]
|
||||||
resources :account_verifications, only: [ :show ]
|
resources :account_verifications, only: [ :show ]
|
||||||
|
resources :password_resets, only: [ :new, :create, :edit, :update ]
|
||||||
resources :sessions, only: [ :new, :create, :destroy ]
|
resources :sessions, only: [ :new, :create, :destroy ]
|
||||||
|
|
||||||
resources :table_invites, only: [ :index, :edit, :update ]
|
resources :table_invites, only: [ :index, :edit, :update ]
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class PasswordResetsControllerTest < ActionDispatch::IntegrationTest
|
||||||
|
test "should get new" do
|
||||||
|
get new_password_reset_path
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should send a password reset email" do
|
||||||
|
user = users(:trevor)
|
||||||
|
assert_emails(+1) do
|
||||||
|
post password_resets_path, params: { username: user.username }
|
||||||
|
assert_redirected_to new_session_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should get edit" do
|
||||||
|
user = users(:trevor)
|
||||||
|
token = user.generate_token_for(:password_reset)
|
||||||
|
get edit_password_reset_path(token: token, id: user.username)
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
test "should update password" do
|
||||||
|
user = users(:trevor)
|
||||||
|
token = user.generate_token_for(:password_reset)
|
||||||
|
put password_reset_path(id: user.username, token: token),
|
||||||
|
params: { password: "password", password_confirmation: "password" }
|
||||||
|
assert_redirected_to new_session_path
|
||||||
|
assert user.reload.authenticate("password")
|
||||||
|
end
|
||||||
|
end
|
7
todo.md
7
todo.md
|
@ -1,5 +1,10 @@
|
||||||
- avatars
|
- avatars
|
||||||
- list invites on user page
|
- delete avatar
|
||||||
|
- default avatars
|
||||||
|
- discrete password page
|
||||||
|
- shared/private notes
|
||||||
- notifications
|
- notifications
|
||||||
- Add characters to users/tables
|
- Add characters to users/tables
|
||||||
- Character sheets/prototypes
|
- Character sheets/prototypes
|
||||||
|
- chat
|
||||||
|
- maps
|
||||||
|
|
Loading…
Reference in New Issue