Skip to content

Commit 0d2431e

Browse files
DrewProebstelDrewProebstelCfaarinchoi03
authored
Fyst 2144 verification code (#68)
* add i18n and styling for landing page * rubocop * pr comments * remove unused flash messages styles * git ignore * restore DS store * rubocop * client menu component * wip dropdown menu' * rubocop * use unless prod for environemntal warning * wip * wip * wip * add specs * rubocop * clean up some unneeded changes * wip * Re-render show to show the error message but with error_status * Pin necessary modules and include "application" since thats the entrypoint - without this importmap will load without executing application.js * Fix rubocop * Use the already available activestorage * fix changed variable in honeycrisp * try precomplie in app.json * try fixing some css * remove asset precompile * add email address page * rubocop * i18n * wip * bring up to main * fix year select controller spec * little more clean up * add the whole form into one div * put the inside of the form in one div * git rid of form actions div * turbo false in the form * generic support for blank error message * update test * implement knockout page * wip * update path in is intake locked * wip * wip * wip * pr updates * pr changes * wip * rubocop * return contact preference to schema * add is locked tests * wip * add sms functionality * merge main * contact preference controller redirects * touch up * new migration * update contact preference case * contact preference form no longer saves anything * restore some development artificats * wip * contact preference is not a form * remove unneeded files * remove devise migration * annotate * make enum * rubocop * wip * wip * wip * fix tests * rubocop * fix some html * wip * add turbo false to phone number * restore accidental html changes * default turbo to false * turbo false for v code * clean up * merge main * pr changes * remove devise test * restore gemfile.lock * pr_updates --------- Co-authored-by: Drew Proebstel <dproebstel@codeforamerica.org> Co-authored-by: Arin Choi <achoi@codeforamerica.org>
1 parent 3bae3af commit 0d2431e

24 files changed

Lines changed: 639 additions & 15 deletions

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ gem "rails-i18n"
99
gem "valid_email2", "~> 4.0.6"
1010
gem "phony"
1111
gem "auto_strip_attributes"
12+
gem "devise"
1213

1314
# Use the Puma web server [https://github.com/puma/puma]
1415
gem "puma", ">= 5.0"

Gemfile.lock

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ GEM
113113
aws-sigv4 (1.12.1)
114114
aws-eventstream (~> 1, >= 1.0.2)
115115
base64 (0.3.0)
116+
bcrypt (3.1.20)
116117
benchmark (0.4.1)
117118
bigdecimal (3.2.2)
118119
bindex (0.8.1)
@@ -144,6 +145,12 @@ GEM
144145
debug (1.11.0)
145146
irb (~> 1.10)
146147
reline (>= 0.3.8)
148+
devise (4.9.4)
149+
bcrypt (~> 3.0)
150+
orm_adapter (~> 0.1)
151+
railties (>= 4.1.0)
152+
responders
153+
warden (~> 1.2.3)
147154
diff-lcs (1.6.2)
148155
dotenv (3.1.8)
149156
drb (2.2.3)
@@ -255,6 +262,7 @@ GEM
255262
racc (~> 1.4)
256263
nokogiri (1.18.8-x86_64-linux-musl)
257264
racc (~> 1.4)
265+
orm_adapter (0.5.0)
258266
parallel (1.27.0)
259267
parser (3.3.8.0)
260268
ast (~> 2.4.1)
@@ -338,6 +346,9 @@ GEM
338346
regexp_parser (2.10.0)
339347
reline (0.6.1)
340348
io-console (~> 0.5)
349+
responders (3.1.1)
350+
actionpack (>= 5.2)
351+
railties (>= 5.2)
341352
rexml (3.4.1)
342353
rspec-core (3.13.5)
343354
rspec-support (~> 3.13.0)
@@ -453,6 +464,8 @@ GEM
453464
valid_email2 (4.0.6)
454465
activemodel (>= 3.2)
455466
mail (~> 2.5)
467+
warden (1.2.9)
468+
rack (>= 2.0.9)
456469
web-console (4.2.1)
457470
actionview (>= 6.0.0)
458471
activemodel (>= 6.0.0)
@@ -491,6 +504,7 @@ DEPENDENCIES
491504
cfa-styleguide (= 0.16.0)!
492505
dartsass-rails (~> 0.5.1)
493506
debug
507+
devise
494508
dotenv
495509
factory_bot_rails
496510
http_accept_language

app/controllers/base_controller.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ def current_archived_intake
1717
existing || StateFileArchivedIntake.create(email_address: email, contact_preference: "email")
1818
end
1919
end
20+
def is_intake_locked
21+
if current_archived_intake.nil? || current_archived_intake.access_locked? || current_archived_intake.permanently_locked_at.present?
22+
redirect_to knock_out_path
23+
end
24+
end
2025
end

app/controllers/email_address_controller.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ def update
1313
session[:email_address] = @form.email_address
1414
session[:phone_number] = nil
1515
current_archived_intake
16-
# TODO Add some kind of logging here
17-
# https://codeforamerica.atlassian.net/browse/FYST-2088
16+
# TODO Add some kind of logging here https://codeforamerica.atlassian.net/browse/FYST-2088
1817

19-
redirect_to root_path
18+
redirect_to edit_verification_code_path
2019
else
2120
render :edit
2221
end
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
class PagesController < ApplicationController
1+
class PagesController < BaseController
22
def home
33
end
4+
5+
def knock_out
6+
@intake = current_archived_intake
7+
end
48
end

app/controllers/phone_number_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def update
1515
current_archived_intake
1616
# TODO Add some kind of logging here. https://codeforamerica.atlassian.net/browse/FYST-2088
1717

18-
redirect_to root_path
18+
redirect_to edit_verification_code_path
1919
else
2020
render :edit
2121
end
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
class VerificationCodeController < BaseController
2+
before_action :is_intake_locked
3+
before_action :setup_contact
4+
5+
def setup_contact
6+
@contact_type = current_archived_intake.contact_preference
7+
@contact_info = current_archived_intake.contact
8+
end
9+
10+
def edit
11+
@form = VerificationCodeForm.new(contact_info: @contact_info)
12+
case current_archived_intake.contact_preference
13+
when "text"
14+
# @phone_number = current_archived_intake.phone_number
15+
# ArchivedIntakeTextVerificationCodeJob.perform_later(
16+
# phone_number: @phone_number,
17+
# locale: I18n.locale
18+
# )
19+
when "email"
20+
# @email_address = current_archived_intake.email_address
21+
# ArchivedIntakeEmailVerificationCodeJob.perform_later(
22+
# email_address: @email_address,
23+
# locale: I18n.locale
24+
# )
25+
else
26+
redirect_to root_path
27+
end
28+
end
29+
30+
def update
31+
@form = VerificationCodeForm.new(verification_code_form_params, contact_info: current_archived_intake.contact)
32+
33+
if @form.valid?
34+
case current_archived_intake.contact_preference
35+
when "text"
36+
# TODO: Some kind of logging here
37+
when "email"
38+
# TODO: Some kind of logging here
39+
end
40+
current_archived_intake.reset_failed_attempts!
41+
session[:code_verified] = true
42+
redirect_to root_path
43+
else
44+
case current_archived_intake.contact_preference
45+
when "text"
46+
# TODO: Some kind of logging here
47+
when "email"
48+
# TODO: Some kind of logging here
49+
end
50+
current_archived_intake.increment_failed_attempts
51+
if current_archived_intake.access_locked?
52+
# TODO: Some kind of logging here
53+
redirect_to knock_out_path
54+
return
55+
end
56+
render :edit
57+
end
58+
end
59+
60+
private
61+
62+
def verification_code_form_params
63+
params.require(:verification_code_form).permit(:verification_code)
64+
end
65+
end
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class VerificationCodeForm < Form
2+
attr_accessor :verification_code, :contact_info
3+
4+
validates :verification_code, presence: true
5+
def initialize(attributes = {}, contact_info: nil)
6+
super(attributes)
7+
@contact_info = contact_info
8+
end
9+
10+
def valid?
11+
return true if Rails.configuration.allow_magic_verification_code && verification_code == "000000"
12+
13+
# hashed_verification_code = VerificationCodeService.hash_verification_code_with_contact_info(@email_address, verification_code)
14+
#
15+
# valid_code = EmailAccessToken.lookup(hashed_verification_code).exists?
16+
17+
valid_code = nil
18+
19+
errors.add(:verification_code, I18n.t("errors.attributes.verification_code.invalid")) unless valid_code
20+
21+
valid_code.present?
22+
end
23+
end

app/models/state_file_archived_intake.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
# id :bigint not null, primary key
66
# contact_preference :integer default("unfilled"), not null
77
# email_address :string
8+
# failed_attempts :integer default(0), not null
89
# fake_address_1 :string
910
# fake_address_2 :string
1011
# hashed_ssn :string
12+
# locked_at :datetime
1113
# mailing_apartment :string
1214
# mailing_city :string
1315
# mailing_state :string
1416
# mailing_street :string
1517
# mailing_zip :string
18+
# permanently_locked_at :datetime
1619
# phone_number :string
1720
# state_code :string
1821
# tax_year :integer
@@ -23,11 +26,25 @@
2326
class StateFileArchivedIntake < ApplicationRecord
2427
has_one_attached :submission_pdf
2528
has_many :state_file_archived_intake_access_logs, class_name: "StateFileArchivedIntakeAccessLog"
29+
devise :lockable, unlock_in: 60.minutes, unlock_strategy: :time
2630

2731
enum :contact_preference, { unfilled: 0, email: 1, text: 2 }, prefix: :contact_preference
2832

2933
def full_address
3034
address_parts = [ mailing_street, mailing_apartment, mailing_city, mailing_state, mailing_zip ]
3135
address_parts.compact_blank.join(", ")
3236
end
37+
38+
def self.maximum_attempts
39+
2
40+
end
41+
42+
def increment_failed_attempts
43+
super
44+
lock_access! if attempts_exceeded? && !access_locked?
45+
end
46+
47+
def contact
48+
contact_preference == "text" ? phone_number : email_address
49+
end
3350
end

app/views/pages/knock_out.html.erb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<% title = t("views.pages.knock_out.title") %>
2+
<% content_for :page_title, title %>
3+
4+
<section class="slab question-layout <%= controller_name.gsub("_", "-") %>-outer">
5+
<div class="grid">
6+
<h1 class="h2"><%= title %></h1>
7+
<p><%= t("views.pages.knock_out.locked_due_to") %></p>
8+
<% if @intake.present? && @intake&.permanently_locked_at.nil? %>
9+
<p><%= t("views.pages.knock_out.one_hour")%></p>
10+
<% end %>
11+
<p><%= t("views.pages.knock_out.also_visit_html", year: session[:year_selected] || "")%></p>
12+
<% if @intake.present? %>
13+
<div class="bulleted">
14+
<ul>
15+
<li><a href="https://azdor.gov/forms/other-forms/request-copies-tax-documents"><%= t("views.pages.knock_out.az_dor") %></a></li>
16+
<% if session[:year_selected] == "2023" %>
17+
<li><a href="https://www.tax.ny.gov/help/contact/get-copy-of-return.htm"><%= t("views.pages.knock_out.ny_dor") %></a></li>
18+
<% end %>
19+
<% if session[:year_selected] == "2024" %>
20+
<li><a href="https://www.marylandcomptroller.gov/content/dam/mdcomp/tax/forms/2023/129.pdf"><%= t("views.pages.knock_out.md_form") %></a></li>
21+
<li><a href="https://www.ncdor.gov/taxes-forms/individual-income-tax/customer-education-individuals/how-get-copy-your-north-carolina-return"><%= t("views.pages.knock_out.nc_dor") %></a></li>
22+
<li><a href="https://www.nj.gov/treasury/taxation/pdf/other_forms/misc/dcc.pdf"><%= t("views.pages.knock_out.nj_dot") %></a></li>
23+
<% end %>
24+
</ul>
25+
</div>
26+
<% end %>
27+
<%= link_to root_path, class: "button button--primary button--wide text--centered spacing-above-25", role: "button" do %>
28+
<%=t("views.pages.knock_out.return_to_home") %>
29+
<% end %>
30+
</div>
31+
</section>

0 commit comments

Comments
 (0)