{"action":"created","comment":{"url":"https://api.github.com/repos/google/WebFundamentals/pulls/comments/121511394","pull_request_review_id":43545845,"id":121511394,"diff_hunk":"@@ -0,0 +1,333 @@\n+project_path: /web/_project.yaml\n+book_path: /web/updates/_book.yaml\n+description: Latest Updates to the Credential Management API\n+\n+{# wf_updated_on: 2017-06-07 #}\n+{# wf_published_on: 2017-06-07 #}\n+{# wf_tags: performance #}\n+{# wf_featured_snippet: Latest updates coming to the Credential Management API in Chrome 60. Also includes an update landed in Chrome 57. #}\n+\n+# Latest Updates to the Credential Management API {: .page-title }\n+\n+{% include \"web/_shared/contributors/agektmr.html\" %}\n+\n+Some of the updates described here are explained at the Google I/O session,\n+**Secure and Seamless Sign-In: Keeping Users Engaged**:\n+\n+<div class=\"video-wrapper-full-width\">\n+  <iframe class=\"devsite-embedded-youtube-video\" data-video-id=\"DBBFK7bvEQo\"\n+          data-autohide=\"1\" data-showinfo=\"0\" frameborder=\"0\" allowfullscreen>\n+  </iframe>\n+</div>\n+\n+## Chrome 57\n+\n+Chrome 57 introduced this important change to the\n+[Credential Management API](/web/fundamentals/security/credential-management).\n+\n+### Credentials can be shared from a different subdomain \n+\n+Chrome can now retrieve a credential stored in a different subdomain using the\n+[Credential Management API](/web/fundamentals/security/credential-management).  \n+\n+For example, if a password is stored in `login.example.com`,\n+a script on `www.example.com` can show it as one of account items in account chooser dialog.\n+When a user taps on the dialog, the password gets passed.\n+\n+Explicitly store the password using `navigator.credentials.store()`.\n+Once it's stored, the password is available as a credential\n+in the exact same origin `www.example.com` onward.\n+\n+**You must explicitly store the credential to the origin.**\n+Users choosing the credentials won’t copy them to the current origin.\n+\n+In the following screenshot, credential information stored under `login.aliexpress.com`\n+is visible to `m.aliexpress.com` and available for the user to choose from:\n+\n+<figure>\n+  <img src=\"/web/updates/images/2017/06/credentials.png\"\n+       alt=\"Account chooser showing selected subdomain login details\"/>\n+</figure>\n+\n+<aside>\n+  <strong>Coming soon:</strong>\n+  Sharing credentials between totally different domains is in development.\n+</aside>\n+\n+## Chrome 60\n+\n+Chrome 60 introduces several important changes to the\n+[Credential Management API](/web/fundamentals/security/credential-management):\n+\n+* `PasswordCredential` object now includes a password.\n+\n+*  As the custom `fetch()` function is no longer required to fetch the password,\n+it will be deprecated soon.\n+\n+* `navigator.credentials.get()` now accepts an enum `mediation`\n+instead of boolean flag `unmediated`.\n+\n+* `requireUserMediation()` renamed to `preventSilentAccess()`.\n+\n+*  New method `navigator.credentials.create()`\n+asynchronously creates credential objects.\n+\n+### `PasswordCredential` object now includes password \n+\n+The Credential Management API took a conservative approach to handling passwords.\n+It concealed passwords from JavaScript, requiring developers\n+to send the `PasswordCredential` object directly to their server\n+for validation via an extension to the `fetch()` API.\n+\n+But this approach introduced a number of restrictions.\n+We received feedback that developers could not use the API because:\n+\n+* They had to send the password as part of a JSON object.\n+\n+* They had to send the hash value of the password to their server.\n+\n+After performing a security analysis and recognizing that concealing passwords\n+from JavaScript did not prevent all attack vectors as effectively as we were hoping,\n+we have decided to make a change.\n+\n+The Credential Management API now includes a raw password\n+in a returned credential object so you have access to it as plain text.\n+You can use existing methods to deliver credential information to your server:\n+\n+    navigator.credentials.get({\n+\n+      password: true,\n+\n+      federated: {\n+\n+        provider: [ 'https://accounts.google.com' ]\n+\n+      },\n+\n+      mediation: 'silent'\n+\n+    }).then(c => {\n+\n+      if (c) {\n+\n+        let form = new FormData();\n+\n+        form.append('email', c.id);\n+\n+        form.append('password', c.password);\n+\n+        form.append('csrf_token', csrf_token);\n+\n+        return fetch('/signin', {\n+\n+          method: 'POST',\n+\n+          credentials: 'include',\n+\n+          body: form\n+\n+        });\n+\n+      } else {\n+\n+        // Fallback to sign-in form\n+\n+      }\n+\n+    }).then(res => {\n+\n+      if (res.status === 200) {\n+\n+        return res.json();\n+\n+      } else {\n+\n+        throw 'Auth failed';\n+\n+      }\n+\n+    }).then(profile => {\n+\n+      console.log('Auth succeeded', profile);\n+\n+    });\n+\n+### Custom fetch will be deprecated soon\n+\n+Now that passwords return in the `PasswordCredential` object,\n+the custom `fetch()` function will stop functioning starting Chrome 62.\n+All developers **MUST** make relevant changes to not use a custom `fetch()`.\n+\n+To determine if you are using a custom `fetch()` function,\n+check if it uses a `PasswordCredential` object or a `FederatedCredential` object\n+as a value of credentials property and remove it, for example:\n+\n+    fetch('/signin', {\n+\n+      method: 'POST',\n+\n+      **credentials: c**\n+\n+    })\n+\n+### `navigator.credentials.get()` now accepts an enum mediation\n+\n+Until Chrome 60,\n+`navigator.credentials.get()` accepted an optional `unmediated` property\n+with a boolean flag. For example:\n+\n+    navigator.credentials.get({\n+\n+      password: true,\n+\n+      federated: {\n+\n+        provider: [ 'https://accounts.google.com' ]\n+\n+      },\n+\n+      unmediated: true\n+\n+    }).then(c => {\n+\n+      // Sign-in\n+\n+    });\n+\n+This positive flag instructs the browser to skip a user mediation.\n+The user mediation could happen when:\n+\n+* A user needs to choose an account to sign-in with.\n+\n+* A user wants to explicitly sign-in\n+after `navigator.credentials.requireUseMediation()` call.\n+\n+The flag is now extended as mediation, for example:\n+\n+    navigator.credentials.get({\n+\n+      password: true,\n+\n+      federated: {\n+\n+        provider: [ 'https://accounts.google.com' ]\n+\n+      },\n+\n+      mediation: 'silent'\n+\n+    }).then(c => {\n+\n+      // Sign-in\n+\n+    });\n+\n+Choose one of the following options for the `mediation` value:\n+\n+<table>\n+  <tr>\n+    <th><code>mediation</code> value</th>\n+    <th>Compared to boolean flag</th>\n+    <th>Behavior</th>\n+  </tr>\n+  <tr>\n+    <td><code>silent</code></td>\n+    <td>Equals <code>unmediated: true</code></td>\n+    <td>Credential passed without showing an account chooser.</td>\n+  </tr>\n+  <tr>\n+    <td><code>optional</code></td>\n+    <td>Equals <code>unmediated: false</code></td>\n+    <td>Shows an account chooser if\n+    <code>preventSilentAccess()</code> called previously.</td>\n+    <td></td>\n+  </tr>\n+  <tr>\n+    <td><code>required</code></td>\n+    <td>A new option</td>\n+    <td>Always show an account chooser.\n+    Useful when you want to let a user to switch an account\n+    using the native account chooser dialog.</td>\n+  </tr>\n+</table>\n+\n+### `requireUserMediation()` renamed to `preventSilentAccess()`\n+\n+To align nicely with the new mediation property offered in the `get()` call ,\n+the `navigator.credentials.requireUserMediation()` method has been renamed to\n+`navigator.credentials.preventSilentAccess()`. \n+\n+See the previous table\n+to understand how calling this function affects `navigator.credentials.get()`.","path":"src/content/en/updates/2017/06/credential-management-updates.md","position":261,"original_position":261,"commit_id":"1bc2dca98a8cf7235ce71c0af9558ba91350f2fe","original_commit_id":"1bc2dca98a8cf7235ce71c0af9558ba91350f2fe","user":{"login":"Meggin","id":1561825,"avatar_url":"https://avatars0.githubusercontent.com/u/1561825?v=3","gravatar_id":"","url":"https://api.github.com/users/Meggin","html_url":"https://github.com/Meggin","followers_url":"https://api.github.com/users/Meggin/followers","following_url":"https://api.github.com/users/Meggin/following{/other_user}","gists_url":"https://api.github.com/users/Meggin/gists{/gist_id}","starred_url":"https://api.github.com/users/Meggin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Meggin/subscriptions","organizations_url":"https://api.github.com/users/Meggin/orgs","repos_url":"https://api.github.com/users/Meggin/repos","events_url":"https://api.github.com/users/Meggin/events{/privacy}","received_events_url":"https://api.github.com/users/Meggin/received_events","type":"User","site_admin":false},"body":"Removed.","created_at":"2017-06-12T19:59:40Z","updated_at":"2017-06-12T19:59:40Z","html_url":"https://github.com/google/WebFundamentals/pull/4666#discussion_r121511394","pull_request_url":"https://api.github.com/repos/google/WebFundamentals/pulls/4666","_links":{"self":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/comments/121511394"},"html":{"href":"https://github.com/google/WebFundamentals/pull/4666#discussion_r121511394"},"pull_request":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/4666"}}},"pull_request":{"url":"https://api.github.com/repos/google/WebFundamentals/pulls/4666","id":124570371,"html_url":"https://github.com/google/WebFundamentals/pull/4666","diff_url":"https://github.com/google/WebFundamentals/pull/4666.diff","patch_url":"https://github.com/google/WebFundamentals/pull/4666.patch","issue_url":"https://api.github.com/repos/google/WebFundamentals/issues/4666","number":4666,"state":"open","locked":false,"title":"Adding credential management updates guide","user":{"login":"Meggin","id":1561825,"avatar_url":"https://avatars0.githubusercontent.com/u/1561825?v=3","gravatar_id":"","url":"https://api.github.com/users/Meggin","html_url":"https://github.com/Meggin","followers_url":"https://api.github.com/users/Meggin/followers","following_url":"https://api.github.com/users/Meggin/following{/other_user}","gists_url":"https://api.github.com/users/Meggin/gists{/gist_id}","starred_url":"https://api.github.com/users/Meggin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Meggin/subscriptions","organizations_url":"https://api.github.com/users/Meggin/orgs","repos_url":"https://api.github.com/users/Meggin/repos","events_url":"https://api.github.com/users/Meggin/events{/privacy}","received_events_url":"https://api.github.com/users/Meggin/received_events","type":"User","site_admin":false},"body":"Ready for review!","created_at":"2017-06-08T05:31:52Z","updated_at":"2017-06-12T19:59:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3a34f033b6b0f6b630b79afefc95b0ecd45a94ee","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/google/WebFundamentals/pulls/4666/commits","review_comments_url":"https://api.github.com/repos/google/WebFundamentals/pulls/4666/comments","review_comment_url":"https://api.github.com/repos/google/WebFundamentals/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/WebFundamentals/issues/4666/comments","statuses_url":"https://api.github.com/repos/google/WebFundamentals/statuses/1bc2dca98a8cf7235ce71c0af9558ba91350f2fe","head":{"label":"google:cred-updates","ref":"cred-updates","sha":"1bc2dca98a8cf7235ce71c0af9558ba91350f2fe","user":{"login":"google","id":1342004,"avatar_url":"https://avatars2.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":19249835,"name":"WebFundamentals","full_name":"google/WebFundamentals","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars2.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/WebFundamentals","description":"Best practices for modern web development","fork":false,"url":"https://api.github.com/repos/google/WebFundamentals","forks_url":"https://api.github.com/repos/google/WebFundamentals/forks","keys_url":"https://api.github.com/repos/google/WebFundamentals/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/WebFundamentals/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/WebFundamentals/teams","hooks_url":"https://api.github.com/repos/google/WebFundamentals/hooks","issue_events_url":"https://api.github.com/repos/google/WebFundamentals/issues/events{/number}","events_url":"https://api.github.com/repos/google/WebFundamentals/events","assignees_url":"https://api.github.com/repos/google/WebFundamentals/assignees{/user}","branches_url":"https://api.github.com/repos/google/WebFundamentals/branches{/branch}","tags_url":"https://api.github.com/repos/google/WebFundamentals/tags","blobs_url":"https://api.github.com/repos/google/WebFundamentals/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/WebFundamentals/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/WebFundamentals/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/WebFundamentals/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/WebFundamentals/statuses/{sha}","languages_url":"https://api.github.com/repos/google/WebFundamentals/languages","stargazers_url":"https://api.github.com/repos/google/WebFundamentals/stargazers","contributors_url":"https://api.github.com/repos/google/WebFundamentals/contributors","subscribers_url":"https://api.github.com/repos/google/WebFundamentals/subscribers","subscription_url":"https://api.github.com/repos/google/WebFundamentals/subscription","commits_url":"https://api.github.com/repos/google/WebFundamentals/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/WebFundamentals/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/WebFundamentals/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/WebFundamentals/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/WebFundamentals/contents/{+path}","compare_url":"https://api.github.com/repos/google/WebFundamentals/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/WebFundamentals/merges","archive_url":"https://api.github.com/repos/google/WebFundamentals/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/WebFundamentals/downloads","issues_url":"https://api.github.com/repos/google/WebFundamentals/issues{/number}","pulls_url":"https://api.github.com/repos/google/WebFundamentals/pulls{/number}","milestones_url":"https://api.github.com/repos/google/WebFundamentals/milestones{/number}","notifications_url":"https://api.github.com/repos/google/WebFundamentals/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/WebFundamentals/labels{/name}","releases_url":"https://api.github.com/repos/google/WebFundamentals/releases{/id}","deployments_url":"https://api.github.com/repos/google/WebFundamentals/deployments","created_at":"2014-04-28T18:45:45Z","updated_at":"2017-06-12T15:23:19Z","pushed_at":"2017-06-12T19:12:52Z","git_url":"git://github.com/google/WebFundamentals.git","ssh_url":"git@github.com:google/WebFundamentals.git","clone_url":"https://github.com/google/WebFundamentals.git","svn_url":"https://github.com/google/WebFundamentals","homepage":"https://developers.google.com/web/fundamentals","size":1280575,"stargazers_count":7482,"watchers_count":7482,"language":"HTML","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1442,"mirror_url":null,"open_issues_count":220,"forks":1442,"open_issues":220,"watchers":7482,"default_branch":"master"}},"base":{"label":"google:master","ref":"master","sha":"fdfd85bcc685aca7f81398caa4a3dad18f6f96fc","user":{"login":"google","id":1342004,"avatar_url":"https://avatars2.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":19249835,"name":"WebFundamentals","full_name":"google/WebFundamentals","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars2.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/WebFundamentals","description":"Best practices for modern web development","fork":false,"url":"https://api.github.com/repos/google/WebFundamentals","forks_url":"https://api.github.com/repos/google/WebFundamentals/forks","keys_url":"https://api.github.com/repos/google/WebFundamentals/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/WebFundamentals/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/WebFundamentals/teams","hooks_url":"https://api.github.com/repos/google/WebFundamentals/hooks","issue_events_url":"https://api.github.com/repos/google/WebFundamentals/issues/events{/number}","events_url":"https://api.github.com/repos/google/WebFundamentals/events","assignees_url":"https://api.github.com/repos/google/WebFundamentals/assignees{/user}","branches_url":"https://api.github.com/repos/google/WebFundamentals/branches{/branch}","tags_url":"https://api.github.com/repos/google/WebFundamentals/tags","blobs_url":"https://api.github.com/repos/google/WebFundamentals/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/WebFundamentals/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/WebFundamentals/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/WebFundamentals/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/WebFundamentals/statuses/{sha}","languages_url":"https://api.github.com/repos/google/WebFundamentals/languages","stargazers_url":"https://api.github.com/repos/google/WebFundamentals/stargazers","contributors_url":"https://api.github.com/repos/google/WebFundamentals/contributors","subscribers_url":"https://api.github.com/repos/google/WebFundamentals/subscribers","subscription_url":"https://api.github.com/repos/google/WebFundamentals/subscription","commits_url":"https://api.github.com/repos/google/WebFundamentals/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/WebFundamentals/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/WebFundamentals/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/WebFundamentals/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/WebFundamentals/contents/{+path}","compare_url":"https://api.github.com/repos/google/WebFundamentals/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/WebFundamentals/merges","archive_url":"https://api.github.com/repos/google/WebFundamentals/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/WebFundamentals/downloads","issues_url":"https://api.github.com/repos/google/WebFundamentals/issues{/number}","pulls_url":"https://api.github.com/repos/google/WebFundamentals/pulls{/number}","milestones_url":"https://api.github.com/repos/google/WebFundamentals/milestones{/number}","notifications_url":"https://api.github.com/repos/google/WebFundamentals/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/WebFundamentals/labels{/name}","releases_url":"https://api.github.com/repos/google/WebFundamentals/releases{/id}","deployments_url":"https://api.github.com/repos/google/WebFundamentals/deployments","created_at":"2014-04-28T18:45:45Z","updated_at":"2017-06-12T15:23:19Z","pushed_at":"2017-06-12T19:12:52Z","git_url":"git://github.com/google/WebFundamentals.git","ssh_url":"git@github.com:google/WebFundamentals.git","clone_url":"https://github.com/google/WebFundamentals.git","svn_url":"https://github.com/google/WebFundamentals","homepage":"https://developers.google.com/web/fundamentals","size":1280575,"stargazers_count":7482,"watchers_count":7482,"language":"HTML","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1442,"mirror_url":null,"open_issues_count":220,"forks":1442,"open_issues":220,"watchers":7482,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/4666"},"html":{"href":"https://github.com/google/WebFundamentals/pull/4666"},"issue":{"href":"https://api.github.com/repos/google/WebFundamentals/issues/4666"},"comments":{"href":"https://api.github.com/repos/google/WebFundamentals/issues/4666/comments"},"review_comments":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/4666/comments"},"review_comment":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/WebFundamentals/pulls/4666/commits"},"statuses":{"href":"https://api.github.com/repos/google/WebFundamentals/statuses/1bc2dca98a8cf7235ce71c0af9558ba91350f2fe"}}}}
{"actor":{"display_login":"Meggin"}}