Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 17 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
version: 2.1

orbs:
browser-tools: circleci/browser-tools@1.1
jq: circleci/jq@2.2.0
slack: circleci/slack@3.4.2
executors:
# Common container definition used by all jobs
ruby_browsers:
docker:
# Specify the Ruby version you desire here
- image: circleci/ruby:2.7.3-node-browsers
- image: cimg/ruby:2.7.3-browsers
environment:
CIRCLE_CI: 'true'
RAILS_ENV: test
Expand Down Expand Up @@ -49,26 +50,26 @@ commands:
steps:
- restore_cache:
keys:
- v1-identity-idp-yarn-{{ checksum "yarn.lock" }}
- v1-identity-idp-yarn-
- v2-identity-idp-yarn-{{ checksum "yarn.lock" }}
- v2-identity-idp-yarn-
- run:
name: Install Yarn
command: yarn install --frozen-lockfile --ignore-engines --cache-folder ~/.cache/yarn
- save_cache:
key: v1-identity-idp-yarn-{{ checksum "yarn.lock" }}
key: v2-identity-idp-yarn-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
yarn-production-install:
steps:
- restore_cache:
keys:
- v1-identity-idp-yarn-production-{{ checksum "yarn.lock" }}
- v1-identity-idp-yarn-production
- v2-identity-idp-yarn-production-{{ checksum "yarn.lock" }}
- v2-identity-idp-yarn-production
- run:
name: Install Yarn
command: yarn install --production --frozen-lockfile --ignore-engines --cache-folder ~/.cache/yarn
- save_cache:
key: v1-identity-idp-yarn-production-{{ checksum "yarn.lock" }}
key: v2-identity-idp-yarn-production-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn

Expand All @@ -77,13 +78,13 @@ commands:
- run: gem install bundler --version $BUNDLER_VERSION
- restore_cache:
keys:
- v2-identity-idp-bundle-{{ checksum "Gemfile.lock" }}
- v3-identity-idp-bundle-{{ checksum "Gemfile.lock" }}
- run:
name: Install dependencies
command: |
bundle check || bundle install --deployment --jobs=4 --retry=3 --without deploy development doc production --path vendor/bundle
- save_cache:
key: v2-identity-idp-bundle-{{ checksum "Gemfile.lock" }}
key: v3-identity-idp-bundle-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
# Custom version of "checkout" that checks out a SHA deployed to sha_url param
Expand Down Expand Up @@ -180,6 +181,7 @@ jobs:
working_directory: ~/identity-idp

steps:
- browser-tools/install-browser-tools
- checkout
- node-install
- yarn-install
Expand All @@ -188,7 +190,7 @@ jobs:
name: Install AWS CLI
command: |
sudo apt-get update
sudo apt-get install python-pip python-dev jq
sudo apt-get install python3-pip python-dev jq
sudo pip install awscli
- run:
name: Install Code Climate Test Reporter
Expand Down Expand Up @@ -246,6 +248,7 @@ jobs:
working_directory: ~/identity-idp
executor: ruby_browsers
steps:
- browser-tools/install-browser-tools
- checkout
- node-install
- yarn-install
Expand Down Expand Up @@ -285,6 +288,7 @@ jobs:
environment:
MONITOR_ENV: DEV
steps:
- browser-tools/install-browser-tools
- jq/install
- checkout-deployed-sha:
sha_url: https://idp.dev.identitysandbox.gov/api/deploy.json
Expand All @@ -303,6 +307,7 @@ jobs:
environment:
MONITOR_ENV: INT
steps:
- browser-tools/install-browser-tools
- jq/install
- checkout-deployed-sha:
sha_url: https://idp.int.identitysandbox.gov/api/deploy.json
Expand All @@ -321,6 +326,7 @@ jobs:
environment:
MONITOR_ENV: STAGING
steps:
- browser-tools/install-browser-tools
- jq/install
- checkout-deployed-sha:
sha_url: https://idp.staging.login.gov/api/deploy.json
Expand All @@ -339,6 +345,7 @@ jobs:
environment:
MONITOR_ENV: PROD
steps:
- browser-tools/install-browser-tools
- checkout
- node-install
- yarn-install
Expand Down
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ gem 'aws-sdk-ses', '~> 1.6'
gem 'base32-crockford'
gem 'bootsnap', '~> 1.9.0', require: false
gem 'blueprinter', '~> 0.25.3'
gem 'browser'
gem 'connection_pool'
gem 'device_detector'
gem 'devise', '~> 4.8'
gem 'dotiw', '>= 4.0.1'
gem 'faraday'
Expand All @@ -38,6 +38,7 @@ gem 'http_accept_language'
gem 'jwt'
gem 'local_time'
gem 'lograge', '>= 0.11.2'
gem 'lru_redux'
gem 'maxminddb'
gem 'net-sftp'
gem 'newrelic_rpm', '~> 7.0'
Expand Down Expand Up @@ -67,7 +68,6 @@ gem 'stringex', require: false
gem 'strong_migrations', '>= 0.4.2'
gem 'subprocess', require: false
gem 'uglifier', '~> 4.2'
gem 'user_agent_parser'
gem 'valid_email', '>= 0.1.3'
gem 'view_component', '~> 2.40.0', require: 'view_component/engine'
gem 'webauthn', '~> 2.1'
Expand Down
9 changes: 5 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ GEM
bootsnap (1.9.1)
msgpack (~> 1.0)
brakeman (5.1.1)
browser (5.3.1)
builder (3.2.4)
bullet (6.1.5)
activesupport (>= 3.0.0)
Expand Down Expand Up @@ -357,6 +358,7 @@ GEM
loofah (2.12.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
lru_redux (1.1.0)
lumberjack (1.2.8)
macaddr (1.7.2)
systemu (~> 2.6.5)
Expand Down Expand Up @@ -421,7 +423,7 @@ GEM
pry (>= 0.10.4)
psych (3.2.1)
public_suffix (4.0.6)
puma (5.3.2)
puma (5.5.1)
nio4r (~> 2.0)
raabro (1.4.0)
racc (1.5.2)
Expand Down Expand Up @@ -630,7 +632,6 @@ GEM
execjs (>= 0.3.0, < 3)
unicode-display_width (2.0.0)
uniform_notifier (1.14.2)
user_agent_parser (2.7.0)
uuid (2.3.9)
macaddr (~> 1.0)
valid_email (0.1.3)
Expand Down Expand Up @@ -703,13 +704,13 @@ DEPENDENCIES
blueprinter (~> 0.25.3)
bootsnap (~> 1.9.0)
brakeman
browser
bullet (>= 6.0.2)
bundler-audit
capybara-screenshot (>= 1.0.23)
capybara-selenium (>= 0.0.6)
connection_pool
derailed_benchmarks (~> 1.8)
device_detector
devise (~> 4.8)
dotiw (>= 4.0.1)
email_spec
Expand All @@ -734,6 +735,7 @@ DEPENDENCIES
knapsack
local_time
lograge (>= 0.11.2)
lru_redux
maxminddb
net-sftp
newrelic_rpm (~> 7.0)
Expand Down Expand Up @@ -789,7 +791,6 @@ DEPENDENCIES
strong_migrations (>= 0.4.2)
subprocess
uglifier (~> 4.2)
user_agent_parser
valid_email (>= 0.1.3)
view_component (~> 2.40.0)
webauthn (~> 2.1)
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ lint:
bundle exec scss-lint

lint_erb:
bundle exec erblint app/views
bundle exec erblint app/views app/components

lint_yaml: normalize_yaml
(! git diff --name-only | grep "^config/.*\.yml$$") || (echo "Error: Run 'make normalize_yaml' to normalize YAML"; exit 1)
Expand Down
1 change: 1 addition & 0 deletions app/assets/stylesheets/components/_file-input.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

.usa-form-group--success .usa-file-input .usa-file-input__target {
border-color: color('success');
border-style: solid;

&:hover {
border-color: color('success-dark');
Expand Down
5 changes: 5 additions & 0 deletions app/assets/stylesheets/components/_form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,12 @@ input::-webkit-inner-spin-button {

.usa-success-message {
@include u-padding-y(.5);
background-image: url(image-path('alert/success.svg'));
background-position: 0 center;
background-repeat: no-repeat;
background-size: 1rem;
color: color('success');
display: block;
font-weight: font-weight('bold');
padding-left: 1.5rem;
}
3 changes: 1 addition & 2 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,6 @@ def add_sp_cost(token)
end

def mobile?
client = DeviceDetector.new(request.user_agent)
client.device_type != 'desktop'
BrowserCache.parse(request.user_agent).mobile?
end
end
10 changes: 7 additions & 3 deletions app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,13 @@ def show

def device_and_events
user_id = current_user.id
@events = DeviceTracking::ListDeviceEvents.call(user_id, device_id, 0, EVENTS_PAGE_SIZE).
map(&:decorate)
@device = Device.where(user_id: user_id).find(device_id)
device = Device.where(user_id: user_id).find(device_id)
return if !device

@events = Event.where(user_id: user_id, device_id: device.id).order(created_at: :desc).
limit(EVENTS_PAGE_SIZE).
map(&:decorate)
@device = device.decorate
end

def device_id
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/idv/confirmations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def generate_personal_key
end

def pending_profile?
current_user.decorate.pending_profile?
current_user.pending_profile?
end
end
end
2 changes: 1 addition & 1 deletion app/controllers/idv/gpo_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def confirmation_maker_perform
confirmation_maker = GpoConfirmationMaker.new(
pii: Pii::Cacher.new(current_user, user_session).fetch,
issuer: sp_session[:issuer],
profile: current_user.decorate.pending_profile,
profile: current_user.pending_profile,
)
confirmation_maker.perform
confirmation_maker
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/users/forget_all_browsers_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def show
end

def destroy
DeviceTracking::ForgetAllBrowsers.new(current_user).call
ForgetAllBrowsers.new(current_user).call

analytics.track_event(Analytics::FORGET_ALL_BROWSERS_SUBMITTED)

Expand Down
11 changes: 10 additions & 1 deletion app/decorators/device_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
DeviceDecorator = Struct.new(:device) do
delegate :nice_name, :last_used_at, :id, to: :device
delegate :last_used_at, :id, to: :device

def last_sign_in_location_and_ip
I18n.t('account.index.sign_in_location_and_ip', location: last_location, ip: device.last_ip)
Expand All @@ -12,4 +12,13 @@ def last_location
def happened_at
device.last_used_at.utc
end

def nice_name
browser = BrowserCache.parse(device.user_agent)
I18n.t(
'account.index.device',
browser: "#{browser.name} #{browser.version}",
os: "#{browser.platform.name} #{browser.platform.version.split('.').first}",
)
end
end
13 changes: 4 additions & 9 deletions app/decorators/user_decorator.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
class UserDecorator
include ActionView::Helpers::DateHelper

delegate :pending_profile, to: :user

attr_reader :user

MAX_RECENT_EVENTS = 5
Expand Down Expand Up @@ -81,14 +83,6 @@ def pending_profile_requires_verification?
true
end

def pending_profile?
pending_profile.present?
end

def pending_profile
user.profiles.verification_pending.order(created_at: :desc).first
end

def identity_not_verified?
!identity_verified?
end
Expand Down Expand Up @@ -143,7 +137,8 @@ def identity_events
end

def recent_devices
DeviceTracking::ListDevices.call(user.id, 0, MAX_RECENT_DEVICES).map(&:decorate)
@recent_devices ||= user.devices.order(last_used_at: :desc).limit(MAX_RECENT_DEVICES).
map(&:decorate)
end

def devices?
Expand Down
12 changes: 9 additions & 3 deletions app/forms/openid_connect_token_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class OpenidConnectTokenForm
in: [CLIENT_ASSERTION_TYPE],
if: :private_key_jwt?

validate :validate_expired
validate :validate_code
validate :validate_pkce_or_private_key_jwt
validate :validate_code_verifier, if: :pkce?
Expand All @@ -31,6 +32,7 @@ def initialize(params)
ATTRS.each do |key|
instance_variable_set(:"@#{key}", params[key])
end
@session_expiration = IdentityConfig.store.session_timeout_in_minutes.minutes.ago
@identity = find_identity_with_code
end

Expand Down Expand Up @@ -61,14 +63,12 @@ def url_options

private

attr_reader :identity
attr_reader :identity, :session_expiration

def find_identity_with_code
return if code.blank? || code.include?("\x00")

session_expiration = IdentityConfig.store.session_timeout_in_minutes.minutes.ago
@identity = ServiceProviderIdentity.where(session_uuid: code).
where('updated_at >= ?', session_expiration).
order(updated_at: :desc).first
end

Expand All @@ -94,6 +94,12 @@ def validate_pkce_or_private_key_jwt
errors.add :code, t('openid_connect.token.errors.invalid_authentication')
end

def validate_expired
if identity&.updated_at && identity.updated_at < session_expiration
errors.add :code, t('openid_connect.token.errors.expired_code')
end
end

def validate_code
errors.add :code, t('openid_connect.token.errors.invalid_code') if identity.blank? ||
!identity.user
Expand Down
Loading