{"action":"created","comment":{"url":"https://api.github.com/repos/18F/identity-idp/pulls/comments/227047889","pull_request_review_id":167001325,"id":227047889,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyNzA0Nzg4OQ==","diff_hunk":"@@ -11,6 +11,7 @@\n         via: %i[get post delete],\n         as: :destroy_user_session\n   match '/api/saml/auth' => 'saml_idp#auth', via: %i[get post]\n+  post '/analytics' => 'analytics#create'","path":"config/routes.rb","position":4,"original_position":4,"commit_id":"71403afd46997f2a22602eec64ad8b99b3310b65","original_commit_id":"71403afd46997f2a22602eec64ad8b99b3310b65","user":{"login":"stevegsa","id":34244063,"node_id":"MDQ6VXNlcjM0MjQ0MDYz","avatar_url":"https://avatars0.githubusercontent.com/u/34244063?v=4","gravatar_id":"","url":"https://api.github.com/users/stevegsa","html_url":"https://github.com/stevegsa","followers_url":"https://api.github.com/users/stevegsa/followers","following_url":"https://api.github.com/users/stevegsa/following{/other_user}","gists_url":"https://api.github.com/users/stevegsa/gists{/gist_id}","starred_url":"https://api.github.com/users/stevegsa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevegsa/subscriptions","organizations_url":"https://api.github.com/users/stevegsa/orgs","repos_url":"https://api.github.com/users/stevegsa/repos","events_url":"https://api.github.com/users/stevegsa/events{/privacy}","received_events_url":"https://api.github.com/users/stevegsa/received_events","type":"User","site_admin":false},"body":"It gets difficult when all the javascript analytics are all flowing through this one analytics endpoint.  The feature flag should essentially be disabling the javascript for platform authenticators but not necessarily the endpoint.","created_at":"2018-10-22T16:39:05Z","updated_at":"2018-10-22T16:39:05Z","html_url":"https://github.com/18F/identity-idp/pull/2609#discussion_r227047889","pull_request_url":"https://api.github.com/repos/18F/identity-idp/pulls/2609","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/18F/identity-idp/pulls/comments/227047889"},"html":{"href":"https://github.com/18F/identity-idp/pull/2609#discussion_r227047889"},"pull_request":{"href":"https://api.github.com/repos/18F/identity-idp/pulls/2609"}},"in_reply_to_id":227004770},"pull_request":{"url":"https://api.github.com/repos/18F/identity-idp/pulls/2609","id":223471545,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIzNDcxNTQ1","html_url":"https://github.com/18F/identity-idp/pull/2609","diff_url":"https://github.com/18F/identity-idp/pull/2609.diff","patch_url":"https://github.com/18F/identity-idp/pull/2609.patch","issue_url":"https://api.github.com/repos/18F/identity-idp/issues/2609","number":2609,"state":"open","locked":false,"title":"LG-745 Store analytics on whether users have platform authenticators","user":{"login":"stevegsa","id":34244063,"node_id":"MDQ6VXNlcjM0MjQ0MDYz","avatar_url":"https://avatars0.githubusercontent.com/u/34244063?v=4","gravatar_id":"","url":"https://api.github.com/users/stevegsa","html_url":"https://github.com/stevegsa","followers_url":"https://api.github.com/users/stevegsa/followers","following_url":"https://api.github.com/users/stevegsa/following{/other_user}","gists_url":"https://api.github.com/users/stevegsa/gists{/gist_id}","starred_url":"https://api.github.com/users/stevegsa/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevegsa/subscriptions","organizations_url":"https://api.github.com/users/stevegsa/orgs","repos_url":"https://api.github.com/users/stevegsa/repos","events_url":"https://api.github.com/users/stevegsa/events{/privacy}","received_events_url":"https://api.github.com/users/stevegsa/received_events","type":"User","site_admin":false},"body":"**Why**: So that we can anticipate and plan for registering and using these devices in future.\r\n\r\n**How**: Use a simple API call to isUserVerifyingPlatformAuthenticatorAvailable which is part of the WebAuthn spec.  For every request add a call to this method. If the promise returns, create an xhr request to report the findings to the analytics.  Only log analytics once per session and only for authenticated users.  Add a feature flag to enable/disable this feature.  The feature flag will conditionally write a data attribute data-platform-authenticator-enabled to the page which controls if the platform authenticator javascript is executed.\r\n\r\nHi! Before submitting your PR for review, and/or before merging it, please\r\ngo through the checklists below. These represent the more critical elements\r\nof our code quality guidelines. The rest of the list can be found in\r\n[CONTRIBUTING.md]\r\n\r\n[CONTRIBUTING.md]: https://github.com/18F/identity-idp/blob/master/CONTRIBUTING.md#pull-request-guidelines\r\n\r\n### Controllers\r\n\r\n- [ ] When adding a new controller that requires the user to be fully\r\nauthenticated, make sure to add `before_action :confirm_two_factor_authenticated`\r\nas the first callback.\r\n\r\n### Database\r\n\r\n- [ ] Unsafe migrations are implemented over several PRs and over several\r\ndeploys to avoid production errors. The [strong_migrations](https://github.com/ankane/strong_migrations#the-zero-downtime-way) gem\r\nwill warn you about unsafe migrations and has great step-by-step instructions\r\nfor various scenarios.\r\n\r\n- [ ] Indexes were added if necessary. This article provides a good overview\r\nof [indexes in Rails](https://goo.gl/1DARYi).\r\n\r\n- [ ] Verified that the changes don't affect other apps (such as the dashboard)\r\n\r\n- [ ] When relevant, a rake task is created to populate the necessary DB columns\r\nin the various environments right before deploying, taking into account the users\r\nwho might not have interacted with this column yet (such as users who have not\r\nset a password yet)\r\n\r\n- [ ] Migrations against existing tables have been tested against a copy of the\r\nproduction database. See #2127 for an example when a migration caused deployment\r\nissues. In that case, all the migration did was add a new column and an index to\r\nthe Users table, which might seem innocuous.\r\n\r\n### Encryption\r\n\r\n- [ ] The changes are compatible with data that was encrypted with the old code.\r\n\r\n### Routes\r\n\r\n- [ ] GET requests are not vulnerable to CSRF attacks (i.e. they don't change\r\nstate or result in destructive behavior).\r\n\r\n### Session\r\n\r\n- [ ] When adding user data to the session, use the `user_session` helper\r\ninstead of the `session` helper so the data does not persist beyond the user's\r\nsession.\r\n\r\n### Testing\r\n\r\n- [ ] Tests added for this feature/bug\r\n- [ ] Prefer feature/integration specs over controller specs\r\n- [ ] When adding code that reads data, write tests for nil values, empty strings,\r\nand invalid inputs.\r\n","created_at":"2018-10-17T05:18:50Z","updated_at":"2018-10-22T16:39:05Z","closed_at":null,"merged_at":null,"merge_commit_sha":"d8c3de7d1c268c85ce6429da9e4ebe614ba7a742","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":355011342,"node_id":"MDU6TGFiZWwzNTUwMTEzNDI=","url":"https://api.github.com/repos/18F/identity-idp/labels/status%20-%20ready%20for%20review","name":"status - ready for review","color":"006b75","default":false},{"id":1067460268,"node_id":"MDU6TGFiZWwxMDY3NDYwMjY4","url":"https://api.github.com/repos/18F/identity-idp/labels/status%20-%20required%20for%20release","name":"status - required for release","color":"db0468","default":false}],"milestone":null,"commits_url":"https://api.github.com/repos/18F/identity-idp/pulls/2609/commits","review_comments_url":"https://api.github.com/repos/18F/identity-idp/pulls/2609/comments","review_comment_url":"https://api.github.com/repos/18F/identity-idp/pulls/comments{/number}","comments_url":"https://api.github.com/repos/18F/identity-idp/issues/2609/comments","statuses_url":"https://api.github.com/repos/18F/identity-idp/statuses/71403afd46997f2a22602eec64ad8b99b3310b65","head":{"label":"18F:stevegsa-add-platform-authenticators-analytics","ref":"stevegsa-add-platform-authenticators-analytics","sha":"71403afd46997f2a22602eec64ad8b99b3310b65","user":{"login":"18F","id":6233994,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYyMzM5OTQ=","avatar_url":"https://avatars0.githubusercontent.com/u/6233994?v=4","gravatar_id":"","url":"https://api.github.com/users/18F","html_url":"https://github.com/18F","followers_url":"https://api.github.com/users/18F/followers","following_url":"https://api.github.com/users/18F/following{/other_user}","gists_url":"https://api.github.com/users/18F/gists{/gist_id}","starred_url":"https://api.github.com/users/18F/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/18F/subscriptions","organizations_url":"https://api.github.com/users/18F/orgs","repos_url":"https://api.github.com/users/18F/repos","events_url":"https://api.github.com/users/18F/events{/privacy}","received_events_url":"https://api.github.com/users/18F/received_events","type":"Organization","site_admin":false},"repo":{"id":50386243,"node_id":"MDEwOlJlcG9zaXRvcnk1MDM4NjI0Mw==","name":"identity-idp","full_name":"18F/identity-idp","private":false,"owner":{"login":"18F","id":6233994,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYyMzM5OTQ=","avatar_url":"https://avatars0.githubusercontent.com/u/6233994?v=4","gravatar_id":"","url":"https://api.github.com/users/18F","html_url":"https://github.com/18F","followers_url":"https://api.github.com/users/18F/followers","following_url":"https://api.github.com/users/18F/following{/other_user}","gists_url":"https://api.github.com/users/18F/gists{/gist_id}","starred_url":"https://api.github.com/users/18F/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/18F/subscriptions","organizations_url":"https://api.github.com/users/18F/orgs","repos_url":"https://api.github.com/users/18F/repos","events_url":"https://api.github.com/users/18F/events{/privacy}","received_events_url":"https://api.github.com/users/18F/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/18F/identity-idp","description":"18F Identity Provider (IdP)","fork":false,"url":"https://api.github.com/repos/18F/identity-idp","forks_url":"https://api.github.com/repos/18F/identity-idp/forks","keys_url":"https://api.github.com/repos/18F/identity-idp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/18F/identity-idp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/18F/identity-idp/teams","hooks_url":"https://api.github.com/repos/18F/identity-idp/hooks","issue_events_url":"https://api.github.com/repos/18F/identity-idp/issues/events{/number}","events_url":"https://api.github.com/repos/18F/identity-idp/events","assignees_url":"https://api.github.com/repos/18F/identity-idp/assignees{/user}","branches_url":"https://api.github.com/repos/18F/identity-idp/branches{/branch}","tags_url":"https://api.github.com/repos/18F/identity-idp/tags","blobs_url":"https://api.github.com/repos/18F/identity-idp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/18F/identity-idp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/18F/identity-idp/git/refs{/sha}","trees_url":"https://api.github.com/repos/18F/identity-idp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/18F/identity-idp/statuses/{sha}","languages_url":"https://api.github.com/repos/18F/identity-idp/languages","stargazers_url":"https://api.github.com/repos/18F/identity-idp/stargazers","contributors_url":"https://api.github.com/repos/18F/identity-idp/contributors","subscribers_url":"https://api.github.com/repos/18F/identity-idp/subscribers","subscription_url":"https://api.github.com/repos/18F/identity-idp/subscription","commits_url":"https://api.github.com/repos/18F/identity-idp/commits{/sha}","git_commits_url":"https://api.github.com/repos/18F/identity-idp/git/commits{/sha}","comments_url":"https://api.github.com/repos/18F/identity-idp/comments{/number}","issue_comment_url":"https://api.github.com/repos/18F/identity-idp/issues/comments{/number}","contents_url":"https://api.github.com/repos/18F/identity-idp/contents/{+path}","compare_url":"https://api.github.com/repos/18F/identity-idp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/18F/identity-idp/merges","archive_url":"https://api.github.com/repos/18F/identity-idp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/18F/identity-idp/downloads","issues_url":"https://api.github.com/repos/18F/identity-idp/issues{/number}","pulls_url":"https://api.github.com/repos/18F/identity-idp/pulls{/number}","milestones_url":"https://api.github.com/repos/18F/identity-idp/milestones{/number}","notifications_url":"https://api.github.com/repos/18F/identity-idp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/18F/identity-idp/labels{/name}","releases_url":"https://api.github.com/repos/18F/identity-idp/releases{/id}","deployments_url":"https://api.github.com/repos/18F/identity-idp/deployments","created_at":"2016-01-25T22:40:59Z","updated_at":"2018-10-22T15:22:07Z","pushed_at":"2018-10-22T16:09:08Z","git_url":"git://github.com/18F/identity-idp.git","ssh_url":"git@github.com:18F/identity-idp.git","clone_url":"https://github.com/18F/identity-idp.git","svn_url":"https://github.com/18F/identity-idp","homepage":"https://secure.login.gov/","size":15974,"stargazers_count":188,"watchers_count":188,"language":"Ruby","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":36,"mirror_url":null,"archived":false,"open_issues_count":27,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":36,"open_issues":27,"watchers":188,"default_branch":"master"}},"base":{"label":"18F:master","ref":"master","sha":"74ac8c03ca70a36064c3a6f9b165e5336d1ac938","user":{"login":"18F","id":6233994,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYyMzM5OTQ=","avatar_url":"https://avatars0.githubusercontent.com/u/6233994?v=4","gravatar_id":"","url":"https://api.github.com/users/18F","html_url":"https://github.com/18F","followers_url":"https://api.github.com/users/18F/followers","following_url":"https://api.github.com/users/18F/following{/other_user}","gists_url":"https://api.github.com/users/18F/gists{/gist_id}","starred_url":"https://api.github.com/users/18F/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/18F/subscriptions","organizations_url":"https://api.github.com/users/18F/orgs","repos_url":"https://api.github.com/users/18F/repos","events_url":"https://api.github.com/users/18F/events{/privacy}","received_events_url":"https://api.github.com/users/18F/received_events","type":"Organization","site_admin":false},"repo":{"id":50386243,"node_id":"MDEwOlJlcG9zaXRvcnk1MDM4NjI0Mw==","name":"identity-idp","full_name":"18F/identity-idp","private":false,"owner":{"login":"18F","id":6233994,"node_id":"MDEyOk9yZ2FuaXphdGlvbjYyMzM5OTQ=","avatar_url":"https://avatars0.githubusercontent.com/u/6233994?v=4","gravatar_id":"","url":"https://api.github.com/users/18F","html_url":"https://github.com/18F","followers_url":"https://api.github.com/users/18F/followers","following_url":"https://api.github.com/users/18F/following{/other_user}","gists_url":"https://api.github.com/users/18F/gists{/gist_id}","starred_url":"https://api.github.com/users/18F/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/18F/subscriptions","organizations_url":"https://api.github.com/users/18F/orgs","repos_url":"https://api.github.com/users/18F/repos","events_url":"https://api.github.com/users/18F/events{/privacy}","received_events_url":"https://api.github.com/users/18F/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/18F/identity-idp","description":"18F Identity Provider (IdP)","fork":false,"url":"https://api.github.com/repos/18F/identity-idp","forks_url":"https://api.github.com/repos/18F/identity-idp/forks","keys_url":"https://api.github.com/repos/18F/identity-idp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/18F/identity-idp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/18F/identity-idp/teams","hooks_url":"https://api.github.com/repos/18F/identity-idp/hooks","issue_events_url":"https://api.github.com/repos/18F/identity-idp/issues/events{/number}","events_url":"https://api.github.com/repos/18F/identity-idp/events","assignees_url":"https://api.github.com/repos/18F/identity-idp/assignees{/user}","branches_url":"https://api.github.com/repos/18F/identity-idp/branches{/branch}","tags_url":"https://api.github.com/repos/18F/identity-idp/tags","blobs_url":"https://api.github.com/repos/18F/identity-idp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/18F/identity-idp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/18F/identity-idp/git/refs{/sha}","trees_url":"https://api.github.com/repos/18F/identity-idp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/18F/identity-idp/statuses/{sha}","languages_url":"https://api.github.com/repos/18F/identity-idp/languages","stargazers_url":"https://api.github.com/repos/18F/identity-idp/stargazers","contributors_url":"https://api.github.com/repos/18F/identity-idp/contributors","subscribers_url":"https://api.github.com/repos/18F/identity-idp/subscribers","subscription_url":"https://api.github.com/repos/18F/identity-idp/subscription","commits_url":"https://api.github.com/repos/18F/identity-idp/commits{/sha}","git_commits_url":"https://api.github.com/repos/18F/identity-idp/git/commits{/sha}","comments_url":"https://api.github.com/repos/18F/identity-idp/comments{/number}","issue_comment_url":"https://api.github.com/repos/18F/identity-idp/issues/comments{/number}","contents_url":"https://api.github.com/repos/18F/identity-idp/contents/{+path}","compare_url":"https://api.github.com/repos/18F/identity-idp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/18F/identity-idp/merges","archive_url":"https://api.github.com/repos/18F/identity-idp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/18F/identity-idp/downloads","issues_url":"https://api.github.com/repos/18F/identity-idp/issues{/number}","pulls_url":"https://api.github.com/repos/18F/identity-idp/pulls{/number}","milestones_url":"https://api.github.com/repos/18F/identity-idp/milestones{/number}","notifications_url":"https://api.github.com/repos/18F/identity-idp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/18F/identity-idp/labels{/name}","releases_url":"https://api.github.com/repos/18F/identity-idp/releases{/id}","deployments_url":"https://api.github.com/repos/18F/identity-idp/deployments","created_at":"2016-01-25T22:40:59Z","updated_at":"2018-10-22T15:22:07Z","pushed_at":"2018-10-22T16:09:08Z","git_url":"git://github.com/18F/identity-idp.git","ssh_url":"git@github.com:18F/identity-idp.git","clone_url":"https://github.com/18F/identity-idp.git","svn_url":"https://github.com/18F/identity-idp","homepage":"https://secure.login.gov/","size":15974,"stargazers_count":188,"watchers_count":188,"language":"Ruby","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":36,"mirror_url":null,"archived":false,"open_issues_count":27,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":36,"open_issues":27,"watchers":188,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/18F/identity-idp/pulls/2609"},"html":{"href":"https://github.com/18F/identity-idp/pull/2609"},"issue":{"href":"https://api.github.com/repos/18F/identity-idp/issues/2609"},"comments":{"href":"https://api.github.com/repos/18F/identity-idp/issues/2609/comments"},"review_comments":{"href":"https://api.github.com/repos/18F/identity-idp/pulls/2609/comments"},"review_comment":{"href":"https://api.github.com/repos/18F/identity-idp/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/18F/identity-idp/pulls/2609/commits"},"statuses":{"href":"https://api.github.com/repos/18F/identity-idp/statuses/71403afd46997f2a22602eec64ad8b99b3310b65"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"stevegsa"}}