Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
49492f4
Update saml_idp revision
achapm Apr 24, 2020
70f18a2
Lg 2939 update us gov banner (#3751)
slj May 6, 2020
9323c2a
[Snyk] Fix for 1 vulnerabilities (#3746)
snyk-bot May 6, 2020
5621e97
Add spec to make sure that re-proofing costs behave as expected (#3754)
zachmargolis May 7, 2020
496cf06
Fix spec to reflect the fact that we've removed SingleLogoutService
zachmargolis May 7, 2020
0548d42
Merge pull request #3734 from 18F/update_saml_idp_revision
achapm May 7, 2020
c97418e
Revert "[Snyk] Fix for 1 vulnerabilities (#3746)" (#3755)
achapm May 7, 2020
bc47ec8
fix bundler config to work (#3759)
timothy-spencer May 11, 2020
45d5d8f
Add deal and IAA information to service_providers table (LG-2865) (#3…
zachmargolis May 11, 2020
d05cd9d
Various accessibility Fixes (#3761)
zachmargolis May 12, 2020
ea40dfe
Make sure hidden webauthn element is skipped by screen readers (LG-29…
zachmargolis May 12, 2020
0a3cb00
Update GSA logo alt text for screen readers (LG-2983) (#3763)
zachmargolis May 13, 2020
3f737e7
LG-2959 Add a missing `return` statement when a Acuant SDK file is no…
jmhooper May 13, 2020
45b2ea6
Remove load testing scripts (#3764)
zachmargolis May 13, 2020
780bf75
Fix typo in method name (#3766)
zachmargolis May 13, 2020
ee75dd0
Update order of elements in footer to match visual order (LG-2989) (#…
zachmargolis May 13, 2020
7bd3c81
fix: package.json to reduce vulnerabilities (#3757)
snyk-bot May 13, 2020
a9c250a
Remove the Acuant SDK from the desktop flow (#3767)
jmhooper May 14, 2020
6bdf1dd
LG-2375 Don't truncate the return to SP link (#3770)
jmhooper May 14, 2020
562cd88
Fix positioning of remember-this-browser checkbox (#3769)
slj May 14, 2020
4a93942
Update yarn.lock (#3771)
zachmargolis May 15, 2020
e63a17c
LG-2936 Add liveness check to main doc auth flow (#3758)
stevegsa May 15, 2020
32432dd
Hide/show email error messages via HTML5 hidden attribute (LG-2996) (…
zachmargolis May 15, 2020
4f9191b
LG-260 Separate otp request tracking and throttling for verified phon…
stevegsa May 15, 2020
cd5b0db
Bring back i18n keys removed in #3767 (#3776)
zachmargolis May 18, 2020
309042c
Account Delete: Require Password (LG-2964) (#3775)
zachmargolis May 19, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ GIT

GIT
remote: https://github.com/18F/saml_idp.git
revision: 95366bbb24088660eadc54ba49f56399cf8b17b4
revision: 8d0bedcd71b025617c0ab094bbc6a7982d9df1cd
branch: master
specs:
saml_idp (0.9.0.pre.18f)
Expand Down
34 changes: 0 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -281,40 +281,6 @@ $ RAILS_ASSET_HOST=localhost:3000 FEDERALIST_PATH=/site/user/repository rake spe

This will output your site to `public/site/user/repository` for quick publishing to [Federalist](https://federalist-docs.18f.gov/pages/using-federalist/). To test compatibility, run `simplehttpserver` from the app's `public` folder and visit `http://localhost:8000/<FEDERALIST PATH>/user_flows` in your browser.

### Load testing

We provide some [Locust.io] Python scripts you can run to test how the
app responds to load. You'll need to have Python and `pyenv-virtualenvwrapper`
installed on your machine. If you're on a Mac, the easiest way to set up Python
and `pyenv-virtualenvwrapper` is to run the [laptop script].

Next, you'll need to set the following values in your local `application.yml`:

```
disable_email_sending: 'true'
enable_load_testing_mode: 'true'
telephony_adapter: 'test'
```

Then, run the app with `make run`, and in a new Terminal tab or window, run:
```
make load_test type=create_account
```
This will simulate 3 concurrent users going through the entire account creation
flow and then signing out. To change the number of concurrent users, number of
requests, and the rate at which users are created, modify the `-c`,
`-n`, and `-r` Locust parameters in `bin/load_test`. Run `locust --help` for
more details.

By default, the test will target the host running at `http://localhost:3000`.
To change the target host, set the `TARGET_HOST` environment variable.
For example:

```
TARGET_HOST=https://awesome.loadtesting.com make load_test type=create_account
```

[Locust.io]: http://locust.io/
[laptop script]: https://github.com/18F/laptop

### Proofing vendors
Expand Down
1 change: 1 addition & 0 deletions app/assets/images/icon-dot-gov.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/assets/images/icon-https.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/assets/stylesheets/components/_banner.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.site .site-wrap .usa-banner {
background-color: #fff;
box-shadow: inset 0 -1px 0 0 #ccc;
}
4 changes: 4 additions & 0 deletions app/assets/stylesheets/components/_util.scss
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,7 @@
.flex-center {
justify-content: center;
}

.flex-no-shrink {
flex-shrink: 0;
}
1 change: 1 addition & 0 deletions app/assets/stylesheets/components/all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
@import 'abbr';
@import 'alert';
@import 'background';
@import 'banner';
@import 'border';
@import 'btn';
@import 'card';
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/acuant_sdk_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class AcuantSdkController < ApplicationController

def show
# Only render files on an allowlist to prevent path traversal issues
render plain: 'Not found', status: :not_found unless requested_asset_permitted?
return render(plain: 'Not found', status: :not_found) unless requested_asset_permitted?

SecureHeaders.append_content_security_policy_directives(
request,
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/idv/doc_auth_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def flow_session
end

def add_unsafe_eval_to_capture_steps
capture_steps = %w[front_image back_image mobile_front_image mobile_back_image]
capture_steps = %w[front_image back_image mobile_front_image mobile_back_image selfie]
return unless capture_steps.include?(params[:step])

# required to run wasm until wasm-eval is available
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/idv/scan_id_acuant_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def field_image
end

def liveness
is_live, is_face_match = ::Acuant::Liveness.
is_live, is_face_match = ::Acuant::LivenessPassThrough.
new(scan_id_session[:instance_id]).call(request.body.read)
scan_id_session[:liveness_pass] = is_live
scan_id_session[:facematch_pass] = is_face_match
Expand Down
24 changes: 22 additions & 2 deletions app/controllers/users/delete_controller.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
module Users
class DeleteController < ReauthnRequiredController
class DeleteController < ApplicationController
before_action :confirm_two_factor_authenticated
before_action :confirm_current_password, only: [:delete]

def show; end
def show
analytics.track_event(Analytics::ACCOUNT_DELETE_VISITED)
end

def delete
send_push_notifications
current_user.destroy!
sign_out
flash[:success] = t('devise.registrations.destroyed')
analytics.track_event(Analytics::ACCOUNT_DELETE_SUBMITTED, success: true)
redirect_to root_url
end

private

def confirm_current_password
return if valid_password?

flash[:error] = t('idv.errors.incorrect_password')
analytics.track_event(Analytics::ACCOUNT_DELETE_SUBMITTED, success: false)
render :show
end

def valid_password?
current_user.valid_password?(password)
end

def password
params.fetch(:user, {})[:password].presence
end

def send_push_notifications
return if Figaro.env.push_notifications_enabled != 'true'
PushNotification::AccountDelete.new.call(current_user.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@ def phone_to_deliver_to
end

def otp_rate_limiter
@_otp_rate_limited ||= OtpRateLimiter.new(phone: phone_to_deliver_to, user: current_user)
@_otp_rate_limited ||= OtpRateLimiter.new(phone: phone_to_deliver_to,
user: current_user,
phone_confirmed: authentication_context?)
end

def redirect_on_nothing_enabled
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/app/acuant/document_capture_dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const showFallbackForm = () => {
fallbackImageForm().classList.remove('hidden');
};

const showAcuantSdkContainer = (container) => {
export const showAcuantSdkContainer = (container) => {
if (documentCaptureFallbackModeEnabled()) return;

hideAcuantSdkContainers();
Expand Down
50 changes: 50 additions & 0 deletions app/javascript/app/acuant/selfie_capture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { acuantSdkPreviewImage, imageDataUrlInput, imageFileInput, showAcuantSdkContainer }
from './document_capture_dom';

const {
fetchSdkInitializationCredentials,
fetchSdkInitializationEndpoint,
acuantSdkInitializationStarted,
acuantSdkInitializeSuccess,
acuantSdkInitializeFailed,
addClickEventListenerToAcuantCaptureButton,
} = require('./document_capture_dom');

export const onCaptured = (image) => {
acuantSdkPreviewImage().src = `data:image/jpeg;base64,${image}`;
imageDataUrlInput().value = `data:image/jpeg;base64,${image}`;
imageFileInput().required = false;
showAcuantSdkContainer('continue-form');
};

export const imageCaptureButtonClicked = (event) => {
event.preventDefault();
window.AcuantPassiveLiveness.startSelfieCapture(onCaptured.bind(this));
};

export const initializeAcuantSdk = (credentials = null, endpoint = null) => {
credentials = credentials || fetchSdkInitializationCredentials();
endpoint = endpoint || fetchSdkInitializationEndpoint();
window.AcuantJavascriptWebSdk.initialize(
credentials,
endpoint,
{
onSuccess: () => {
addClickEventListenerToAcuantCaptureButton(imageCaptureButtonClicked);
acuantSdkInitializeSuccess();
},
onFail: acuantSdkInitializeFailed,
},
);
};

export const loadAndInitializeAcuantSdk = () => {
acuantSdkInitializationStarted();
window.onAcuantSdkLoaded = initializeAcuantSdk;

const sdk = document.createElement('script');
sdk.src = 'AcuantJavascriptWebSdk.min.js';
sdk.async = true;

document.body.appendChild(sdk);
};
3 changes: 3 additions & 0 deletions app/javascript/app/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import autoLogout from './auto-logout';
import countdownTimer from './countdown-timer';
import msFormatter from './ms-formatter';
import enableBannerToggling from './toggle-banner';

window.LoginGov = (window.LoginGov || {});
const LoginGov = window.LoginGov;
Expand All @@ -11,3 +12,5 @@ documentElement.className = documentElement.className.replace(/no-js/, '');
LoginGov.autoLogout = autoLogout;
LoginGov.countdownTimer = countdownTimer;
LoginGov.msFormatter = msFormatter;

enableBannerToggling();
18 changes: 18 additions & 0 deletions app/javascript/app/utils/toggle-banner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export default function toggleBanner() {
const enableBannerToggling = () => {
const bannerButton = document.querySelector('.usa-banner__button');

const toggleBannerSection = (evt) => {
evt.currentTarget.setAttribute(
'aria-expanded',
evt.currentTarget.getAttribute('aria-expanded') === 'true' ? 'false' : 'true',
);
const howYouKnowSection = document.querySelector('#gov-banner');
if (howYouKnowSection) howYouKnowSection.classList.toggle('hide');
};

if (bannerButton) bannerButton.addEventListener('click', toggleBannerSection);
};

window.onload = enableBannerToggling;
}
7 changes: 7 additions & 0 deletions app/javascript/packs/acuant_selfie_capture.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { loadAndInitializeAcuantSdk } from '../app/acuant/selfie_capture';
import { setDocumentCaptureFallbackTimeout } from '../app/acuant/document_capture_fallback';

document.addEventListener('DOMContentLoaded', () => {
loadAndInitializeAcuantSdk();
setDocumentCaptureFallbackTimeout();
});
18 changes: 14 additions & 4 deletions app/javascript/packs/email-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@ function emailValidation() {
const email = document.querySelector('input[type="email"]');
let blurTimer;

function hideElem(elem) {
elem.classList.add('hide');
elem.hidden = true;
}

function showElem(elem) {
elem.classList.remove('hide');
elem.hidden = false;
}

// remove focus from the email input after error is displayed
function blurEmailInput(input) {
blurTimer = setTimeout(function () {
Expand All @@ -14,15 +24,15 @@ function emailValidation() {

function resetEmailInvalid(input) {
input.classList.remove('usa-input--error');
alert.classList.add('hide');
alertInline.classList.add('hide');
hideElem(alert);
hideElem(alertInline);
clearTimeout(blurTimer);
}

function displayEmailInvalid(input) {
input.classList.add('usa-input--error');
alert.classList.remove('hide');
alertInline.classList.remove('hide');
showElem(alert);
showElem(alertInline);
blurEmailInput(input);
}

Expand Down
1 change: 1 addition & 0 deletions app/javascript/packs/webauthn-unhide-signup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ function unhideWebauthn() {
if (WebAuthn.isWebAuthnEnabled()) {
const elem = document.querySelector('label[for=two_factor_options_form_selection_webauthn]');
if (elem) {
elem.hidden = false;
elem.classList.remove('hide');
}
}
Expand Down
9 changes: 4 additions & 5 deletions app/models/otp_requests_tracker.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
class OtpRequestsTracker < ApplicationRecord
def self.find_or_create_with_phone(phone)
tries ||= 1
phone ||= phone.strip
phone_fingerprint ||= Pii::Fingerprinter.fingerprint(phone)
def self.find_or_create_with_phone_and_confirmed(phone, phone_confirmed)
tries = 1
phone_fingerprint = Pii::Fingerprinter.fingerprint(phone.strip)

where(phone_fingerprint: phone_fingerprint).
where(phone_fingerprint: phone_fingerprint, phone_confirmed: phone_confirmed).
first_or_create(otp_send_count: 0, otp_last_sent_at: Time.zone.now)
rescue ActiveRecord::RecordNotUnique
retry unless (tries -= 1).zero?
Expand Down
Loading