diff --git a/wp-admin/authorize-application.php b/wp-admin/authorize-application.php
new file mode 100644
index 0000000000..dd60a349f6
--- /dev/null
+++ b/wp-admin/authorize-application.php
@@ -0,0 +1,230 @@
+ $app_name ) );
+
+ if ( is_wp_error( $created ) ) {
+ $error = $created;
+ } else {
+ list( $new_password ) = $created;
+
+ if ( $success_url ) {
+ $redirect = add_query_arg(
+ array(
+ 'username' => urlencode( wp_get_current_user()->user_login ),
+ 'password' => urlencode( $new_password ),
+ ),
+ $success_url
+ );
+ }
+ }
+ }
+
+ if ( $redirect ) {
+ // Explicitly not using wp_safe_redirect b/c sends to arbitrary domain.
+ wp_redirect( $redirect );
+ exit;
+ }
+}
+
+$title = __( 'Authorize Application' );
+
+$app_name = ! empty( $_REQUEST['app_name'] ) ? $_REQUEST['app_name'] : '';
+$success_url = ! empty( $_REQUEST['success_url'] ) ? $_REQUEST['success_url'] : null;
+$reject_url = ! empty( $_REQUEST['reject_url'] ) ? $_REQUEST['reject_url'] : $success_url;
+$user = wp_get_current_user();
+
+$request = compact( 'app_name', 'success_url', 'reject_url' );
+$is_valid = wp_is_authorize_application_password_request_valid( $request, $user );
+
+if ( is_wp_error( $is_valid ) ) {
+ wp_die(
+ __( 'The Authorize Application request is not allowed.' ) . ' ' . implode( ' ', $is_valid->get_error_messages() ),
+ __( 'Cannot Authorize Application' )
+ );
+}
+
+if ( ! wp_is_application_passwords_available_for_user( $user ) ) {
+ if ( wp_is_application_passwords_available() ) {
+ $message = __( 'Application passwords are not enabled for your account. Please contact the site administrator for assistance.' );
+ } else {
+ $message = __( 'Application passwords are not enabled.' );
+ }
+
+ wp_die(
+ $message,
+ __( 'Cannot Authorize Application' ),
+ array(
+ 'link_text' => __( 'Go Back' ),
+ 'link_url' => $reject_url ? add_query_arg( 'error', 'disabled', $reject_url ) : admin_url(),
+ )
+ );
+}
+
+wp_enqueue_script( 'auth-app' );
+wp_localize_script(
+ 'auth-app',
+ 'authApp',
+ array(
+ 'user_login' => $user->user_login,
+ 'success' => $success_url,
+ 'reject' => $reject_url ? $reject_url : admin_url(),
+ )
+);
+
+require_once ABSPATH . 'wp-admin/admin-header.php';
+
+?>
+
+
+
+
+
+
+
+
+
+
+
+ ' . esc_html( $app_name ) . '' );
+ ?>
+
+
+
+
+
+
+
+
+ ' . esc_html( $app_name ) . '',
+ '' . esc_html( WP_Application_Passwords::chunk_password( $new_password ) ) . ''
+ );
+ ?>
+
+
+
+
+
+
+
+
+
+input[type=checkbox]{margin-top:0}.wp-admin p label input[type=checkbox]{margin-top:-4px}.wp-admin p label input[type=radio]{margin-top:-2px}input[type=radio]{border-radius:50%;margin-left:.25rem;line-height:.71428571}input[type=checkbox]:checked::before,input[type=radio]:checked::before{float:right;display:inline-block;vertical-align:middle;width:1rem;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}input[type=checkbox]:checked::before{content:url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%231e8cbe%27%2F%3E%3C%2Fsvg%3E);margin:-.1875rem -.25rem 0 0;height:1.3125rem;width:1.3125rem}input[type=radio]:checked::before{content:"";border-radius:50%;width:.5rem;height:.5rem;margin:.1875rem;background-color:#1e8cbe;line-height:1.14285714}@-moz-document url-prefix(){.form-table input.tog,input[type=checkbox],input[type=radio]{margin-bottom:-1px}}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-decoration{display:none}.wp-admin input[type=file]{padding:3px 0;cursor:pointer}input.readonly,input[readonly],textarea.readonly,textarea[readonly]{background-color:#eee}::-webkit-input-placeholder{color:#72777c}::-moz-placeholder{color:#72777c;opacity:1}:-ms-input-placeholder{color:#72777c}.form-invalid input,.form-invalid input:focus,.form-invalid select,.form-invalid select:focus{border-color:#dc3232!important;box-shadow:0 0 2px rgba(204,0,0,.8)}.form-table .form-required.form-invalid td:after{content:"\f534";font:normal 20px/1 dashicons;color:#dc3232;margin-right:-25px;vertical-align:middle}.form-table .form-required.user-pass1-wrap.form-invalid td:after{content:""}.form-table .form-required.user-pass1-wrap.form-invalid .password-input-wrapper:after{content:"\f534";font:normal 20px/1 dashicons;color:#dc3232;margin:0 -29px 0 6px;vertical-align:middle}.form-input-tip{color:#666}input.disabled,input:disabled,select.disabled,select:disabled,textarea.disabled,textarea:disabled{background:rgba(255,255,255,.5);border-color:rgba(222,222,222,.75);box-shadow:inset 0 1px 2px rgba(0,0,0,.04);color:rgba(51,51,51,.5)}input[type=file].disabled,input[type=file]:disabled,input[type=range].disabled,input[type=range]:disabled{background:0 0;box-shadow:none;cursor:default}input[type=checkbox].disabled,input[type=checkbox].disabled:checked:before,input[type=checkbox]:disabled,input[type=checkbox]:disabled:checked:before,input[type=radio].disabled,input[type=radio].disabled:checked:before,input[type=radio]:disabled,input[type=radio]:disabled:checked:before{opacity:.7}.wp-core-ui select{font-size:14px;line-height:2;color:#32373c;border-color:#7e8993;box-shadow:none;border-radius:3px;padding:0 8px 0 24px;min-height:30px;max-width:25rem;-webkit-appearance:none;background:#fff url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E') no-repeat left 5px top 55%;background-size:16px 16px;cursor:pointer;vertical-align:middle}.wp-core-ui select:hover{color:#007cba}.wp-core-ui select:focus{border-color:#007cba;color:#016087;box-shadow:0 0 0 1px #007cba}.wp-core-ui select:active{border-color:#999;box-shadow:none}.wp-core-ui select.disabled,.wp-core-ui select:disabled{color:#a0a5aa;border-color:#ddd;background-color:#f7f7f7;background-image:url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23a0a5aa%22%2F%3E%3C%2Fsvg%3E');box-shadow:none;text-shadow:0 1px 0 #fff;cursor:default;transform:none}.wp-core-ui select:-moz-focusring{color:transparent;text-shadow:0 0 0 #016087}.wp-core-ui select::-ms-value{background:0 0;color:#555}.wp-core-ui select:hover::-ms-value{color:#007cba}.wp-core-ui select:focus::-ms-value{color:#016087}.wp-core-ui select.disabled::-ms-value,.wp-core-ui select:disabled::-ms-value{color:#a0a5aa}.wp-core-ui select::-ms-expand{display:none}.wp-admin .button-cancel{display:inline-block;min-height:28px;padding:0 5px;line-height:2}.meta-box-sortables select{max-width:100%}.meta-box-sortables input{vertical-align:middle}.misc-pub-post-status select{margin-top:0}.wp-core-ui select[multiple]{height:auto;padding-left:8px;background:#fff}.submit{padding:1.5em 0;margin:5px 0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border:none}form p.submit a.cancel:hover{text-decoration:none}p.submit{text-align:right;max-width:100%;margin-top:20px;padding-top:10px}.textright p.submit{border:none;text-align:left}table.form-table+input+input+p.submit,table.form-table+input+p.submit,table.form-table+p.submit{border-top:none;padding-top:0}#major-publishing-actions input,#minor-publishing-actions .preview,#minor-publishing-actions input{text-align:center}input.all-options,textarea.all-options{width:250px}input.large-text,textarea.large-text{width:99%}.regular-text{width:25em}input.small-text{width:50px;padding:0 6px}label input.small-text{margin-top:-4px}input[type=number].small-text{width:65px;padding-left:0}input.tiny-text{width:35px}input[type=number].tiny-text{width:45px;padding-left:0}#doaction,#doaction2,#post-query-submit{margin:0 0 0 8px}.tablenav .actions select{float:right;margin-left:6px;max-width:12.5rem}#timezone_string option{margin-right:1em}.wp-cancel-pw>.dashicons,.wp-hide-pw>.dashicons{position:relative;top:3px;width:1.25rem;height:1.25rem;top:.25rem;font-size:20px}.wp-cancel-pw .dashicons-no{display:none}#your-profile label+a,label{vertical-align:middle}#your-profile label+a,fieldset label{vertical-align:middle}.options-media-php [for*="_size_"]{min-width:10em;vertical-align:baseline}.options-media-php .small-text[name*="_size_"]{margin:0 0 1em}#misc-publishing-actions label{vertical-align:baseline}#pass-strength-result{background-color:#eee;border:1px solid #ddd;color:#23282d;margin:-1px 1px 5px;padding:3px 5px;text-align:center;width:25em;box-sizing:border-box;opacity:0}#pass-strength-result.short{background-color:#f1adad;border-color:#e35b5b;opacity:1}#pass-strength-result.bad{background-color:#fbc5a9;border-color:#f78b53;opacity:1}#pass-strength-result.good{background-color:#ffe399;border-color:#ffc733;opacity:1}#pass-strength-result.strong{background-color:#c1e1b9;border-color:#83c373;opacity:1}#pass1-text.short,#pass1.short{border-color:#e35b5b}#pass1-text.bad,#pass1.bad{border-color:#f78b53}#pass1-text.good,#pass1.good{border-color:#ffc733}#pass1-text.strong,#pass1.strong{border-color:#83c373}.pw-weak{display:none}.indicator-hint{padding-top:8px}.wp-pwd [type=password],.wp-pwd [type=text]{margin-bottom:0;min-height:30px}.wp-pwd input::-ms-reveal{display:none}#pass1-text,.show-password #pass1{display:none}#pass1-text::-ms-clear{display:none}.show-password #pass1-text{display:inline-block}p.search-box{float:left;margin:0}.network-admin.themes-php p.search-box{clear:right}.search-box input[name="s"],.tablenav .search-plugins input[name="s"],.tagsdiv .newtag{float:right;margin:0 0 0 4px}.js.plugins-php .search-box .wp-filter-search{margin:0;width:280px}input[type=email].ui-autocomplete-loading,input[type=text].ui-autocomplete-loading{background-image:url(../images/loading.gif);background-repeat:no-repeat;background-position:left center;visibility:visible}input.ui-autocomplete-input.open{border-bottom-color:transparent}ul#add-to-blog-users{margin:0 14px 0 0}.ui-autocomplete{padding:0;margin:0;list-style:none;position:absolute;z-index:10000;border:1px solid #5b9dd9;box-shadow:0 1px 2px rgba(30,140,190,.8);background-color:#fff}.ui-autocomplete li{margin-bottom:0;padding:4px 10px;white-space:nowrap;text-align:right;cursor:pointer}.ui-autocomplete .ui-state-focus{background-color:#ddd}.wp-tags-autocomplete .ui-state-focus{background-color:#0073aa;color:#fff}.form-table{border-collapse:collapse;margin-top:.5em;width:100%;clear:both}.form-table,.form-table td,.form-table td p,.form-table th{font-size:14px}.form-table td{margin-bottom:9px;padding:15px 10px;line-height:1.3;vertical-align:middle}.form-table th,.form-wrap label{color:#23282d;font-weight:400;text-shadow:none;vertical-align:baseline}.form-table th{vertical-align:top;text-align:right;padding:20px 0 20px 10px;width:200px;line-height:1.3;font-weight:600}.form-table .td-full,.form-table th.th-full{width:auto;padding:20px 0 20px 10px;font-weight:400}.form-table td p{margin-top:4px;margin-bottom:0}.form-table .date-time-doc{margin-top:1em}.form-table p.timezone-info{margin:1em 0}.form-table td fieldset label{margin:.35em 0 .5em!important;display:inline-block}.form-table td fieldset p label{margin-top:0!important}.form-table td fieldset label,.form-table td fieldset li,.form-table td fieldset p{line-height:1.4}.form-table input.tog,.form-table input[type=radio]{margin-top:-4px;margin-left:4px;float:none}.form-table .pre{padding:8px;margin:0}table.form-table td .updated{font-size:13px}table.form-table td .updated p{font-size:13px;margin:.3em 0}#profile-page .form-table textarea{width:500px;margin-bottom:6px}#profile-page .form-table #rich_editing{margin-left:5px}#your-profile legend{font-size:22px}#display_name{width:15em}#adduser .form-field input,#createuser .form-field input{width:25em}.color-option{display:inline-block;width:24%;padding:5px 15px 15px;box-sizing:border-box;margin-bottom:3px}.color-option.selected,.color-option:hover{background:#ddd}.color-palette{width:100%;border-spacing:0;border-collapse:collapse}.color-palette td{height:20px;padding:0;border:none}.color-option{cursor:pointer}.tool-box .title{margin:8px 0;font-size:18px;font-weight:400;line-height:24px}.label-responsive{vertical-align:middle}#export-filters p{margin:0 0 1em}#export-filters p.submit{margin:7px 0 5px}.card{position:relative;margin-top:20px;padding:.7em 2em 1em;min-width:255px;max-width:520px;border:1px solid #ccd0d4;box-shadow:0 1px 1px rgba(0,0,0,.04);background:#fff;box-sizing:border-box}.pressthis h4{margin:2em 0 1em}.pressthis textarea{width:100%;font-size:1em}#pressthis-code-wrap{overflow:auto}.pressthis-bookmarklet-wrapper{margin:20px 0 8px;vertical-align:top;position:relative;z-index:1}.pressthis-bookmarklet,.pressthis-bookmarklet:active,.pressthis-bookmarklet:focus,.pressthis-bookmarklet:hover{display:inline-block;position:relative;cursor:move;color:#32373c;background:#e5e5e5;border-radius:5px;border:1px solid #b4b9be;font-style:normal;line-height:16px;font-size:14px;text-decoration:none}.pressthis-bookmarklet:active{outline:0}.pressthis-bookmarklet:after{content:"";width:70%;height:55%;z-index:-1;position:absolute;left:10px;bottom:9px;background:0 0;transform:skew(-20deg) rotate(-6deg);box-shadow:0 10px 8px rgba(0,0,0,.6)}.pressthis-bookmarklet:hover:after{transform:skew(-20deg) rotate(-9deg);box-shadow:0 10px 8px rgba(0,0,0,.7)}.pressthis-bookmarklet span{display:inline-block;margin:0 0 0;padding:0 9px 8px 12px}.pressthis-bookmarklet span:before{color:#72777c;font:normal 20px/1 dashicons;content:"\f157";position:relative;display:inline-block;top:4px;margin-left:4px}.pressthis-js-toggle{margin-right:10px;padding:0;height:auto;vertical-align:top}.pressthis-js-toggle.button.button{margin-right:10px;padding:0;height:auto;vertical-align:top}.pressthis-js-toggle .dashicons{margin:5px 7px 6px 8px;color:#555d66}.timezone-info code{white-space:nowrap}.defaultavatarpicker .avatar{margin:2px 0;vertical-align:middle}.options-general-php .date-time-text{display:inline-block;min-width:10em}.options-general-php input.small-text{width:56px;margin:-2px 0}.options-general-php .spinner{float:none;margin:-3px 3px 0}.options-general-php .language-install-spinner,.settings-php .language-install-spinner{display:inline-block;float:none;margin:-3px 5px 0;vertical-align:middle}.form-table.permalink-structure .available-structure-tags li{float:right;margin-left:5px}.setup-php textarea{max-width:100%}.form-field #site-address{max-width:25em}.form-field #domain{max-width:22em}.form-field #admin-email,.form-field #blog_last_updated,.form-field #blog_registered,.form-field #path,.form-field #site-title{max-width:25em}.form-field #path{margin-bottom:5px}#search-sites,#search-users{max-width:60%}.request-filesystem-credentials-dialog{display:none;visibility:visible}.request-filesystem-credentials-dialog .notification-dialog{top:10%;max-height:85%}.request-filesystem-credentials-dialog-content{margin:25px}#request-filesystem-credentials-title{font-size:1.3em;margin:1em 0}.request-filesystem-credentials-form legend{font-size:1em;padding:1.33em 0;font-weight:600}.request-filesystem-credentials-form input[type=password],.request-filesystem-credentials-form input[type=text]{display:block}.request-filesystem-credentials-dialog input[type=password],.request-filesystem-credentials-dialog input[type=text]{width:100%}.request-filesystem-credentials-form .field-title{font-weight:600}.request-filesystem-credentials-dialog label[for=hostname],.request-filesystem-credentials-dialog label[for=private_key],.request-filesystem-credentials-dialog label[for=public_key]{display:block;margin-bottom:1em}.request-filesystem-credentials-dialog .ftp-password,.request-filesystem-credentials-dialog .ftp-username{float:right;width:48%}.request-filesystem-credentials-dialog .ftp-password{margin-right:4%}.request-filesystem-credentials-dialog .request-filesystem-credentials-action-buttons{text-align:left}.request-filesystem-credentials-dialog label[for=ftp]{margin-left:10px}.request-filesystem-credentials-dialog #auth-keys-desc{margin-bottom:0}#request-filesystem-credentials-dialog .button:not(:last-child){margin-left:10px}#request-filesystem-credentials-form .cancel-button{display:none}#request-filesystem-credentials-dialog .cancel-button{display:inline}.request-filesystem-credentials-dialog .ftp-password,.request-filesystem-credentials-dialog .ftp-username{float:none;width:auto}.request-filesystem-credentials-dialog .ftp-username{margin-bottom:1em}.request-filesystem-credentials-dialog .ftp-password{margin:0}.request-filesystem-credentials-dialog .ftp-password em{color:#888}.request-filesystem-credentials-dialog label{display:block;line-height:1.5;margin-bottom:1em}.request-filesystem-credentials-form legend{padding-bottom:0}.request-filesystem-credentials-form #ssh-keys legend{font-size:1.3em}.request-filesystem-credentials-form .notice{margin:0 0 20px 0;clear:both}.tools-privacy-policy-page form{margin-bottom:1.3em}.tools-privacy-policy-page input.button,.tools-privacy-policy-page select{margin:0 6px 0 1px}.tools-privacy-edit{margin:1.5em 0}.tools-privacy-policy-page span{line-height:2}.privacy_requests .column-email{width:40%}.privacy_requests .column-type{text-align:center}.privacy_requests tfoot td:first-child,.privacy_requests thead td:first-child{border-right:4px solid #fff}.privacy_requests tbody th{border-right:4px solid #fff;background:#fff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.1)}.privacy_requests .row-actions{color:#72777c}.privacy_requests .row-actions.processing{position:static}.privacy_requests tbody .has-request-results th{box-shadow:none}.privacy_requests tbody .request-results th .notice{margin:0 0 5px}.privacy_requests tbody td{background:#fff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.1)}.privacy_requests tbody .has-request-results td{box-shadow:none}.privacy_requests .next_steps .button{word-wrap:break-word;white-space:normal}.privacy_requests .status-request-confirmed td,.privacy_requests .status-request-confirmed th{background-color:#f7fcfe;border-right-color:#00a0d2}.privacy_requests .status-request-failed td,.privacy_requests .status-request-failed th{background-color:#fef7f1;border-right-color:#d64d21}.privacy_requests .export_personal_data_failed a{vertical-align:baseline}.status-label{font-weight:600}.status-label.status-request-pending{font-weight:400;font-style:italic;color:#6c7781}.status-label.status-request-failed{color:#a00;font-weight:600}.wp-privacy-request-form{clear:both}.wp-privacy-request-form-field{margin:1.5em 0}.wp-privacy-request-form label{font-weight:600;line-height:1.5;padding-bottom:.5em;display:block}.wp-privacy-request-form input{margin:0}.email-personal-data::before{display:inline-block;font:normal 20px/1 dashicons;margin:3px -2px 0 5px;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:top}.email-personal-data--sending::before{color:#f56e28;content:"\f463";animation:rotation 2s infinite linear}.email-personal-data--sent::before{color:#79ba49;content:"\f147"}@media screen and (max-width:782px){textarea{-webkit-appearance:none}input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:3px 10px;min-height:40px}::-webkit-datetime-edit{line-height:1.875}.widefat tfoot td input[type=checkbox],.widefat th input[type=checkbox],.widefat thead td input[type=checkbox],input[type=checkbox]{-webkit-appearance:none}.widefat tfoot td input[type=checkbox],.widefat th input[type=checkbox],.widefat thead td input[type=checkbox]{margin-bottom:8px}.widefat tfoot td input[type=checkbox]:before,.widefat th input[type=checkbox]:before,.widefat thead td input[type=checkbox]:before,input[type=checkbox]:checked:before{width:1.875rem;height:1.875rem;margin:-.1875rem -.3125rem}input[type=checkbox],input[type=radio]{height:1.5625rem;width:1.5625rem}.wp-admin p input[type=checkbox],.wp-admin p input[type=radio]{margin-top:-.1875rem}input[type=radio]:checked:before{vertical-align:middle;width:.5625rem;height:.5625rem;margin:.4375rem;line-height:.76190476}.wp-upload-form input[type=submit]{margin-top:10px}.wp-admin .form-table select,.wp-core-ui select{min-height:40px;font-size:16px;line-height:1.625;padding:5px 8px 5px 24px}.wp-admin .button-cancel{margin-bottom:0;padding:2px 0;font-size:14px;vertical-align:middle}#adduser .form-field input,#createuser .form-field input{width:100%}.form-table{box-sizing:border-box}.form-table td,.form-table th,.label-responsive{display:block;width:auto;vertical-align:middle}.label-responsive{margin:.5em 0}.export-filters li{margin-bottom:0}.form-table .color-palette td{display:table-cell;width:15px}.form-table table.color-palette{margin-left:10px}input,textarea{font-size:16px}#profile-page .form-table textarea,.form-table span.description,.form-table td input[type=email],.form-table td input[type=password],.form-table td input[type=text],.form-table td select,.form-table td textarea{width:100%;display:block;max-width:none;box-sizing:border-box}.form-table .form-required.form-invalid td:after{float:left;margin:-30px 0 0 3px}.form-table input[type=text].small-text,input[type=number].small-text,input[type=password].small-text,input[type=search].small-text,input[type=text].small-text{width:auto;max-width:4.375em;display:inline;padding:3px 6px;margin:0 3px}#pass-strength-result{width:100%;box-sizing:border-box;padding:8px}p.search-box{float:none;position:absolute;bottom:0;width:98%;height:90px;margin-bottom:20px}p.search-box input[name="s"]{float:none;width:100%;margin-bottom:10px;vertical-align:middle}p.search-box input[type=submit]{margin-bottom:10px}.form-table span.description{display:inline;padding:4px 0 0;line-height:1.4;font-size:14px}.form-table th{padding:10px 0 0 0;border-bottom:0}.form-table td{margin-bottom:0;padding:4px 0 6px 0}.form-table.permalink-structure td code{margin-right:32px;display:inline-block}.form-table.permalink-structure td input[type=text]{margin-right:32px;margin-top:4px;width:96%}.form-table input.regular-text{width:100%}.form-table label{font-size:14px}.background-position-control .button-group>label{font-size:0}.form-table fieldset label{display:block}#local-time,#utc-time{display:block;float:none;margin-top:.5em}.form-field #domain{max-width:none}.wp-pwd{position:relative}#profile-page .form-table #pass1{padding-left:90px}.wp-pwd button.button{background:0 0;border:1px solid transparent;box-shadow:none;line-height:2;margin:0;padding:5px 9px;position:absolute;left:0;top:0;width:2.375rem;height:2.375rem;min-width:40px;min-height:40px}.wp-pwd button.wp-hide-pw{left:2.5rem}.wp-pwd button.button:focus,.wp-pwd button.button:hover{background:0 0}.wp-pwd button.button:active{background:0 0;box-shadow:none;transform:none}.wp-pwd .button .text{display:none}.wp-pwd [type=password],.wp-pwd [type=text]{line-height:2;padding-left:5rem}.wp-cancel-pw .dashicons-no{display:inline-block}.options-general-php input[type=text].small-text{max-width:6.25em;margin:0}.tools-privacy-policy-page form.wp-create-privacy-page{margin-bottom:1em}.tools-privacy-policy-page input#set-page,.tools-privacy-policy-page select{margin:10px 0 0}.tools-privacy-policy-page .wp-create-privacy-page span{display:block;margin-bottom:1em}.tools-privacy-policy-page .wp-create-privacy-page .button{margin-right:0}.wp-list-table.privacy_requests tr:not(.inline-edit-row):not(.no-items) td.column-primary:not(.check-column){display:table-cell}.wp-list-table.privacy_requests.widefat th input,.wp-list-table.privacy_requests.widefat thead td input{margin-right:5px}.wp-privacy-request-form-field input[type=text]{width:100%;margin-bottom:10px;vertical-align:middle}.regular-text{max-width:100%}}@media only screen and (max-width:768px){.form-field input[type=email],.form-field input[type=password],.form-field input[type=text],.form-field select,.form-field textarea{width:99%}.form-wrap .form-field{padding:0}}@media only screen and (max-height:480px),screen and (max-width:450px){.file-editor-warning .notification-dialog,.request-filesystem-credentials-dialog .notification-dialog{width:100%;height:100%;max-height:100%;position:fixed;top:0;margin:0;right:0}}@media screen and (max-width:600px){.color-option{width:49%}}@media only screen and (max-width:320px){.options-general-php .date-time-text.date-time-custom-text{min-width:0;margin-left:.5em}}@keyframes rotation{0%{transform:rotate(0)}100%{transform:rotate(-359deg)}}
\ No newline at end of file
+button,input,select,textarea{box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:inherit}input,textarea{font-size:14px}textarea{overflow:auto;padding:2px 6px;line-height:1.42857143;resize:vertical}label{cursor:pointer}input,select{margin:0 1px}textarea.code{padding:4px 6px 1px 6px}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{box-shadow:0 0 0 transparent;border-radius:4px;border:1px solid #7e8993;background-color:#fff;color:#32373c}input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{padding:0 8px;line-height:2;min-height:30px}::-webkit-datetime-edit{line-height:1.85714286}input[type=checkbox]:focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=radio]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#007cba;box-shadow:0 0 0 1px #007cba;outline:2px solid transparent}input[type=email],input[type=url]{direction:ltr}input[type=checkbox],input[type=radio]{border:1px solid #7e8993;border-radius:4px;background:#fff;color:#555;clear:none;cursor:pointer;display:inline-block;line-height:0;height:1rem;margin:-.25rem 0 0 .25rem;outline:0;padding:0!important;text-align:center;vertical-align:middle;width:1rem;min-width:1rem;-webkit-appearance:none;box-shadow:inset 0 1px 2px rgba(0,0,0,.1);transition:.05s border-color ease-in-out}input[type=radio]:checked+label:before{color:#82878c}.wp-core-ui input[type=reset]:active,.wp-core-ui input[type=reset]:hover{color:#006799}.wp-admin p input[type=checkbox],.wp-admin p input[type=radio],td>input[type=checkbox]{margin-top:0}.wp-admin p label input[type=checkbox]{margin-top:-4px}.wp-admin p label input[type=radio]{margin-top:-2px}input[type=radio]{border-radius:50%;margin-left:.25rem;line-height:.71428571}input[type=checkbox]:checked::before,input[type=radio]:checked::before{float:right;display:inline-block;vertical-align:middle;width:1rem;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}input[type=checkbox]:checked::before{content:url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%231e8cbe%27%2F%3E%3C%2Fsvg%3E);margin:-.1875rem -.25rem 0 0;height:1.3125rem;width:1.3125rem}input[type=radio]:checked::before{content:"";border-radius:50%;width:.5rem;height:.5rem;margin:.1875rem;background-color:#1e8cbe;line-height:1.14285714}@-moz-document url-prefix(){.form-table input.tog,input[type=checkbox],input[type=radio]{margin-bottom:-1px}}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-decoration{display:none}.wp-admin input[type=file]{padding:3px 0;cursor:pointer}input.readonly,input[readonly],textarea.readonly,textarea[readonly]{background-color:#eee}::-webkit-input-placeholder{color:#72777c}::-moz-placeholder{color:#72777c;opacity:1}:-ms-input-placeholder{color:#72777c}.form-invalid input,.form-invalid input:focus,.form-invalid select,.form-invalid select:focus{border-color:#dc3232!important;box-shadow:0 0 2px rgba(204,0,0,.8)}.form-table .form-required.form-invalid td:after{content:"\f534";font:normal 20px/1 dashicons;color:#dc3232;margin-right:-25px;vertical-align:middle}.form-table .form-required.user-pass1-wrap.form-invalid td:after{content:""}.form-table .form-required.user-pass1-wrap.form-invalid .password-input-wrapper:after{content:"\f534";font:normal 20px/1 dashicons;color:#dc3232;margin:0 -29px 0 6px;vertical-align:middle}.form-input-tip{color:#666}input.disabled,input:disabled,select.disabled,select:disabled,textarea.disabled,textarea:disabled{background:rgba(255,255,255,.5);border-color:rgba(222,222,222,.75);box-shadow:inset 0 1px 2px rgba(0,0,0,.04);color:rgba(51,51,51,.5)}input[type=file].disabled,input[type=file]:disabled,input[type=range].disabled,input[type=range]:disabled{background:0 0;box-shadow:none;cursor:default}input[type=checkbox].disabled,input[type=checkbox].disabled:checked:before,input[type=checkbox]:disabled,input[type=checkbox]:disabled:checked:before,input[type=radio].disabled,input[type=radio].disabled:checked:before,input[type=radio]:disabled,input[type=radio]:disabled:checked:before{opacity:.7}.wp-core-ui select{font-size:14px;line-height:2;color:#32373c;border-color:#7e8993;box-shadow:none;border-radius:3px;padding:0 8px 0 24px;min-height:30px;max-width:25rem;-webkit-appearance:none;background:#fff url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E') no-repeat left 5px top 55%;background-size:16px 16px;cursor:pointer;vertical-align:middle}.wp-core-ui select:hover{color:#007cba}.wp-core-ui select:focus{border-color:#007cba;color:#016087;box-shadow:0 0 0 1px #007cba}.wp-core-ui select:active{border-color:#999;box-shadow:none}.wp-core-ui select.disabled,.wp-core-ui select:disabled{color:#a0a5aa;border-color:#ddd;background-color:#f7f7f7;background-image:url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23a0a5aa%22%2F%3E%3C%2Fsvg%3E');box-shadow:none;text-shadow:0 1px 0 #fff;cursor:default;transform:none}.wp-core-ui select:-moz-focusring{color:transparent;text-shadow:0 0 0 #016087}.wp-core-ui select::-ms-value{background:0 0;color:#555}.wp-core-ui select:hover::-ms-value{color:#007cba}.wp-core-ui select:focus::-ms-value{color:#016087}.wp-core-ui select.disabled::-ms-value,.wp-core-ui select:disabled::-ms-value{color:#a0a5aa}.wp-core-ui select::-ms-expand{display:none}.wp-admin .button-cancel{display:inline-block;min-height:28px;padding:0 5px;line-height:2}.meta-box-sortables select{max-width:100%}.meta-box-sortables input{vertical-align:middle}.misc-pub-post-status select{margin-top:0}.wp-core-ui select[multiple]{height:auto;padding-left:8px;background:#fff}.submit{padding:1.5em 0;margin:5px 0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border:none}form p.submit a.cancel:hover{text-decoration:none}p.submit{text-align:right;max-width:100%;margin-top:20px;padding-top:10px}.textright p.submit{border:none;text-align:left}table.form-table+input+input+p.submit,table.form-table+input+p.submit,table.form-table+p.submit{border-top:none;padding-top:0}#major-publishing-actions input,#minor-publishing-actions .preview,#minor-publishing-actions input{text-align:center}input.all-options,textarea.all-options{width:250px}input.large-text,textarea.large-text{width:99%}.regular-text{width:25em}input.small-text{width:50px;padding:0 6px}label input.small-text{margin-top:-4px}input[type=number].small-text{width:65px;padding-left:0}input.tiny-text{width:35px}input[type=number].tiny-text{width:45px;padding-left:0}#doaction,#doaction2,#post-query-submit{margin:0 0 0 8px}.tablenav .actions select{float:right;margin-left:6px;max-width:12.5rem}#timezone_string option{margin-right:1em}.wp-cancel-pw>.dashicons,.wp-hide-pw>.dashicons{position:relative;top:3px;width:1.25rem;height:1.25rem;top:.25rem;font-size:20px}.wp-cancel-pw .dashicons-no{display:none}#your-profile label+a,label{vertical-align:middle}#your-profile label+a,fieldset label{vertical-align:middle}.options-media-php [for*="_size_"]{min-width:10em;vertical-align:baseline}.options-media-php .small-text[name*="_size_"]{margin:0 0 1em}#misc-publishing-actions label{vertical-align:baseline}#pass-strength-result{background-color:#eee;border:1px solid #ddd;color:#23282d;margin:-1px 1px 5px;padding:3px 5px;text-align:center;width:25em;box-sizing:border-box;opacity:0}#pass-strength-result.short{background-color:#f1adad;border-color:#e35b5b;opacity:1}#pass-strength-result.bad{background-color:#fbc5a9;border-color:#f78b53;opacity:1}#pass-strength-result.good{background-color:#ffe399;border-color:#ffc733;opacity:1}#pass-strength-result.strong{background-color:#c1e1b9;border-color:#83c373;opacity:1}#pass1-text.short,#pass1.short{border-color:#e35b5b}#pass1-text.bad,#pass1.bad{border-color:#f78b53}#pass1-text.good,#pass1.good{border-color:#ffc733}#pass1-text.strong,#pass1.strong{border-color:#83c373}.pw-weak{display:none}.indicator-hint{padding-top:8px}.wp-pwd [type=password],.wp-pwd [type=text]{margin-bottom:0;min-height:30px}.wp-pwd input::-ms-reveal{display:none}#pass1-text,.show-password #pass1{display:none}#pass1-text::-ms-clear{display:none}.show-password #pass1-text{display:inline-block}p.search-box{float:left;margin:0}.network-admin.themes-php p.search-box{clear:right}.search-box input[name="s"],.tablenav .search-plugins input[name="s"],.tagsdiv .newtag{float:right;margin:0 0 0 4px}.js.plugins-php .search-box .wp-filter-search{margin:0;width:280px}input[type=email].ui-autocomplete-loading,input[type=text].ui-autocomplete-loading{background-image:url(../images/loading.gif);background-repeat:no-repeat;background-position:left center;visibility:visible}input.ui-autocomplete-input.open{border-bottom-color:transparent}ul#add-to-blog-users{margin:0 14px 0 0}.ui-autocomplete{padding:0;margin:0;list-style:none;position:absolute;z-index:10000;border:1px solid #5b9dd9;box-shadow:0 1px 2px rgba(30,140,190,.8);background-color:#fff}.ui-autocomplete li{margin-bottom:0;padding:4px 10px;white-space:nowrap;text-align:right;cursor:pointer}.ui-autocomplete .ui-state-focus{background-color:#ddd}.wp-tags-autocomplete .ui-state-focus{background-color:#0073aa;color:#fff}.form-table{border-collapse:collapse;margin-top:.5em;width:100%;clear:both}.form-table,.form-table td,.form-table td p,.form-table th{font-size:14px}.form-table td{margin-bottom:9px;padding:15px 10px;line-height:1.3;vertical-align:middle}.form-table th,.form-wrap label{color:#23282d;font-weight:400;text-shadow:none;vertical-align:baseline}.form-table th{vertical-align:top;text-align:right;padding:20px 0 20px 10px;width:200px;line-height:1.3;font-weight:600}.form-table .td-full,.form-table th.th-full{width:auto;padding:20px 0 20px 10px;font-weight:400}.form-table td p{margin-top:4px;margin-bottom:0}.form-table .date-time-doc{margin-top:1em}.form-table p.timezone-info{margin:1em 0}.form-table td fieldset label{margin:.35em 0 .5em!important;display:inline-block}.form-table td fieldset p label{margin-top:0!important}.form-table td fieldset label,.form-table td fieldset li,.form-table td fieldset p{line-height:1.4}.form-table input.tog,.form-table input[type=radio]{margin-top:-4px;margin-left:4px;float:none}.form-table .pre{padding:8px;margin:0}table.form-table td .updated{font-size:13px}table.form-table td .updated p{font-size:13px;margin:.3em 0}#profile-page .form-table textarea{width:500px;margin-bottom:6px}#profile-page .form-table #rich_editing{margin-left:5px}#your-profile legend{font-size:22px}#display_name{width:15em}#adduser .form-field input,#createuser .form-field input{width:25em}.color-option{display:inline-block;width:24%;padding:5px 15px 15px;box-sizing:border-box;margin-bottom:3px}.color-option.selected,.color-option:hover{background:#ddd}.color-palette{width:100%;border-spacing:0;border-collapse:collapse}.color-palette td{height:20px;padding:0;border:none}.color-option{cursor:pointer}.new-application-password-notice.notice{margin-top:20px;margin-bottom:0}.tool-box .title{margin:8px 0;font-size:18px;font-weight:400;line-height:24px}.label-responsive{vertical-align:middle}#export-filters p{margin:0 0 1em}#export-filters p.submit{margin:7px 0 5px}.card{position:relative;margin-top:20px;padding:.7em 2em 1em;min-width:255px;max-width:520px;border:1px solid #ccd0d4;box-shadow:0 1px 1px rgba(0,0,0,.04);background:#fff;box-sizing:border-box}.pressthis h4{margin:2em 0 1em}.pressthis textarea{width:100%;font-size:1em}#pressthis-code-wrap{overflow:auto}.pressthis-bookmarklet-wrapper{margin:20px 0 8px;vertical-align:top;position:relative;z-index:1}.pressthis-bookmarklet,.pressthis-bookmarklet:active,.pressthis-bookmarklet:focus,.pressthis-bookmarklet:hover{display:inline-block;position:relative;cursor:move;color:#32373c;background:#e5e5e5;border-radius:5px;border:1px solid #b4b9be;font-style:normal;line-height:16px;font-size:14px;text-decoration:none}.pressthis-bookmarklet:active{outline:0}.pressthis-bookmarklet:after{content:"";width:70%;height:55%;z-index:-1;position:absolute;left:10px;bottom:9px;background:0 0;transform:skew(-20deg) rotate(-6deg);box-shadow:0 10px 8px rgba(0,0,0,.6)}.pressthis-bookmarklet:hover:after{transform:skew(-20deg) rotate(-9deg);box-shadow:0 10px 8px rgba(0,0,0,.7)}.pressthis-bookmarklet span{display:inline-block;margin:0 0 0;padding:0 9px 8px 12px}.pressthis-bookmarklet span:before{color:#72777c;font:normal 20px/1 dashicons;content:"\f157";position:relative;display:inline-block;top:4px;margin-left:4px}.pressthis-js-toggle{margin-right:10px;padding:0;height:auto;vertical-align:top}.pressthis-js-toggle.button.button{margin-right:10px;padding:0;height:auto;vertical-align:top}.pressthis-js-toggle .dashicons{margin:5px 7px 6px 8px;color:#555d66}.timezone-info code{white-space:nowrap}.defaultavatarpicker .avatar{margin:2px 0;vertical-align:middle}.options-general-php .date-time-text{display:inline-block;min-width:10em}.options-general-php input.small-text{width:56px;margin:-2px 0}.options-general-php .spinner{float:none;margin:-3px 3px 0}.options-general-php .language-install-spinner,.settings-php .language-install-spinner{display:inline-block;float:none;margin:-3px 5px 0;vertical-align:middle}.form-table.permalink-structure .available-structure-tags li{float:right;margin-left:5px}.setup-php textarea{max-width:100%}.form-field #site-address{max-width:25em}.form-field #domain{max-width:22em}.form-field #admin-email,.form-field #blog_last_updated,.form-field #blog_registered,.form-field #path,.form-field #site-title{max-width:25em}.form-field #path{margin-bottom:5px}#search-sites,#search-users{max-width:60%}.request-filesystem-credentials-dialog{display:none;visibility:visible}.request-filesystem-credentials-dialog .notification-dialog{top:10%;max-height:85%}.request-filesystem-credentials-dialog-content{margin:25px}#request-filesystem-credentials-title{font-size:1.3em;margin:1em 0}.request-filesystem-credentials-form legend{font-size:1em;padding:1.33em 0;font-weight:600}.request-filesystem-credentials-form input[type=password],.request-filesystem-credentials-form input[type=text]{display:block}.request-filesystem-credentials-dialog input[type=password],.request-filesystem-credentials-dialog input[type=text]{width:100%}.request-filesystem-credentials-form .field-title{font-weight:600}.request-filesystem-credentials-dialog label[for=hostname],.request-filesystem-credentials-dialog label[for=private_key],.request-filesystem-credentials-dialog label[for=public_key]{display:block;margin-bottom:1em}.request-filesystem-credentials-dialog .ftp-password,.request-filesystem-credentials-dialog .ftp-username{float:right;width:48%}.request-filesystem-credentials-dialog .ftp-password{margin-right:4%}.request-filesystem-credentials-dialog .request-filesystem-credentials-action-buttons{text-align:left}.request-filesystem-credentials-dialog label[for=ftp]{margin-left:10px}.request-filesystem-credentials-dialog #auth-keys-desc{margin-bottom:0}#request-filesystem-credentials-dialog .button:not(:last-child){margin-left:10px}#request-filesystem-credentials-form .cancel-button{display:none}#request-filesystem-credentials-dialog .cancel-button{display:inline}.request-filesystem-credentials-dialog .ftp-password,.request-filesystem-credentials-dialog .ftp-username{float:none;width:auto}.request-filesystem-credentials-dialog .ftp-username{margin-bottom:1em}.request-filesystem-credentials-dialog .ftp-password{margin:0}.request-filesystem-credentials-dialog .ftp-password em{color:#888}.request-filesystem-credentials-dialog label{display:block;line-height:1.5;margin-bottom:1em}.request-filesystem-credentials-form legend{padding-bottom:0}.request-filesystem-credentials-form #ssh-keys legend{font-size:1.3em}.request-filesystem-credentials-form .notice{margin:0 0 20px 0;clear:both}.tools-privacy-policy-page form{margin-bottom:1.3em}.tools-privacy-policy-page input.button,.tools-privacy-policy-page select{margin:0 6px 0 1px}.tools-privacy-edit{margin:1.5em 0}.tools-privacy-policy-page span{line-height:2}.privacy_requests .column-email{width:40%}.privacy_requests .column-type{text-align:center}.privacy_requests tfoot td:first-child,.privacy_requests thead td:first-child{border-right:4px solid #fff}.privacy_requests tbody th{border-right:4px solid #fff;background:#fff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.1)}.privacy_requests .row-actions{color:#72777c}.privacy_requests .row-actions.processing{position:static}.privacy_requests tbody .has-request-results th{box-shadow:none}.privacy_requests tbody .request-results th .notice{margin:0 0 5px}.privacy_requests tbody td{background:#fff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.1)}.privacy_requests tbody .has-request-results td{box-shadow:none}.privacy_requests .next_steps .button{word-wrap:break-word;white-space:normal}.privacy_requests .status-request-confirmed td,.privacy_requests .status-request-confirmed th{background-color:#f7fcfe;border-right-color:#00a0d2}.privacy_requests .status-request-failed td,.privacy_requests .status-request-failed th{background-color:#fef7f1;border-right-color:#d64d21}.privacy_requests .export_personal_data_failed a{vertical-align:baseline}.status-label{font-weight:600}.status-label.status-request-pending{font-weight:400;font-style:italic;color:#6c7781}.status-label.status-request-failed{color:#a00;font-weight:600}.wp-privacy-request-form{clear:both}.wp-privacy-request-form-field{margin:1.5em 0}.wp-privacy-request-form label{font-weight:600;line-height:1.5;padding-bottom:.5em;display:block}.wp-privacy-request-form input{margin:0}.email-personal-data::before{display:inline-block;font:normal 20px/1 dashicons;margin:3px -2px 0 5px;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:top}.email-personal-data--sending::before{color:#f56e28;content:"\f463";animation:rotation 2s infinite linear}.email-personal-data--sent::before{color:#79ba49;content:"\f147"}@media screen and (max-width:782px){textarea{-webkit-appearance:none}input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:3px 10px;min-height:40px}::-webkit-datetime-edit{line-height:1.875}.widefat tfoot td input[type=checkbox],.widefat th input[type=checkbox],.widefat thead td input[type=checkbox],input[type=checkbox]{-webkit-appearance:none}.widefat tfoot td input[type=checkbox],.widefat th input[type=checkbox],.widefat thead td input[type=checkbox]{margin-bottom:8px}.widefat tfoot td input[type=checkbox]:before,.widefat th input[type=checkbox]:before,.widefat thead td input[type=checkbox]:before,input[type=checkbox]:checked:before{width:1.875rem;height:1.875rem;margin:-.1875rem -.3125rem}input[type=checkbox],input[type=radio]{height:1.5625rem;width:1.5625rem}.wp-admin p input[type=checkbox],.wp-admin p input[type=radio]{margin-top:-.1875rem}input[type=radio]:checked:before{vertical-align:middle;width:.5625rem;height:.5625rem;margin:.4375rem;line-height:.76190476}.wp-upload-form input[type=submit]{margin-top:10px}.wp-admin .form-table select,.wp-core-ui select{min-height:40px;font-size:16px;line-height:1.625;padding:5px 8px 5px 24px}.wp-admin .button-cancel{margin-bottom:0;padding:2px 0;font-size:14px;vertical-align:middle}#adduser .form-field input,#createuser .form-field input{width:100%}.form-table{box-sizing:border-box}.form-table td,.form-table th,.label-responsive{display:block;width:auto;vertical-align:middle}.label-responsive{margin:.5em 0}.export-filters li{margin-bottom:0}.form-table .color-palette td{display:table-cell;width:15px}.form-table table.color-palette{margin-left:10px}input,textarea{font-size:16px}#profile-page .form-table textarea,.form-table span.description,.form-table td input[type=email],.form-table td input[type=password],.form-table td input[type=text],.form-table td select,.form-table td textarea{width:100%;display:block;max-width:none;box-sizing:border-box}.form-table .form-required.form-invalid td:after{float:left;margin:-30px 0 0 3px}.form-table input[type=text].small-text,input[type=number].small-text,input[type=password].small-text,input[type=search].small-text,input[type=text].small-text{width:auto;max-width:4.375em;display:inline;padding:3px 6px;margin:0 3px}#pass-strength-result{width:100%;box-sizing:border-box;padding:8px}p.search-box{float:none;position:absolute;bottom:0;width:98%;height:90px;margin-bottom:20px}p.search-box input[name="s"]{float:none;width:100%;margin-bottom:10px;vertical-align:middle}p.search-box input[type=submit]{margin-bottom:10px}.form-table span.description{display:inline;padding:4px 0 0;line-height:1.4;font-size:14px}.form-table th{padding:10px 0 0 0;border-bottom:0}.form-table td{margin-bottom:0;padding:4px 0 6px 0}.form-table.permalink-structure td code{margin-right:32px;display:inline-block}.form-table.permalink-structure td input[type=text]{margin-right:32px;margin-top:4px;width:96%}.form-table input.regular-text{width:100%}.form-table label{font-size:14px}.background-position-control .button-group>label{font-size:0}.form-table fieldset label{display:block}#local-time,#utc-time{display:block;float:none;margin-top:.5em}.form-field #domain{max-width:none}.wp-pwd{position:relative}#profile-page .form-table #pass1{padding-left:90px}.wp-pwd button.button{background:0 0;border:1px solid transparent;box-shadow:none;line-height:2;margin:0;padding:5px 9px;position:absolute;left:0;top:0;width:2.375rem;height:2.375rem;min-width:40px;min-height:40px}.wp-pwd button.wp-hide-pw{left:2.5rem}.wp-pwd button.button:focus,.wp-pwd button.button:hover{background:0 0}.wp-pwd button.button:active{background:0 0;box-shadow:none;transform:none}.wp-pwd .button .text{display:none}.wp-pwd [type=password],.wp-pwd [type=text]{line-height:2;padding-left:5rem}.wp-cancel-pw .dashicons-no{display:inline-block}.options-general-php input[type=text].small-text{max-width:6.25em;margin:0}.tools-privacy-policy-page form.wp-create-privacy-page{margin-bottom:1em}.tools-privacy-policy-page input#set-page,.tools-privacy-policy-page select{margin:10px 0 0}.tools-privacy-policy-page .wp-create-privacy-page span{display:block;margin-bottom:1em}.tools-privacy-policy-page .wp-create-privacy-page .button{margin-right:0}.wp-list-table.privacy_requests tr:not(.inline-edit-row):not(.no-items) td.column-primary:not(.check-column){display:table-cell}.wp-list-table.privacy_requests.widefat th input,.wp-list-table.privacy_requests.widefat thead td input{margin-right:5px}.wp-privacy-request-form-field input[type=text]{width:100%;margin-bottom:10px;vertical-align:middle}.regular-text{max-width:100%}}@media only screen and (max-width:768px){.form-field input[type=email],.form-field input[type=password],.form-field input[type=text],.form-field select,.form-field textarea{width:99%}.form-wrap .form-field{padding:0}}@media only screen and (max-height:480px),screen and (max-width:450px){.file-editor-warning .notification-dialog,.request-filesystem-credentials-dialog .notification-dialog{width:100%;height:100%;max-height:100%;position:fixed;top:0;margin:0;right:0}}@media screen and (max-width:600px){.color-option{width:49%}}@media only screen and (max-width:320px){.options-general-php .date-time-text.date-time-custom-text{min-width:0;margin-left:.5em}}@keyframes rotation{0%{transform:rotate(0)}100%{transform:rotate(-359deg)}}
\ No newline at end of file
diff --git a/wp-admin/css/forms.css b/wp-admin/css/forms.css
index 0aa63f1f52..2f03173491 100644
--- a/wp-admin/css/forms.css
+++ b/wp-admin/css/forms.css
@@ -756,7 +756,7 @@ ul#add-to-blog-users {
display: inline-block;
}
-.form-table td fieldset p label {
+.form-table td fieldset p label {
margin-top: 0 !important;
}
@@ -841,6 +841,11 @@ table.form-table td .updated p {
cursor: pointer;
}
+.new-application-password-notice.notice {
+ margin-top: 20px;
+ margin-bottom: 0;
+}
+
/*------------------------------------------------------------------------------
19.0 - Tools
------------------------------------------------------------------------------*/
diff --git a/wp-admin/css/forms.min.css b/wp-admin/css/forms.min.css
index 6b17f677d1..4e1b839cfc 100644
--- a/wp-admin/css/forms.min.css
+++ b/wp-admin/css/forms.min.css
@@ -1,2 +1,2 @@
/*! This file is auto-generated */
-button,input,select,textarea{box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:inherit}input,textarea{font-size:14px}textarea{overflow:auto;padding:2px 6px;line-height:1.42857143;resize:vertical}label{cursor:pointer}input,select{margin:0 1px}textarea.code{padding:4px 6px 1px 6px}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{box-shadow:0 0 0 transparent;border-radius:4px;border:1px solid #7e8993;background-color:#fff;color:#32373c}input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{padding:0 8px;line-height:2;min-height:30px}::-webkit-datetime-edit{line-height:1.85714286}input[type=checkbox]:focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=radio]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#007cba;box-shadow:0 0 0 1px #007cba;outline:2px solid transparent}input[type=email],input[type=url]{direction:ltr}input[type=checkbox],input[type=radio]{border:1px solid #7e8993;border-radius:4px;background:#fff;color:#555;clear:none;cursor:pointer;display:inline-block;line-height:0;height:1rem;margin:-.25rem .25rem 0 0;outline:0;padding:0!important;text-align:center;vertical-align:middle;width:1rem;min-width:1rem;-webkit-appearance:none;box-shadow:inset 0 1px 2px rgba(0,0,0,.1);transition:.05s border-color ease-in-out}input[type=radio]:checked+label:before{color:#82878c}.wp-core-ui input[type=reset]:active,.wp-core-ui input[type=reset]:hover{color:#006799}.wp-admin p input[type=checkbox],.wp-admin p input[type=radio],td>input[type=checkbox]{margin-top:0}.wp-admin p label input[type=checkbox]{margin-top:-4px}.wp-admin p label input[type=radio]{margin-top:-2px}input[type=radio]{border-radius:50%;margin-right:.25rem;line-height:.71428571}input[type=checkbox]:checked::before,input[type=radio]:checked::before{float:left;display:inline-block;vertical-align:middle;width:1rem;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}input[type=checkbox]:checked::before{content:url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%231e8cbe%27%2F%3E%3C%2Fsvg%3E);margin:-.1875rem 0 0 -.25rem;height:1.3125rem;width:1.3125rem}input[type=radio]:checked::before{content:"";border-radius:50%;width:.5rem;height:.5rem;margin:.1875rem;background-color:#1e8cbe;line-height:1.14285714}@-moz-document url-prefix(){.form-table input.tog,input[type=checkbox],input[type=radio]{margin-bottom:-1px}}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-decoration{display:none}.wp-admin input[type=file]{padding:3px 0;cursor:pointer}input.readonly,input[readonly],textarea.readonly,textarea[readonly]{background-color:#eee}::-webkit-input-placeholder{color:#72777c}::-moz-placeholder{color:#72777c;opacity:1}:-ms-input-placeholder{color:#72777c}.form-invalid input,.form-invalid input:focus,.form-invalid select,.form-invalid select:focus{border-color:#dc3232!important;box-shadow:0 0 2px rgba(204,0,0,.8)}.form-table .form-required.form-invalid td:after{content:"\f534";font:normal 20px/1 dashicons;color:#dc3232;margin-left:-25px;vertical-align:middle}.form-table .form-required.user-pass1-wrap.form-invalid td:after{content:""}.form-table .form-required.user-pass1-wrap.form-invalid .password-input-wrapper:after{content:"\f534";font:normal 20px/1 dashicons;color:#dc3232;margin:0 6px 0 -29px;vertical-align:middle}.form-input-tip{color:#666}input.disabled,input:disabled,select.disabled,select:disabled,textarea.disabled,textarea:disabled{background:rgba(255,255,255,.5);border-color:rgba(222,222,222,.75);box-shadow:inset 0 1px 2px rgba(0,0,0,.04);color:rgba(51,51,51,.5)}input[type=file].disabled,input[type=file]:disabled,input[type=range].disabled,input[type=range]:disabled{background:0 0;box-shadow:none;cursor:default}input[type=checkbox].disabled,input[type=checkbox].disabled:checked:before,input[type=checkbox]:disabled,input[type=checkbox]:disabled:checked:before,input[type=radio].disabled,input[type=radio].disabled:checked:before,input[type=radio]:disabled,input[type=radio]:disabled:checked:before{opacity:.7}.wp-core-ui select{font-size:14px;line-height:2;color:#32373c;border-color:#7e8993;box-shadow:none;border-radius:3px;padding:0 24px 0 8px;min-height:30px;max-width:25rem;-webkit-appearance:none;background:#fff url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E') no-repeat right 5px top 55%;background-size:16px 16px;cursor:pointer;vertical-align:middle}.wp-core-ui select:hover{color:#007cba}.wp-core-ui select:focus{border-color:#007cba;color:#016087;box-shadow:0 0 0 1px #007cba}.wp-core-ui select:active{border-color:#999;box-shadow:none}.wp-core-ui select.disabled,.wp-core-ui select:disabled{color:#a0a5aa;border-color:#ddd;background-color:#f7f7f7;background-image:url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23a0a5aa%22%2F%3E%3C%2Fsvg%3E');box-shadow:none;text-shadow:0 1px 0 #fff;cursor:default;transform:none}.wp-core-ui select:-moz-focusring{color:transparent;text-shadow:0 0 0 #016087}.wp-core-ui select::-ms-value{background:0 0;color:#555}.wp-core-ui select:hover::-ms-value{color:#007cba}.wp-core-ui select:focus::-ms-value{color:#016087}.wp-core-ui select.disabled::-ms-value,.wp-core-ui select:disabled::-ms-value{color:#a0a5aa}.wp-core-ui select::-ms-expand{display:none}.wp-admin .button-cancel{display:inline-block;min-height:28px;padding:0 5px;line-height:2}.meta-box-sortables select{max-width:100%}.meta-box-sortables input{vertical-align:middle}.misc-pub-post-status select{margin-top:0}.wp-core-ui select[multiple]{height:auto;padding-right:8px;background:#fff}.submit{padding:1.5em 0;margin:5px 0;border-bottom-left-radius:3px;border-bottom-right-radius:3px;border:none}form p.submit a.cancel:hover{text-decoration:none}p.submit{text-align:left;max-width:100%;margin-top:20px;padding-top:10px}.textright p.submit{border:none;text-align:right}table.form-table+input+input+p.submit,table.form-table+input+p.submit,table.form-table+p.submit{border-top:none;padding-top:0}#major-publishing-actions input,#minor-publishing-actions .preview,#minor-publishing-actions input{text-align:center}input.all-options,textarea.all-options{width:250px}input.large-text,textarea.large-text{width:99%}.regular-text{width:25em}input.small-text{width:50px;padding:0 6px}label input.small-text{margin-top:-4px}input[type=number].small-text{width:65px;padding-right:0}input.tiny-text{width:35px}input[type=number].tiny-text{width:45px;padding-right:0}#doaction,#doaction2,#post-query-submit{margin:0 8px 0 0}.tablenav .actions select{float:left;margin-right:6px;max-width:12.5rem}#timezone_string option{margin-left:1em}.wp-cancel-pw>.dashicons,.wp-hide-pw>.dashicons{position:relative;top:3px;width:1.25rem;height:1.25rem;top:.25rem;font-size:20px}.wp-cancel-pw .dashicons-no{display:none}#your-profile label+a,label{vertical-align:middle}#your-profile label+a,fieldset label{vertical-align:middle}.options-media-php [for*="_size_"]{min-width:10em;vertical-align:baseline}.options-media-php .small-text[name*="_size_"]{margin:0 0 1em}#misc-publishing-actions label{vertical-align:baseline}#pass-strength-result{background-color:#eee;border:1px solid #ddd;color:#23282d;margin:-1px 1px 5px;padding:3px 5px;text-align:center;width:25em;box-sizing:border-box;opacity:0}#pass-strength-result.short{background-color:#f1adad;border-color:#e35b5b;opacity:1}#pass-strength-result.bad{background-color:#fbc5a9;border-color:#f78b53;opacity:1}#pass-strength-result.good{background-color:#ffe399;border-color:#ffc733;opacity:1}#pass-strength-result.strong{background-color:#c1e1b9;border-color:#83c373;opacity:1}#pass1-text.short,#pass1.short{border-color:#e35b5b}#pass1-text.bad,#pass1.bad{border-color:#f78b53}#pass1-text.good,#pass1.good{border-color:#ffc733}#pass1-text.strong,#pass1.strong{border-color:#83c373}.pw-weak{display:none}.indicator-hint{padding-top:8px}.wp-pwd [type=password],.wp-pwd [type=text]{margin-bottom:0;min-height:30px}.wp-pwd input::-ms-reveal{display:none}#pass1-text,.show-password #pass1{display:none}#pass1-text::-ms-clear{display:none}.show-password #pass1-text{display:inline-block}p.search-box{float:right;margin:0}.network-admin.themes-php p.search-box{clear:left}.search-box input[name="s"],.tablenav .search-plugins input[name="s"],.tagsdiv .newtag{float:left;margin:0 4px 0 0}.js.plugins-php .search-box .wp-filter-search{margin:0;width:280px}input[type=email].ui-autocomplete-loading,input[type=text].ui-autocomplete-loading{background-image:url(../images/loading.gif);background-repeat:no-repeat;background-position:right center;visibility:visible}input.ui-autocomplete-input.open{border-bottom-color:transparent}ul#add-to-blog-users{margin:0 0 0 14px}.ui-autocomplete{padding:0;margin:0;list-style:none;position:absolute;z-index:10000;border:1px solid #5b9dd9;box-shadow:0 1px 2px rgba(30,140,190,.8);background-color:#fff}.ui-autocomplete li{margin-bottom:0;padding:4px 10px;white-space:nowrap;text-align:left;cursor:pointer}.ui-autocomplete .ui-state-focus{background-color:#ddd}.wp-tags-autocomplete .ui-state-focus{background-color:#0073aa;color:#fff}.form-table{border-collapse:collapse;margin-top:.5em;width:100%;clear:both}.form-table,.form-table td,.form-table td p,.form-table th{font-size:14px}.form-table td{margin-bottom:9px;padding:15px 10px;line-height:1.3;vertical-align:middle}.form-table th,.form-wrap label{color:#23282d;font-weight:400;text-shadow:none;vertical-align:baseline}.form-table th{vertical-align:top;text-align:left;padding:20px 10px 20px 0;width:200px;line-height:1.3;font-weight:600}.form-table .td-full,.form-table th.th-full{width:auto;padding:20px 10px 20px 0;font-weight:400}.form-table td p{margin-top:4px;margin-bottom:0}.form-table .date-time-doc{margin-top:1em}.form-table p.timezone-info{margin:1em 0}.form-table td fieldset label{margin:.35em 0 .5em!important;display:inline-block}.form-table td fieldset p label{margin-top:0!important}.form-table td fieldset label,.form-table td fieldset li,.form-table td fieldset p{line-height:1.4}.form-table input.tog,.form-table input[type=radio]{margin-top:-4px;margin-right:4px;float:none}.form-table .pre{padding:8px;margin:0}table.form-table td .updated{font-size:13px}table.form-table td .updated p{font-size:13px;margin:.3em 0}#profile-page .form-table textarea{width:500px;margin-bottom:6px}#profile-page .form-table #rich_editing{margin-right:5px}#your-profile legend{font-size:22px}#display_name{width:15em}#adduser .form-field input,#createuser .form-field input{width:25em}.color-option{display:inline-block;width:24%;padding:5px 15px 15px;box-sizing:border-box;margin-bottom:3px}.color-option.selected,.color-option:hover{background:#ddd}.color-palette{width:100%;border-spacing:0;border-collapse:collapse}.color-palette td{height:20px;padding:0;border:none}.color-option{cursor:pointer}.tool-box .title{margin:8px 0;font-size:18px;font-weight:400;line-height:24px}.label-responsive{vertical-align:middle}#export-filters p{margin:0 0 1em}#export-filters p.submit{margin:7px 0 5px}.card{position:relative;margin-top:20px;padding:.7em 2em 1em;min-width:255px;max-width:520px;border:1px solid #ccd0d4;box-shadow:0 1px 1px rgba(0,0,0,.04);background:#fff;box-sizing:border-box}.pressthis h4{margin:2em 0 1em}.pressthis textarea{width:100%;font-size:1em}#pressthis-code-wrap{overflow:auto}.pressthis-bookmarklet-wrapper{margin:20px 0 8px;vertical-align:top;position:relative;z-index:1}.pressthis-bookmarklet,.pressthis-bookmarklet:active,.pressthis-bookmarklet:focus,.pressthis-bookmarklet:hover{display:inline-block;position:relative;cursor:move;color:#32373c;background:#e5e5e5;border-radius:5px;border:1px solid #b4b9be;font-style:normal;line-height:16px;font-size:14px;text-decoration:none}.pressthis-bookmarklet:active{outline:0}.pressthis-bookmarklet:after{content:"";width:70%;height:55%;z-index:-1;position:absolute;right:10px;bottom:9px;background:0 0;transform:skew(20deg) rotate(6deg);box-shadow:0 10px 8px rgba(0,0,0,.6)}.pressthis-bookmarklet:hover:after{transform:skew(20deg) rotate(9deg);box-shadow:0 10px 8px rgba(0,0,0,.7)}.pressthis-bookmarklet span{display:inline-block;margin:0 0 0;padding:0 12px 8px 9px}.pressthis-bookmarklet span:before{color:#72777c;font:normal 20px/1 dashicons;content:"\f157";position:relative;display:inline-block;top:4px;margin-right:4px}.pressthis-js-toggle{margin-left:10px;padding:0;height:auto;vertical-align:top}.pressthis-js-toggle.button.button{margin-left:10px;padding:0;height:auto;vertical-align:top}.pressthis-js-toggle .dashicons{margin:5px 8px 6px 7px;color:#555d66}.timezone-info code{white-space:nowrap}.defaultavatarpicker .avatar{margin:2px 0;vertical-align:middle}.options-general-php .date-time-text{display:inline-block;min-width:10em}.options-general-php input.small-text{width:56px;margin:-2px 0}.options-general-php .spinner{float:none;margin:-3px 3px 0}.options-general-php .language-install-spinner,.settings-php .language-install-spinner{display:inline-block;float:none;margin:-3px 5px 0;vertical-align:middle}.form-table.permalink-structure .available-structure-tags li{float:left;margin-right:5px}.setup-php textarea{max-width:100%}.form-field #site-address{max-width:25em}.form-field #domain{max-width:22em}.form-field #admin-email,.form-field #blog_last_updated,.form-field #blog_registered,.form-field #path,.form-field #site-title{max-width:25em}.form-field #path{margin-bottom:5px}#search-sites,#search-users{max-width:60%}.request-filesystem-credentials-dialog{display:none;visibility:visible}.request-filesystem-credentials-dialog .notification-dialog{top:10%;max-height:85%}.request-filesystem-credentials-dialog-content{margin:25px}#request-filesystem-credentials-title{font-size:1.3em;margin:1em 0}.request-filesystem-credentials-form legend{font-size:1em;padding:1.33em 0;font-weight:600}.request-filesystem-credentials-form input[type=password],.request-filesystem-credentials-form input[type=text]{display:block}.request-filesystem-credentials-dialog input[type=password],.request-filesystem-credentials-dialog input[type=text]{width:100%}.request-filesystem-credentials-form .field-title{font-weight:600}.request-filesystem-credentials-dialog label[for=hostname],.request-filesystem-credentials-dialog label[for=private_key],.request-filesystem-credentials-dialog label[for=public_key]{display:block;margin-bottom:1em}.request-filesystem-credentials-dialog .ftp-password,.request-filesystem-credentials-dialog .ftp-username{float:left;width:48%}.request-filesystem-credentials-dialog .ftp-password{margin-left:4%}.request-filesystem-credentials-dialog .request-filesystem-credentials-action-buttons{text-align:right}.request-filesystem-credentials-dialog label[for=ftp]{margin-right:10px}.request-filesystem-credentials-dialog #auth-keys-desc{margin-bottom:0}#request-filesystem-credentials-dialog .button:not(:last-child){margin-right:10px}#request-filesystem-credentials-form .cancel-button{display:none}#request-filesystem-credentials-dialog .cancel-button{display:inline}.request-filesystem-credentials-dialog .ftp-password,.request-filesystem-credentials-dialog .ftp-username{float:none;width:auto}.request-filesystem-credentials-dialog .ftp-username{margin-bottom:1em}.request-filesystem-credentials-dialog .ftp-password{margin:0}.request-filesystem-credentials-dialog .ftp-password em{color:#888}.request-filesystem-credentials-dialog label{display:block;line-height:1.5;margin-bottom:1em}.request-filesystem-credentials-form legend{padding-bottom:0}.request-filesystem-credentials-form #ssh-keys legend{font-size:1.3em}.request-filesystem-credentials-form .notice{margin:0 0 20px 0;clear:both}.tools-privacy-policy-page form{margin-bottom:1.3em}.tools-privacy-policy-page input.button,.tools-privacy-policy-page select{margin:0 1px 0 6px}.tools-privacy-edit{margin:1.5em 0}.tools-privacy-policy-page span{line-height:2}.privacy_requests .column-email{width:40%}.privacy_requests .column-type{text-align:center}.privacy_requests tfoot td:first-child,.privacy_requests thead td:first-child{border-left:4px solid #fff}.privacy_requests tbody th{border-left:4px solid #fff;background:#fff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.1)}.privacy_requests .row-actions{color:#72777c}.privacy_requests .row-actions.processing{position:static}.privacy_requests tbody .has-request-results th{box-shadow:none}.privacy_requests tbody .request-results th .notice{margin:0 0 5px}.privacy_requests tbody td{background:#fff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.1)}.privacy_requests tbody .has-request-results td{box-shadow:none}.privacy_requests .next_steps .button{word-wrap:break-word;white-space:normal}.privacy_requests .status-request-confirmed td,.privacy_requests .status-request-confirmed th{background-color:#f7fcfe;border-left-color:#00a0d2}.privacy_requests .status-request-failed td,.privacy_requests .status-request-failed th{background-color:#fef7f1;border-left-color:#d64d21}.privacy_requests .export_personal_data_failed a{vertical-align:baseline}.status-label{font-weight:600}.status-label.status-request-pending{font-weight:400;font-style:italic;color:#6c7781}.status-label.status-request-failed{color:#a00;font-weight:600}.wp-privacy-request-form{clear:both}.wp-privacy-request-form-field{margin:1.5em 0}.wp-privacy-request-form label{font-weight:600;line-height:1.5;padding-bottom:.5em;display:block}.wp-privacy-request-form input{margin:0}.email-personal-data::before{display:inline-block;font:normal 20px/1 dashicons;margin:3px 5px 0 -2px;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:top}.email-personal-data--sending::before{color:#f56e28;content:"\f463";animation:rotation 2s infinite linear}.email-personal-data--sent::before{color:#79ba49;content:"\f147"}@media screen and (max-width:782px){textarea{-webkit-appearance:none}input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:3px 10px;min-height:40px}::-webkit-datetime-edit{line-height:1.875}.widefat tfoot td input[type=checkbox],.widefat th input[type=checkbox],.widefat thead td input[type=checkbox],input[type=checkbox]{-webkit-appearance:none}.widefat tfoot td input[type=checkbox],.widefat th input[type=checkbox],.widefat thead td input[type=checkbox]{margin-bottom:8px}.widefat tfoot td input[type=checkbox]:before,.widefat th input[type=checkbox]:before,.widefat thead td input[type=checkbox]:before,input[type=checkbox]:checked:before{width:1.875rem;height:1.875rem;margin:-.1875rem -.3125rem}input[type=checkbox],input[type=radio]{height:1.5625rem;width:1.5625rem}.wp-admin p input[type=checkbox],.wp-admin p input[type=radio]{margin-top:-.1875rem}input[type=radio]:checked:before{vertical-align:middle;width:.5625rem;height:.5625rem;margin:.4375rem;line-height:.76190476}.wp-upload-form input[type=submit]{margin-top:10px}.wp-admin .form-table select,.wp-core-ui select{min-height:40px;font-size:16px;line-height:1.625;padding:5px 24px 5px 8px}.wp-admin .button-cancel{margin-bottom:0;padding:2px 0;font-size:14px;vertical-align:middle}#adduser .form-field input,#createuser .form-field input{width:100%}.form-table{box-sizing:border-box}.form-table td,.form-table th,.label-responsive{display:block;width:auto;vertical-align:middle}.label-responsive{margin:.5em 0}.export-filters li{margin-bottom:0}.form-table .color-palette td{display:table-cell;width:15px}.form-table table.color-palette{margin-right:10px}input,textarea{font-size:16px}#profile-page .form-table textarea,.form-table span.description,.form-table td input[type=email],.form-table td input[type=password],.form-table td input[type=text],.form-table td select,.form-table td textarea{width:100%;display:block;max-width:none;box-sizing:border-box}.form-table .form-required.form-invalid td:after{float:right;margin:-30px 3px 0 0}.form-table input[type=text].small-text,input[type=number].small-text,input[type=password].small-text,input[type=search].small-text,input[type=text].small-text{width:auto;max-width:4.375em;display:inline;padding:3px 6px;margin:0 3px}#pass-strength-result{width:100%;box-sizing:border-box;padding:8px}p.search-box{float:none;position:absolute;bottom:0;width:98%;height:90px;margin-bottom:20px}p.search-box input[name="s"]{float:none;width:100%;margin-bottom:10px;vertical-align:middle}p.search-box input[type=submit]{margin-bottom:10px}.form-table span.description{display:inline;padding:4px 0 0;line-height:1.4;font-size:14px}.form-table th{padding:10px 0 0 0;border-bottom:0}.form-table td{margin-bottom:0;padding:4px 0 6px 0}.form-table.permalink-structure td code{margin-left:32px;display:inline-block}.form-table.permalink-structure td input[type=text]{margin-left:32px;margin-top:4px;width:96%}.form-table input.regular-text{width:100%}.form-table label{font-size:14px}.background-position-control .button-group>label{font-size:0}.form-table fieldset label{display:block}#local-time,#utc-time{display:block;float:none;margin-top:.5em}.form-field #domain{max-width:none}.wp-pwd{position:relative}#profile-page .form-table #pass1{padding-right:90px}.wp-pwd button.button{background:0 0;border:1px solid transparent;box-shadow:none;line-height:2;margin:0;padding:5px 9px;position:absolute;right:0;top:0;width:2.375rem;height:2.375rem;min-width:40px;min-height:40px}.wp-pwd button.wp-hide-pw{right:2.5rem}.wp-pwd button.button:focus,.wp-pwd button.button:hover{background:0 0}.wp-pwd button.button:active{background:0 0;box-shadow:none;transform:none}.wp-pwd .button .text{display:none}.wp-pwd [type=password],.wp-pwd [type=text]{line-height:2;padding-right:5rem}.wp-cancel-pw .dashicons-no{display:inline-block}.options-general-php input[type=text].small-text{max-width:6.25em;margin:0}.tools-privacy-policy-page form.wp-create-privacy-page{margin-bottom:1em}.tools-privacy-policy-page input#set-page,.tools-privacy-policy-page select{margin:10px 0 0}.tools-privacy-policy-page .wp-create-privacy-page span{display:block;margin-bottom:1em}.tools-privacy-policy-page .wp-create-privacy-page .button{margin-left:0}.wp-list-table.privacy_requests tr:not(.inline-edit-row):not(.no-items) td.column-primary:not(.check-column){display:table-cell}.wp-list-table.privacy_requests.widefat th input,.wp-list-table.privacy_requests.widefat thead td input{margin-left:5px}.wp-privacy-request-form-field input[type=text]{width:100%;margin-bottom:10px;vertical-align:middle}.regular-text{max-width:100%}}@media only screen and (max-width:768px){.form-field input[type=email],.form-field input[type=password],.form-field input[type=text],.form-field select,.form-field textarea{width:99%}.form-wrap .form-field{padding:0}}@media only screen and (max-height:480px),screen and (max-width:450px){.file-editor-warning .notification-dialog,.request-filesystem-credentials-dialog .notification-dialog{width:100%;height:100%;max-height:100%;position:fixed;top:0;margin:0;left:0}}@media screen and (max-width:600px){.color-option{width:49%}}@media only screen and (max-width:320px){.options-general-php .date-time-text.date-time-custom-text{min-width:0;margin-right:.5em}}@keyframes rotation{0%{transform:rotate(0)}100%{transform:rotate(359deg)}}
\ No newline at end of file
+button,input,select,textarea{box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:inherit}input,textarea{font-size:14px}textarea{overflow:auto;padding:2px 6px;line-height:1.42857143;resize:vertical}label{cursor:pointer}input,select{margin:0 1px}textarea.code{padding:4px 6px 1px 6px}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{box-shadow:0 0 0 transparent;border-radius:4px;border:1px solid #7e8993;background-color:#fff;color:#32373c}input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{padding:0 8px;line-height:2;min-height:30px}::-webkit-datetime-edit{line-height:1.85714286}input[type=checkbox]:focus,input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=radio]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,select:focus,textarea:focus{border-color:#007cba;box-shadow:0 0 0 1px #007cba;outline:2px solid transparent}input[type=email],input[type=url]{direction:ltr}input[type=checkbox],input[type=radio]{border:1px solid #7e8993;border-radius:4px;background:#fff;color:#555;clear:none;cursor:pointer;display:inline-block;line-height:0;height:1rem;margin:-.25rem .25rem 0 0;outline:0;padding:0!important;text-align:center;vertical-align:middle;width:1rem;min-width:1rem;-webkit-appearance:none;box-shadow:inset 0 1px 2px rgba(0,0,0,.1);transition:.05s border-color ease-in-out}input[type=radio]:checked+label:before{color:#82878c}.wp-core-ui input[type=reset]:active,.wp-core-ui input[type=reset]:hover{color:#006799}.wp-admin p input[type=checkbox],.wp-admin p input[type=radio],td>input[type=checkbox]{margin-top:0}.wp-admin p label input[type=checkbox]{margin-top:-4px}.wp-admin p label input[type=radio]{margin-top:-2px}input[type=radio]{border-radius:50%;margin-right:.25rem;line-height:.71428571}input[type=checkbox]:checked::before,input[type=radio]:checked::before{float:left;display:inline-block;vertical-align:middle;width:1rem;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}input[type=checkbox]:checked::before{content:url(data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2020%2020%27%3E%3Cpath%20d%3D%27M14.83%204.89l1.34.94-5.81%208.38H9.02L5.78%209.67l1.34-1.25%202.57%202.4z%27%20fill%3D%27%231e8cbe%27%2F%3E%3C%2Fsvg%3E);margin:-.1875rem 0 0 -.25rem;height:1.3125rem;width:1.3125rem}input[type=radio]:checked::before{content:"";border-radius:50%;width:.5rem;height:.5rem;margin:.1875rem;background-color:#1e8cbe;line-height:1.14285714}@-moz-document url-prefix(){.form-table input.tog,input[type=checkbox],input[type=radio]{margin-bottom:-1px}}input[type=search]{-webkit-appearance:textfield}input[type=search]::-webkit-search-decoration{display:none}.wp-admin input[type=file]{padding:3px 0;cursor:pointer}input.readonly,input[readonly],textarea.readonly,textarea[readonly]{background-color:#eee}::-webkit-input-placeholder{color:#72777c}::-moz-placeholder{color:#72777c;opacity:1}:-ms-input-placeholder{color:#72777c}.form-invalid input,.form-invalid input:focus,.form-invalid select,.form-invalid select:focus{border-color:#dc3232!important;box-shadow:0 0 2px rgba(204,0,0,.8)}.form-table .form-required.form-invalid td:after{content:"\f534";font:normal 20px/1 dashicons;color:#dc3232;margin-left:-25px;vertical-align:middle}.form-table .form-required.user-pass1-wrap.form-invalid td:after{content:""}.form-table .form-required.user-pass1-wrap.form-invalid .password-input-wrapper:after{content:"\f534";font:normal 20px/1 dashicons;color:#dc3232;margin:0 6px 0 -29px;vertical-align:middle}.form-input-tip{color:#666}input.disabled,input:disabled,select.disabled,select:disabled,textarea.disabled,textarea:disabled{background:rgba(255,255,255,.5);border-color:rgba(222,222,222,.75);box-shadow:inset 0 1px 2px rgba(0,0,0,.04);color:rgba(51,51,51,.5)}input[type=file].disabled,input[type=file]:disabled,input[type=range].disabled,input[type=range]:disabled{background:0 0;box-shadow:none;cursor:default}input[type=checkbox].disabled,input[type=checkbox].disabled:checked:before,input[type=checkbox]:disabled,input[type=checkbox]:disabled:checked:before,input[type=radio].disabled,input[type=radio].disabled:checked:before,input[type=radio]:disabled,input[type=radio]:disabled:checked:before{opacity:.7}.wp-core-ui select{font-size:14px;line-height:2;color:#32373c;border-color:#7e8993;box-shadow:none;border-radius:3px;padding:0 24px 0 8px;min-height:30px;max-width:25rem;-webkit-appearance:none;background:#fff url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E') no-repeat right 5px top 55%;background-size:16px 16px;cursor:pointer;vertical-align:middle}.wp-core-ui select:hover{color:#007cba}.wp-core-ui select:focus{border-color:#007cba;color:#016087;box-shadow:0 0 0 1px #007cba}.wp-core-ui select:active{border-color:#999;box-shadow:none}.wp-core-ui select.disabled,.wp-core-ui select:disabled{color:#a0a5aa;border-color:#ddd;background-color:#f7f7f7;background-image:url('data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23a0a5aa%22%2F%3E%3C%2Fsvg%3E');box-shadow:none;text-shadow:0 1px 0 #fff;cursor:default;transform:none}.wp-core-ui select:-moz-focusring{color:transparent;text-shadow:0 0 0 #016087}.wp-core-ui select::-ms-value{background:0 0;color:#555}.wp-core-ui select:hover::-ms-value{color:#007cba}.wp-core-ui select:focus::-ms-value{color:#016087}.wp-core-ui select.disabled::-ms-value,.wp-core-ui select:disabled::-ms-value{color:#a0a5aa}.wp-core-ui select::-ms-expand{display:none}.wp-admin .button-cancel{display:inline-block;min-height:28px;padding:0 5px;line-height:2}.meta-box-sortables select{max-width:100%}.meta-box-sortables input{vertical-align:middle}.misc-pub-post-status select{margin-top:0}.wp-core-ui select[multiple]{height:auto;padding-right:8px;background:#fff}.submit{padding:1.5em 0;margin:5px 0;border-bottom-left-radius:3px;border-bottom-right-radius:3px;border:none}form p.submit a.cancel:hover{text-decoration:none}p.submit{text-align:left;max-width:100%;margin-top:20px;padding-top:10px}.textright p.submit{border:none;text-align:right}table.form-table+input+input+p.submit,table.form-table+input+p.submit,table.form-table+p.submit{border-top:none;padding-top:0}#major-publishing-actions input,#minor-publishing-actions .preview,#minor-publishing-actions input{text-align:center}input.all-options,textarea.all-options{width:250px}input.large-text,textarea.large-text{width:99%}.regular-text{width:25em}input.small-text{width:50px;padding:0 6px}label input.small-text{margin-top:-4px}input[type=number].small-text{width:65px;padding-right:0}input.tiny-text{width:35px}input[type=number].tiny-text{width:45px;padding-right:0}#doaction,#doaction2,#post-query-submit{margin:0 8px 0 0}.tablenav .actions select{float:left;margin-right:6px;max-width:12.5rem}#timezone_string option{margin-left:1em}.wp-cancel-pw>.dashicons,.wp-hide-pw>.dashicons{position:relative;top:3px;width:1.25rem;height:1.25rem;top:.25rem;font-size:20px}.wp-cancel-pw .dashicons-no{display:none}#your-profile label+a,label{vertical-align:middle}#your-profile label+a,fieldset label{vertical-align:middle}.options-media-php [for*="_size_"]{min-width:10em;vertical-align:baseline}.options-media-php .small-text[name*="_size_"]{margin:0 0 1em}#misc-publishing-actions label{vertical-align:baseline}#pass-strength-result{background-color:#eee;border:1px solid #ddd;color:#23282d;margin:-1px 1px 5px;padding:3px 5px;text-align:center;width:25em;box-sizing:border-box;opacity:0}#pass-strength-result.short{background-color:#f1adad;border-color:#e35b5b;opacity:1}#pass-strength-result.bad{background-color:#fbc5a9;border-color:#f78b53;opacity:1}#pass-strength-result.good{background-color:#ffe399;border-color:#ffc733;opacity:1}#pass-strength-result.strong{background-color:#c1e1b9;border-color:#83c373;opacity:1}#pass1-text.short,#pass1.short{border-color:#e35b5b}#pass1-text.bad,#pass1.bad{border-color:#f78b53}#pass1-text.good,#pass1.good{border-color:#ffc733}#pass1-text.strong,#pass1.strong{border-color:#83c373}.pw-weak{display:none}.indicator-hint{padding-top:8px}.wp-pwd [type=password],.wp-pwd [type=text]{margin-bottom:0;min-height:30px}.wp-pwd input::-ms-reveal{display:none}#pass1-text,.show-password #pass1{display:none}#pass1-text::-ms-clear{display:none}.show-password #pass1-text{display:inline-block}p.search-box{float:right;margin:0}.network-admin.themes-php p.search-box{clear:left}.search-box input[name="s"],.tablenav .search-plugins input[name="s"],.tagsdiv .newtag{float:left;margin:0 4px 0 0}.js.plugins-php .search-box .wp-filter-search{margin:0;width:280px}input[type=email].ui-autocomplete-loading,input[type=text].ui-autocomplete-loading{background-image:url(../images/loading.gif);background-repeat:no-repeat;background-position:right center;visibility:visible}input.ui-autocomplete-input.open{border-bottom-color:transparent}ul#add-to-blog-users{margin:0 0 0 14px}.ui-autocomplete{padding:0;margin:0;list-style:none;position:absolute;z-index:10000;border:1px solid #5b9dd9;box-shadow:0 1px 2px rgba(30,140,190,.8);background-color:#fff}.ui-autocomplete li{margin-bottom:0;padding:4px 10px;white-space:nowrap;text-align:left;cursor:pointer}.ui-autocomplete .ui-state-focus{background-color:#ddd}.wp-tags-autocomplete .ui-state-focus{background-color:#0073aa;color:#fff}.form-table{border-collapse:collapse;margin-top:.5em;width:100%;clear:both}.form-table,.form-table td,.form-table td p,.form-table th{font-size:14px}.form-table td{margin-bottom:9px;padding:15px 10px;line-height:1.3;vertical-align:middle}.form-table th,.form-wrap label{color:#23282d;font-weight:400;text-shadow:none;vertical-align:baseline}.form-table th{vertical-align:top;text-align:left;padding:20px 10px 20px 0;width:200px;line-height:1.3;font-weight:600}.form-table .td-full,.form-table th.th-full{width:auto;padding:20px 10px 20px 0;font-weight:400}.form-table td p{margin-top:4px;margin-bottom:0}.form-table .date-time-doc{margin-top:1em}.form-table p.timezone-info{margin:1em 0}.form-table td fieldset label{margin:.35em 0 .5em!important;display:inline-block}.form-table td fieldset p label{margin-top:0!important}.form-table td fieldset label,.form-table td fieldset li,.form-table td fieldset p{line-height:1.4}.form-table input.tog,.form-table input[type=radio]{margin-top:-4px;margin-right:4px;float:none}.form-table .pre{padding:8px;margin:0}table.form-table td .updated{font-size:13px}table.form-table td .updated p{font-size:13px;margin:.3em 0}#profile-page .form-table textarea{width:500px;margin-bottom:6px}#profile-page .form-table #rich_editing{margin-right:5px}#your-profile legend{font-size:22px}#display_name{width:15em}#adduser .form-field input,#createuser .form-field input{width:25em}.color-option{display:inline-block;width:24%;padding:5px 15px 15px;box-sizing:border-box;margin-bottom:3px}.color-option.selected,.color-option:hover{background:#ddd}.color-palette{width:100%;border-spacing:0;border-collapse:collapse}.color-palette td{height:20px;padding:0;border:none}.color-option{cursor:pointer}.new-application-password-notice.notice{margin-top:20px;margin-bottom:0}.tool-box .title{margin:8px 0;font-size:18px;font-weight:400;line-height:24px}.label-responsive{vertical-align:middle}#export-filters p{margin:0 0 1em}#export-filters p.submit{margin:7px 0 5px}.card{position:relative;margin-top:20px;padding:.7em 2em 1em;min-width:255px;max-width:520px;border:1px solid #ccd0d4;box-shadow:0 1px 1px rgba(0,0,0,.04);background:#fff;box-sizing:border-box}.pressthis h4{margin:2em 0 1em}.pressthis textarea{width:100%;font-size:1em}#pressthis-code-wrap{overflow:auto}.pressthis-bookmarklet-wrapper{margin:20px 0 8px;vertical-align:top;position:relative;z-index:1}.pressthis-bookmarklet,.pressthis-bookmarklet:active,.pressthis-bookmarklet:focus,.pressthis-bookmarklet:hover{display:inline-block;position:relative;cursor:move;color:#32373c;background:#e5e5e5;border-radius:5px;border:1px solid #b4b9be;font-style:normal;line-height:16px;font-size:14px;text-decoration:none}.pressthis-bookmarklet:active{outline:0}.pressthis-bookmarklet:after{content:"";width:70%;height:55%;z-index:-1;position:absolute;right:10px;bottom:9px;background:0 0;transform:skew(20deg) rotate(6deg);box-shadow:0 10px 8px rgba(0,0,0,.6)}.pressthis-bookmarklet:hover:after{transform:skew(20deg) rotate(9deg);box-shadow:0 10px 8px rgba(0,0,0,.7)}.pressthis-bookmarklet span{display:inline-block;margin:0 0 0;padding:0 12px 8px 9px}.pressthis-bookmarklet span:before{color:#72777c;font:normal 20px/1 dashicons;content:"\f157";position:relative;display:inline-block;top:4px;margin-right:4px}.pressthis-js-toggle{margin-left:10px;padding:0;height:auto;vertical-align:top}.pressthis-js-toggle.button.button{margin-left:10px;padding:0;height:auto;vertical-align:top}.pressthis-js-toggle .dashicons{margin:5px 8px 6px 7px;color:#555d66}.timezone-info code{white-space:nowrap}.defaultavatarpicker .avatar{margin:2px 0;vertical-align:middle}.options-general-php .date-time-text{display:inline-block;min-width:10em}.options-general-php input.small-text{width:56px;margin:-2px 0}.options-general-php .spinner{float:none;margin:-3px 3px 0}.options-general-php .language-install-spinner,.settings-php .language-install-spinner{display:inline-block;float:none;margin:-3px 5px 0;vertical-align:middle}.form-table.permalink-structure .available-structure-tags li{float:left;margin-right:5px}.setup-php textarea{max-width:100%}.form-field #site-address{max-width:25em}.form-field #domain{max-width:22em}.form-field #admin-email,.form-field #blog_last_updated,.form-field #blog_registered,.form-field #path,.form-field #site-title{max-width:25em}.form-field #path{margin-bottom:5px}#search-sites,#search-users{max-width:60%}.request-filesystem-credentials-dialog{display:none;visibility:visible}.request-filesystem-credentials-dialog .notification-dialog{top:10%;max-height:85%}.request-filesystem-credentials-dialog-content{margin:25px}#request-filesystem-credentials-title{font-size:1.3em;margin:1em 0}.request-filesystem-credentials-form legend{font-size:1em;padding:1.33em 0;font-weight:600}.request-filesystem-credentials-form input[type=password],.request-filesystem-credentials-form input[type=text]{display:block}.request-filesystem-credentials-dialog input[type=password],.request-filesystem-credentials-dialog input[type=text]{width:100%}.request-filesystem-credentials-form .field-title{font-weight:600}.request-filesystem-credentials-dialog label[for=hostname],.request-filesystem-credentials-dialog label[for=private_key],.request-filesystem-credentials-dialog label[for=public_key]{display:block;margin-bottom:1em}.request-filesystem-credentials-dialog .ftp-password,.request-filesystem-credentials-dialog .ftp-username{float:left;width:48%}.request-filesystem-credentials-dialog .ftp-password{margin-left:4%}.request-filesystem-credentials-dialog .request-filesystem-credentials-action-buttons{text-align:right}.request-filesystem-credentials-dialog label[for=ftp]{margin-right:10px}.request-filesystem-credentials-dialog #auth-keys-desc{margin-bottom:0}#request-filesystem-credentials-dialog .button:not(:last-child){margin-right:10px}#request-filesystem-credentials-form .cancel-button{display:none}#request-filesystem-credentials-dialog .cancel-button{display:inline}.request-filesystem-credentials-dialog .ftp-password,.request-filesystem-credentials-dialog .ftp-username{float:none;width:auto}.request-filesystem-credentials-dialog .ftp-username{margin-bottom:1em}.request-filesystem-credentials-dialog .ftp-password{margin:0}.request-filesystem-credentials-dialog .ftp-password em{color:#888}.request-filesystem-credentials-dialog label{display:block;line-height:1.5;margin-bottom:1em}.request-filesystem-credentials-form legend{padding-bottom:0}.request-filesystem-credentials-form #ssh-keys legend{font-size:1.3em}.request-filesystem-credentials-form .notice{margin:0 0 20px 0;clear:both}.tools-privacy-policy-page form{margin-bottom:1.3em}.tools-privacy-policy-page input.button,.tools-privacy-policy-page select{margin:0 1px 0 6px}.tools-privacy-edit{margin:1.5em 0}.tools-privacy-policy-page span{line-height:2}.privacy_requests .column-email{width:40%}.privacy_requests .column-type{text-align:center}.privacy_requests tfoot td:first-child,.privacy_requests thead td:first-child{border-left:4px solid #fff}.privacy_requests tbody th{border-left:4px solid #fff;background:#fff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.1)}.privacy_requests .row-actions{color:#72777c}.privacy_requests .row-actions.processing{position:static}.privacy_requests tbody .has-request-results th{box-shadow:none}.privacy_requests tbody .request-results th .notice{margin:0 0 5px}.privacy_requests tbody td{background:#fff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.1)}.privacy_requests tbody .has-request-results td{box-shadow:none}.privacy_requests .next_steps .button{word-wrap:break-word;white-space:normal}.privacy_requests .status-request-confirmed td,.privacy_requests .status-request-confirmed th{background-color:#f7fcfe;border-left-color:#00a0d2}.privacy_requests .status-request-failed td,.privacy_requests .status-request-failed th{background-color:#fef7f1;border-left-color:#d64d21}.privacy_requests .export_personal_data_failed a{vertical-align:baseline}.status-label{font-weight:600}.status-label.status-request-pending{font-weight:400;font-style:italic;color:#6c7781}.status-label.status-request-failed{color:#a00;font-weight:600}.wp-privacy-request-form{clear:both}.wp-privacy-request-form-field{margin:1.5em 0}.wp-privacy-request-form label{font-weight:600;line-height:1.5;padding-bottom:.5em;display:block}.wp-privacy-request-form input{margin:0}.email-personal-data::before{display:inline-block;font:normal 20px/1 dashicons;margin:3px 5px 0 -2px;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;vertical-align:top}.email-personal-data--sending::before{color:#f56e28;content:"\f463";animation:rotation 2s infinite linear}.email-personal-data--sent::before{color:#79ba49;content:"\f147"}@media screen and (max-width:782px){textarea{-webkit-appearance:none}input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:3px 10px;min-height:40px}::-webkit-datetime-edit{line-height:1.875}.widefat tfoot td input[type=checkbox],.widefat th input[type=checkbox],.widefat thead td input[type=checkbox],input[type=checkbox]{-webkit-appearance:none}.widefat tfoot td input[type=checkbox],.widefat th input[type=checkbox],.widefat thead td input[type=checkbox]{margin-bottom:8px}.widefat tfoot td input[type=checkbox]:before,.widefat th input[type=checkbox]:before,.widefat thead td input[type=checkbox]:before,input[type=checkbox]:checked:before{width:1.875rem;height:1.875rem;margin:-.1875rem -.3125rem}input[type=checkbox],input[type=radio]{height:1.5625rem;width:1.5625rem}.wp-admin p input[type=checkbox],.wp-admin p input[type=radio]{margin-top:-.1875rem}input[type=radio]:checked:before{vertical-align:middle;width:.5625rem;height:.5625rem;margin:.4375rem;line-height:.76190476}.wp-upload-form input[type=submit]{margin-top:10px}.wp-admin .form-table select,.wp-core-ui select{min-height:40px;font-size:16px;line-height:1.625;padding:5px 24px 5px 8px}.wp-admin .button-cancel{margin-bottom:0;padding:2px 0;font-size:14px;vertical-align:middle}#adduser .form-field input,#createuser .form-field input{width:100%}.form-table{box-sizing:border-box}.form-table td,.form-table th,.label-responsive{display:block;width:auto;vertical-align:middle}.label-responsive{margin:.5em 0}.export-filters li{margin-bottom:0}.form-table .color-palette td{display:table-cell;width:15px}.form-table table.color-palette{margin-right:10px}input,textarea{font-size:16px}#profile-page .form-table textarea,.form-table span.description,.form-table td input[type=email],.form-table td input[type=password],.form-table td input[type=text],.form-table td select,.form-table td textarea{width:100%;display:block;max-width:none;box-sizing:border-box}.form-table .form-required.form-invalid td:after{float:right;margin:-30px 3px 0 0}.form-table input[type=text].small-text,input[type=number].small-text,input[type=password].small-text,input[type=search].small-text,input[type=text].small-text{width:auto;max-width:4.375em;display:inline;padding:3px 6px;margin:0 3px}#pass-strength-result{width:100%;box-sizing:border-box;padding:8px}p.search-box{float:none;position:absolute;bottom:0;width:98%;height:90px;margin-bottom:20px}p.search-box input[name="s"]{float:none;width:100%;margin-bottom:10px;vertical-align:middle}p.search-box input[type=submit]{margin-bottom:10px}.form-table span.description{display:inline;padding:4px 0 0;line-height:1.4;font-size:14px}.form-table th{padding:10px 0 0 0;border-bottom:0}.form-table td{margin-bottom:0;padding:4px 0 6px 0}.form-table.permalink-structure td code{margin-left:32px;display:inline-block}.form-table.permalink-structure td input[type=text]{margin-left:32px;margin-top:4px;width:96%}.form-table input.regular-text{width:100%}.form-table label{font-size:14px}.background-position-control .button-group>label{font-size:0}.form-table fieldset label{display:block}#local-time,#utc-time{display:block;float:none;margin-top:.5em}.form-field #domain{max-width:none}.wp-pwd{position:relative}#profile-page .form-table #pass1{padding-right:90px}.wp-pwd button.button{background:0 0;border:1px solid transparent;box-shadow:none;line-height:2;margin:0;padding:5px 9px;position:absolute;right:0;top:0;width:2.375rem;height:2.375rem;min-width:40px;min-height:40px}.wp-pwd button.wp-hide-pw{right:2.5rem}.wp-pwd button.button:focus,.wp-pwd button.button:hover{background:0 0}.wp-pwd button.button:active{background:0 0;box-shadow:none;transform:none}.wp-pwd .button .text{display:none}.wp-pwd [type=password],.wp-pwd [type=text]{line-height:2;padding-right:5rem}.wp-cancel-pw .dashicons-no{display:inline-block}.options-general-php input[type=text].small-text{max-width:6.25em;margin:0}.tools-privacy-policy-page form.wp-create-privacy-page{margin-bottom:1em}.tools-privacy-policy-page input#set-page,.tools-privacy-policy-page select{margin:10px 0 0}.tools-privacy-policy-page .wp-create-privacy-page span{display:block;margin-bottom:1em}.tools-privacy-policy-page .wp-create-privacy-page .button{margin-left:0}.wp-list-table.privacy_requests tr:not(.inline-edit-row):not(.no-items) td.column-primary:not(.check-column){display:table-cell}.wp-list-table.privacy_requests.widefat th input,.wp-list-table.privacy_requests.widefat thead td input{margin-left:5px}.wp-privacy-request-form-field input[type=text]{width:100%;margin-bottom:10px;vertical-align:middle}.regular-text{max-width:100%}}@media only screen and (max-width:768px){.form-field input[type=email],.form-field input[type=password],.form-field input[type=text],.form-field select,.form-field textarea{width:99%}.form-wrap .form-field{padding:0}}@media only screen and (max-height:480px),screen and (max-width:450px){.file-editor-warning .notification-dialog,.request-filesystem-credentials-dialog .notification-dialog{width:100%;height:100%;max-height:100%;position:fixed;top:0;margin:0;left:0}}@media screen and (max-width:600px){.color-option{width:49%}}@media only screen and (max-width:320px){.options-general-php .date-time-text.date-time-custom-text{min-width:0;margin-right:.5em}}@keyframes rotation{0%{transform:rotate(0)}100%{transform:rotate(359deg)}}
\ No newline at end of file
diff --git a/wp-admin/includes/class-wp-application-passwords-list-table.php b/wp-admin/includes/class-wp-application-passwords-list-table.php
new file mode 100644
index 0000000000..fc21c59931
--- /dev/null
+++ b/wp-admin/includes/class-wp-application-passwords-list-table.php
@@ -0,0 +1,248 @@
+ __( 'Name' ),
+ 'created' => __( 'Created' ),
+ 'last_used' => __( 'Last Used' ),
+ 'last_ip' => __( 'Last IP' ),
+ 'revoke' => __( 'Revoke' ),
+ );
+ }
+
+ /**
+ * Prepares the list of items for displaying.
+ *
+ * @since 5.6.0
+ */
+ public function prepare_items() {
+ global $user_id;
+ $this->items = array_reverse( WP_Application_Passwords::get_user_application_passwords( $user_id ) );
+ }
+
+ /**
+ * Handles the name column output.
+ *
+ * @since 5.6.0
+ *
+ * @param array $item The current application password item.
+ */
+ public function column_name( $item ) {
+ echo esc_html( $item['name'] );
+ }
+
+ /**
+ * Handles the created column output.
+ *
+ * @since 5.6.0
+ *
+ * @param array $item The current application password item.
+ */
+ public function column_created( $item ) {
+ if ( empty( $item['created'] ) ) {
+ echo '—';
+ } else {
+ echo gmdate( get_option( 'date_format', 'r' ), $item['created'] );
+ }
+ }
+
+ /**
+ * Handles the last used column output.
+ *
+ * @since 5.6.0
+ *
+ * @param array $item The current application password item.
+ */
+ public function column_last_used( $item ) {
+ if ( empty( $item['last_used'] ) ) {
+ echo '—';
+ } else {
+ echo gmdate( get_option( 'date_format', 'r' ), $item['last_used'] );
+ }
+ }
+
+ /**
+ * Handles the last ip column output.
+ *
+ * @since 5.6.0
+ *
+ * @param array $item The current application password item.
+ */
+ public function column_last_ip( $item ) {
+ if ( empty( $item['last_ip'] ) ) {
+ echo '—';
+ } else {
+ echo $item['last_ip'];
+ }
+ }
+
+ /**
+ * Handles the revoke column output.
+ *
+ * @since 5.6.0
+ */
+ public function column_revoke() {
+ submit_button( __( 'Revoke' ), 'delete', 'revoke-application-password', false );
+ }
+
+ /**
+ * Generates content for a single row of the table
+ *
+ * @since 5.6.0
+ *
+ * @param array $item The current item.
+ * @param string $column_name The current column name.
+ */
+ protected function column_default( $item, $column_name ) {
+ /**
+ * Fires for each custom column in the Application Passwords list table.
+ *
+ * Custom columns are registered using the {@see 'manage_application-passwords-user_columns'} filter.
+ *
+ * @since 5.6.0
+ *
+ * @param string $column_name Name of the custom column.
+ * @param array $item The application password item.
+ */
+ do_action( "manage_{$this->screen->id}_custom_column", $column_name, $item );
+ }
+
+ /**
+ * Generates custom table navigation to prevent conflicting nonces.
+ *
+ * @since 5.6.0
+ *
+ * @param string $which The location of the bulk actions: 'top' or 'bottom'.
+ */
+ protected function display_tablenav( $which ) {
+ ?>
+
+
+
+
+
+
+
+ bulk_actions( $which ); ?>
+
+ extra_tablenav( $which );
+ $this->pagination( $which );
+ ?>
+
+
+ ';
+ $this->single_row_columns( $item );
+ echo '';
+ }
+
+ /**
+ * Gets the name of the default primary column.
+ *
+ * @since 5.6.0
+ *
+ * @return string Name of the default primary column, in this case, 'name'.
+ */
+ protected function get_default_primary_column_name() {
+ return 'name';
+ }
+
+ /**
+ * Prints the JavaScript template for the new row item.
+ *
+ * @since 5.6.0
+ */
+ public function print_js_template_row() {
+ list( $columns, $hidden, , $primary ) = $this->get_column_info();
+
+ echo '';
+
+ foreach ( $columns as $column_name => $display_name ) {
+ $is_primary = $primary === $column_name;
+ $classes = "{$column_name} column-{$column_name}";
+
+ if ( $is_primary ) {
+ $classes .= ' has-row-actions column-primary';
+ }
+
+ if ( in_array( $column_name, $hidden, true ) ) {
+ $classes .= ' hidden';
+ }
+
+ printf( '', esc_attr( $classes ), esc_attr( wp_strip_all_tags( $display_name ) ) );
+
+ switch ( $column_name ) {
+ case 'name':
+ echo '{{ data.name }}';
+ break;
+ case 'created':
+ echo "<# print( wp.date.dateI18n( '" . esc_js( get_option( 'date_format' ) ) . "', data.created ) ) #>";
+ break;
+ case 'last_used':
+ echo "<# print( data.last_used !== null ? wp.date.dateI18n( '" . esc_js( get_option( 'date_format' ) ) . "', data.last_used ) : '—' ) #>";
+ break;
+ case 'last_ip':
+ echo "{{ data.last_ip || '—' }}";
+ break;
+ case 'revoke':
+ echo $this->column_revoke();
+ break;
+ default:
+ /**
+ * Fires in the JavaScript row template for each custom column in the Application Passwords list table.
+ *
+ * Custom columns are registered using the {@see 'manage_application-passwords-user_columns'} filter.
+ *
+ * @since 5.6.0
+ *
+ * @param string $column_name Name of the custom column.
+ */
+ do_action( "manage_{$this->screen->id}_custom_column_js_template", $column_name );
+ break;
+ }
+
+ if ( $is_primary ) {
+ echo '';
+ }
+
+ echo ' | ';
+ }
+
+ echo '
';
+ }
+}
diff --git a/wp-admin/includes/list-table.php b/wp-admin/includes/list-table.php
index 342f48dc9f..b702a5089f 100644
--- a/wp-admin/includes/list-table.php
+++ b/wp-admin/includes/list-table.php
@@ -33,6 +33,7 @@ function _get_list_table( $class, $args = array() ) {
'WP_Themes_List_Table' => 'themes',
'WP_Theme_Install_List_Table' => array( 'themes', 'theme-install' ),
'WP_Plugins_List_Table' => 'plugins',
+ 'WP_Application_Passwords_List_Table' => 'application-passwords',
// Network Admin.
'WP_MS_Sites_List_Table' => 'ms-sites',
diff --git a/wp-admin/includes/user.php b/wp-admin/includes/user.php
index 78deb2552e..de7cb989c1 100644
--- a/wp-admin/includes/user.php
+++ b/wp-admin/includes/user.php
@@ -594,3 +594,61 @@ Please click the following link to activate your user account:
wp_specialchars_decode( translate_user_role( $role['name'] ) )
);
}
+
+/**
+ * Checks if the Authorize Application Password request is valid.
+ *
+ * @since 5.6.0
+ *
+ * @param array $request {
+ * The array of request data. All arguments are optional and may be empty.
+ *
+ * @type string $app_name The suggested name of the application.
+ * @type string $success_url The url the user will be redirected to after approving the application.
+ * @type string $reject_url The url the user will be redirected to after rejecting the application.
+ * }
+ * @param WP_User $user The user authorizing the application.
+ * @return true|WP_Error True if the request is valid, a WP_Error object contains errors if not.
+ */
+function wp_is_authorize_application_password_request_valid( $request, $user ) {
+ $error = new WP_Error();
+
+ if ( ! empty( $request['success_url'] ) ) {
+ $scheme = wp_parse_url( $request['success_url'], PHP_URL_SCHEME );
+
+ if ( 'http' === $scheme ) {
+ $error->add(
+ 'invalid_redirect_scheme',
+ __( 'The success url must be served over a secure connection.' )
+ );
+ }
+ }
+
+ if ( ! empty( $request['reject_url'] ) ) {
+ $scheme = wp_parse_url( $request['reject_url'], PHP_URL_SCHEME );
+
+ if ( 'http' === $scheme ) {
+ $error->add(
+ 'invalid_redirect_scheme',
+ __( 'The rejection url must be served over a secure connection.' )
+ );
+ }
+ }
+
+ /**
+ * Fires before application password errors are returned.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_Error $error The error object.
+ * @param array $request The array of request data.
+ * @param WP_User $user The user authorizing the application.
+ */
+ do_action( 'wp_authorize_application_password_request_errors', $error, $request, $user );
+
+ if ( $error->has_errors() ) {
+ return $error;
+ }
+
+ return true;
+}
diff --git a/wp-admin/js/application-passwords.js b/wp-admin/js/application-passwords.js
new file mode 100644
index 0000000000..1ba6e0e665
--- /dev/null
+++ b/wp-admin/js/application-passwords.js
@@ -0,0 +1,196 @@
+/**
+ * @output wp-admin/js/application-passwords.js
+ */
+
+( function( $ ) {
+ var $appPassSection = $( '#application-passwords-section' ),
+ $newAppPassForm = $appPassSection.find( '.create-application-password' ),
+ $newAppPassField = $newAppPassForm.find( '.input' ),
+ $newAppPassButton = $newAppPassForm.find( '.button' ),
+ $appPassTwrapper = $appPassSection.find( '.application-passwords-list-table-wrapper' ),
+ $appPassTbody = $appPassSection.find( 'tbody' ),
+ $appPassTrNoItems = $appPassTbody.find( '.no-items' ),
+ $removeAllBtn = $( '#revoke-all-application-passwords' ),
+ tmplNewAppPass = wp.template( 'new-application-password' ),
+ tmplAppPassRow = wp.template( 'application-password-row' ),
+ userId = $( '#user_id' ).val();
+
+ $newAppPassButton.click( function( e ) {
+ e.preventDefault();
+ var name = $newAppPassField.val();
+
+ if ( 0 === name.length ) {
+ $newAppPassField.focus();
+ return;
+ }
+
+ clearErrors();
+ $newAppPassField.prop( 'disabled', true );
+ $newAppPassButton.prop( 'disabled', true );
+
+ var request = {
+ name: name
+ };
+
+ /**
+ * Filters the request data used to create a new Application Password.
+ *
+ * @since 5.6.0
+ *
+ * @param {Object} request The request data.
+ * @param {number} userId The id of the user the password is added for.
+ */
+ request = wp.hooks.applyFilters( 'wp_application_passwords_new_password_request', request, userId );
+
+ wp.apiRequest( {
+ path: '/wp/v2/users/' + userId + '/application-passwords',
+ method: 'POST',
+ data: request
+ } ).always( function() {
+ $newAppPassField.prop( 'disabled', false );
+ $newAppPassButton.prop( 'disabled', false );
+ } ).done( function( response ) {
+ $newAppPassField.val( '' );
+ $newAppPassButton.prop( 'disabled', false );
+
+ $newAppPassForm.after( tmplNewAppPass( {
+ name: name,
+ password: response.password
+ } ) );
+ $( '.new-application-password-notice' ).focus();
+
+ $appPassTbody.prepend( tmplAppPassRow( response ) );
+
+ $appPassTwrapper.show();
+ $appPassTrNoItems.remove();
+
+ /**
+ * Fires after an application password has been successfully created.
+ *
+ * @since 5.6.0
+ *
+ * @param {Object} response The response data from the REST API.
+ * @param {Object} request The request data used to create the password.
+ */
+ wp.hooks.doAction( 'wp_application_passwords_created_password', response, request );
+ } ).fail( handleErrorResponse );
+ } );
+
+ $appPassTbody.on( 'click', '.delete', function( e ) {
+ e.preventDefault();
+
+ if ( ! window.confirm( wp.i18n.__( 'Are you sure you want to revoke this password? This action cannot be undone.' ) ) ) {
+ return;
+ }
+
+ var $submitButton = $( this ),
+ $tr = $submitButton.closest( 'tr' ),
+ uuid = $tr.data( 'uuid' );
+
+ clearErrors();
+ $submitButton.prop( 'disabled', true );
+
+ wp.apiRequest( {
+ path: '/wp/v2/users/' + userId + '/application-passwords/' + uuid,
+ method: 'DELETE'
+ } ).always( function() {
+ $submitButton.prop( 'disabled', false );
+ } ).done( function( response ) {
+ if ( response.deleted ) {
+ if ( 0 === $tr.siblings().length ) {
+ $appPassTwrapper.hide();
+ }
+ $tr.remove();
+
+ wp.a11y.speak( wp.i18n.__( 'Application password revoked.' ) );
+ }
+ } ).fail( handleErrorResponse );
+ } );
+
+ $removeAllBtn.on( 'click', function( e ) {
+ e.preventDefault();
+
+ if ( ! window.confirm( wp.i18n.__( 'Are you sure you want to revoke all passwords? This action cannot be undone.' ) ) ) {
+ return;
+ }
+
+ var $submitButton = $( this );
+
+ clearErrors();
+ $submitButton.prop( 'disabled', true );
+
+ wp.apiRequest( {
+ path: '/wp/v2/users/' + userId + '/application-passwords',
+ method: 'DELETE'
+ } ).always( function() {
+ $submitButton.prop( 'disabled', false );
+ } ).done( function( response ) {
+ if ( response.deleted ) {
+ $appPassTbody.children().remove();
+ $appPassSection.children( '.new-application-password' ).remove();
+ $appPassTwrapper.hide();
+
+ wp.a11y.speak( wp.i18n.__( 'All application passwords revoked.' ) );
+ }
+ } ).fail( handleErrorResponse );
+ } );
+
+ $( document ).on( 'click', '.new-application-password-notice .notice-dismiss', function( e ) {
+ e.preventDefault();
+ var $el = $( this ).parent();
+ $el.fadeTo( 100, 0, function () {
+ $el.slideUp( 100, function () {
+ $el.remove();
+ } );
+ } );
+ } );
+
+ // If there are no items, don't display the table yet. If there are, show it.
+ if ( 0 === $appPassTbody.children( 'tr' ).not( $appPassTrNoItems ).length ) {
+ $appPassTwrapper.hide();
+ }
+
+ /**
+ * Handles an error response from the REST API.
+ *
+ * @since 5.6.0
+ *
+ * @param {jqXHR} xhr The XHR object from the ajax call.
+ * @param {string} textStatus The string categorizing the ajax request's status.
+ * @param {string} errorThrown The HTTP status error text.
+ */
+ function handleErrorResponse( xhr, textStatus, errorThrown ) {
+ var errorMessage = errorThrown;
+
+ if ( xhr.responseJSON && xhr.responseJSON.message ) {
+ errorMessage = xhr.responseJSON.message;
+ }
+
+ addError( errorMessage );
+ }
+
+ /**
+ * Displays an error message in the Application Passwords section.
+ *
+ * @since 5.6.0
+ *
+ * @param {string} message The error message to display.
+ */
+ function addError( message ) {
+ var $notice = $( '' )
+ .attr( 'role', 'alert' )
+ .addClass( 'notice notice-error' )
+ .append( $( '' ).text( message ) );
+
+ $newAppPassForm.after( $notice );
+ }
+
+ /**
+ * Clears error messages from the Application Passwords section.
+ *
+ * @since 5.6.0
+ */
+ function clearErrors() {
+ $( '.notice', $appPassSection ).remove();
+ }
+}( jQuery ) );
diff --git a/wp-admin/js/application-passwords.min.js b/wp-admin/js/application-passwords.min.js
new file mode 100644
index 0000000000..745266b328
--- /dev/null
+++ b/wp-admin/js/application-passwords.min.js
@@ -0,0 +1,2 @@
+/*! This file is auto-generated */
+!function(i){var o=i("#application-passwords-section"),n=o.find(".create-application-password"),p=n.find(".input"),s=n.find(".button"),t=o.find(".application-passwords-list-table-wrapper"),r=o.find("tbody"),d=r.find(".no-items"),e=i("#revoke-all-application-passwords"),l=wp.template("new-application-password"),c=wp.template("application-password-row"),w=i("#user_id").val();function u(e,a,o){var p=o;e.responseJSON&&e.responseJSON.message&&(p=e.responseJSON.message),function(e){var a=i("").attr("role","alert").addClass("notice notice-error").append(i("").text(e));n.after(a)}(p)}function f(){i(".notice",o).remove()}s.click(function(e){e.preventDefault();var a=p.val();if(0!==a.length){f(),p.prop("disabled",!0),s.prop("disabled",!0);var o={name:a};o=wp.hooks.applyFilters("wp_application_passwords_new_password_request",o,w),wp.apiRequest({path:"/wp/v2/users/"+w+"/application-passwords",method:"POST",data:o}).always(function(){p.prop("disabled",!1),s.prop("disabled",!1)}).done(function(e){p.val(""),s.prop("disabled",!1),n.after(l({name:a,password:e.password})),i(".new-application-password-notice").focus(),r.prepend(c(e)),t.show(),d.remove(),wp.hooks.doAction("wp_application_passwords_created_password",e,o)}).fail(u)}else p.focus()}),r.on("click",".delete",function(e){if(e.preventDefault(),window.confirm(wp.i18n.__("Are you sure you want to revoke this password? This action cannot be undone."))){var a=i(this),o=a.closest("tr"),p=o.data("uuid");f(),a.prop("disabled",!0),wp.apiRequest({path:"/wp/v2/users/"+w+"/application-passwords/"+p,method:"DELETE"}).always(function(){a.prop("disabled",!1)}).done(function(e){e.deleted&&(0===o.siblings().length&&t.hide(),o.remove(),wp.a11y.speak(wp.i18n.__("Application password revoked.")))}).fail(u)}}),e.on("click",function(e){if(e.preventDefault(),window.confirm(wp.i18n.__("Are you sure you want to revoke all passwords? This action cannot be undone."))){var a=i(this);f(),a.prop("disabled",!0),wp.apiRequest({path:"/wp/v2/users/"+w+"/application-passwords",method:"DELETE"}).always(function(){a.prop("disabled",!1)}).done(function(e){e.deleted&&(r.children().remove(),o.children(".new-application-password").remove(),t.hide(),wp.a11y.speak(wp.i18n.__("All application passwords revoked.")))}).fail(u)}}),i(document).on("click",".new-application-password-notice .notice-dismiss",function(e){e.preventDefault();var a=i(this).parent();a.fadeTo(100,0,function(){a.slideUp(100,function(){a.remove()})})}),0===r.children("tr").not(d).length&&t.hide()}(jQuery);
\ No newline at end of file
diff --git a/wp-admin/js/auth-app.js b/wp-admin/js/auth-app.js
new file mode 100644
index 0000000000..808bb0754b
--- /dev/null
+++ b/wp-admin/js/auth-app.js
@@ -0,0 +1,152 @@
+/**
+ * @output wp-admin/js/auth-app.js
+ */
+
+/* global authApp */
+
+( function( $, authApp ) {
+ var $appNameField = $( '#app_name' ),
+ $approveBtn = $( '#approve' ),
+ $rejectBtn = $( '#reject' ),
+ $form = $appNameField.closest( 'form' ),
+ context = {
+ userLogin: authApp.user_login,
+ successUrl: authApp.success,
+ rejectUrl: authApp.reject
+ };
+
+ $approveBtn.click( function( e ) {
+ var name = $appNameField.val();
+
+ e.preventDefault();
+
+ if ( 0 === name.length ) {
+ $appNameField.focus();
+ return;
+ }
+
+ $appNameField.prop( 'disabled', true );
+ $approveBtn.prop( 'disabled', true );
+
+ var request = {
+ name: name
+ };
+
+ /**
+ * Filters the request data used to Authorize an Application Password request.
+ *
+ * @since 5.6.0
+ *
+ * @param {Object} request The request data.
+ * @param {Object} context Context about the Application Password request.
+ * @param {string} context.userLogin The user's login username.
+ * @param {string} context.successUrl The URL the user will be redirected to after approving the request.
+ * @param {string} context.rejectUrl The URL the user will be redirected to after rejecting the request.
+ */
+ request = wp.hooks.applyFilters( 'wp_application_passwords_approve_app_request', request, context );
+
+ wp.apiRequest( {
+ path: '/wp/v2/users/me/application-passwords',
+ method: 'POST',
+ data: request
+ } ).done( function( response, textStatus, jqXHR ) {
+
+ /**
+ * Fires when an Authorize Application Password request has been successfully approved.
+ *
+ * @since 5.6.0
+ *
+ * @param {Object} response The response from the REST API.
+ * @param {string} response.password The newly created password.
+ * @param {string} textStatus The status of the request.
+ * @param {jqXHR} jqXHR The underlying jqXHR object that made the request.
+ */
+ wp.hooks.doAction( 'wp_application_passwords_approve_app_request_success', response, textStatus, jqXHR );
+
+ var raw = authApp.success,
+ url, message, $notice;
+
+ if ( raw ) {
+ url = raw + ( -1 === raw.indexOf( '?' ) ? '?' : '&' ) +
+ 'user_login=' + encodeURIComponent( authApp.user_login ) +
+ '&password=' + encodeURIComponent( response.password );
+
+ window.location = url;
+ } else {
+ message = wp.i18n.sprintf(
+ wp.i18n.__( 'Your new password for %1$s is: %2$s.' ),
+ '',
+ ''
+ );
+ $notice = $( '' )
+ .attr( 'role', 'alert' )
+ .attr( 'tabindex', 0 )
+ .addClass( 'notice notice-success notice-alt' )
+ .append( $( '' ).html( message ) );
+
+ // We're using .text() to write the variables to avoid any chance of XSS.
+ $( 'strong', $notice ).text( name );
+ $( 'kbd', $notice ).text( response.password );
+
+ $form.replaceWith( $notice );
+ $notice.focus();
+ }
+ } ).fail( function( jqXHR, textStatus, errorThrown ) {
+ var errorMessage = errorThrown,
+ error = null;
+
+ if ( jqXHR.responseJSON ) {
+ error = jqXHR.responseJSON;
+
+ if ( error.message ) {
+ errorMessage = error.message;
+ }
+ }
+
+ var $notice = $( '' )
+ .attr( 'role', 'alert' )
+ .addClass( 'notice notice-error' )
+ .append( $( '' ).text( errorMessage ) );
+
+ $( 'h1' ).after( $notice );
+
+ $appNameField.prop( 'disabled', false );
+ $approveBtn.prop( 'disabled', false );
+
+ /**
+ * Fires when an Authorize Application Password request encountered an error when trying to approve the request.
+ *
+ * @since 5.6.0
+ *
+ * @param {Object|null} error The error from the REST API. May be null if the server did not send proper JSON.
+ * @param {string} textStatus The status of the request.
+ * @param {string} errorThrown The error message associated with the response status code.
+ * @param {jqXHR} jqXHR The underlying jqXHR object that made the request.
+ */
+ wp.hooks.doAction( 'wp_application_passwords_approve_app_request_success', error, textStatus, jqXHR );
+ } );
+ } );
+
+ $rejectBtn.click( function( e ) {
+ e.preventDefault();
+
+ /**
+ * Fires when an Authorize Application Password request has been rejected by the user.
+ *
+ * @since 5.6.0
+ *
+ * @param {Object} context Context about the Application Password request.
+ * @param {string} context.userLogin The user's login username.
+ * @param {string} context.successUrl The URL the user will be redirected to after approving the request.
+ * @param {string} context.rejectUrl The URL the user will be redirected to after rejecting the request.
+ */
+ wp.hooks.doAction( 'wp_application_passwords_reject_app', context );
+
+ // @todo: Make a better way to do this so it feels like less of a semi-open redirect.
+ window.location = authApp.reject;
+ } );
+
+ $form.on( 'submit', function( e ) {
+ e.preventDefault();
+ } );
+}( jQuery, authApp ) );
diff --git a/wp-admin/js/auth-app.min.js b/wp-admin/js/auth-app.min.js
new file mode 100644
index 0000000000..9ad5a24ee6
--- /dev/null
+++ b/wp-admin/js/auth-app.min.js
@@ -0,0 +1,2 @@
+/*! This file is auto-generated */
+!function(i,c){var r=i("#app_name"),d=i("#approve"),e=i("#reject"),l=r.closest("form"),o={userLogin:c.user_login,successUrl:c.success,rejectUrl:c.reject};d.click(function(e){var n=r.val();if(e.preventDefault(),0!==n.length){r.prop("disabled",!0),d.prop("disabled",!0);var s={name:n};s=wp.hooks.applyFilters("wp_application_passwords_approve_app_request",s,o),wp.apiRequest({path:"/wp/v2/users/me/application-passwords",method:"POST",data:s}).done(function(e,s,o){wp.hooks.doAction("wp_application_passwords_approve_app_request_success",e,s,o);var p,a,t,r=c.success;r?(p=r+(-1===r.indexOf("?")?"?":"&")+"user_login="+encodeURIComponent(c.user_login)+"&password="+encodeURIComponent(e.password),window.location=p):(a=wp.i18n.sprintf(wp.i18n.__("Your new password for %1$s is: %2$s."),"",""),t=i("").attr("role","alert").attr("tabindex",0).addClass("notice notice-success notice-alt").append(i("").html(a)),i("strong",t).text(n),i("kbd",t).text(e.password),l.replaceWith(t),t.focus())}).fail(function(e,s,o){var p=o,a=null;e.responseJSON&&(a=e.responseJSON).message&&(p=a.message);var t=i("").attr("role","alert").addClass("notice notice-error").append(i("").text(p));i("h1").after(t),r.prop("disabled",!1),d.prop("disabled",!1),wp.hooks.doAction("wp_application_passwords_approve_app_request_success",a,s,e)})}else r.focus()}),e.click(function(e){e.preventDefault(),wp.hooks.doAction("wp_application_passwords_reject_app",o),window.location=c.reject}),l.on("submit",function(e){e.preventDefault()})}(jQuery,authApp);
\ No newline at end of file
diff --git a/wp-admin/user-edit.php b/wp-admin/user-edit.php
index 8c7088e96d..29e8f1a994 100644
--- a/wp-admin/user-edit.php
+++ b/wp-admin/user-edit.php
@@ -27,6 +27,10 @@ if ( ! $user_id && IS_PROFILE_PAGE ) {
wp_enqueue_script( 'user-profile' );
+if ( wp_is_application_passwords_available_for_user( $user_id ) ) {
+ wp_enqueue_script( 'application-passwords' );
+}
+
if ( IS_PROFILE_PAGE ) {
$title = __( 'Profile' );
} else {
@@ -702,6 +706,39 @@ endif;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 'application-passwords-user' ) );
+ $application_passwords_list_table->prepare_items();
+ $application_passwords_list_table->display();
+ ?>
+
+
+
+
+
+
+
+
+
+
wp_generate_uuid4(),
+ 'name' => $args['name'],
+ 'password' => $hashed_password,
+ 'created' => time(),
+ 'last_used' => null,
+ 'last_ip' => null,
+ );
+
+ $passwords = static::get_user_application_passwords( $user_id );
+ $passwords[] = $new_item;
+ $saved = static::set_user_application_passwords( $user_id, $passwords );
+
+ if ( ! $saved ) {
+ return new WP_Error( 'db_error', __( 'Could not save application password.' ) );
+ }
+
+ /**
+ * Fires when an application password is created.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id The user ID.
+ * @param array $new_item The details about the created password.
+ * @param string $new_password The unhashed generated app password.
+ * @param array $args Information used to create the application password.
+ */
+ do_action( 'wp_create_application_password', $user_id, $new_item, $new_password, $args );
+
+ return array( $new_password, $new_item );
+ }
+
+ /**
+ * Gets a user's application passwords.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id User ID.
+ * @return array The list of app passwords.
+ */
+ public static function get_user_application_passwords( $user_id ) {
+ $passwords = get_user_meta( $user_id, static::USERMETA_KEY_APPLICATION_PASSWORDS, true );
+
+ if ( ! is_array( $passwords ) ) {
+ return array();
+ }
+
+ $save = false;
+
+ foreach ( $passwords as $i => $password ) {
+ if ( ! isset( $password['uuid'] ) ) {
+ $passwords[ $i ]['uuid'] = wp_generate_uuid4();
+ $save = true;
+ }
+ }
+
+ if ( $save ) {
+ static::set_user_application_passwords( $user_id, $passwords );
+ }
+
+ return $passwords;
+ }
+
+ /**
+ * Gets a user's application password with the given uuid.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id User ID.
+ * @param string $uuid The password's uuid.
+ * @return array|null The application password if found, null otherwise.
+ */
+ public static function get_user_application_password( $user_id, $uuid ) {
+ $passwords = static::get_user_application_passwords( $user_id );
+
+ foreach ( $passwords as $password ) {
+ if ( $password['uuid'] === $uuid ) {
+ return $password;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Updates an application password.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id User ID.
+ * @param string $uuid The password's uuid.
+ * @param array $update Information about the application password to update.
+ * @return true|WP_Error True if successful, otherwise a WP_Error instance is returned on error.
+ */
+ public static function update_application_password( $user_id, $uuid, $update = array() ) {
+ $passwords = static::get_user_application_passwords( $user_id );
+
+ foreach ( $passwords as &$item ) {
+ if ( $item['uuid'] !== $uuid ) {
+ continue;
+ }
+
+ $save = false;
+
+ if ( ! empty( $update['name'] ) && $item['name'] !== $update['name'] ) {
+ $item['name'] = $update['name'];
+ $save = true;
+ }
+
+ if ( $save ) {
+ $saved = static::set_user_application_passwords( $user_id, $passwords );
+
+ if ( ! $saved ) {
+ return new WP_Error( 'db_error', __( 'Could not save application password.' ) );
+ }
+ }
+
+ /**
+ * Fires when an application password is updated.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id The user ID.
+ * @param array $item The updated app password details.
+ * @param array $update The information to update.
+ */
+ do_action( 'wp_update_application_password', $user_id, $item, $update );
+
+ return true;
+ }
+
+ return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) );
+ }
+
+ /**
+ * Records that an application password has been used.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id User ID.
+ * @param string $uuid The password's uuid.
+ * @return true|WP_Error True if the usage was recorded, a WP_Error if an error occurs.
+ */
+ public static function record_application_password_usage( $user_id, $uuid ) {
+ $passwords = static::get_user_application_passwords( $user_id );
+
+ foreach ( $passwords as &$password ) {
+ if ( $password['uuid'] !== $uuid ) {
+ continue;
+ }
+
+ // Only record activity once a day.
+ if ( $password['last_used'] + DAY_IN_SECONDS > time() ) {
+ continue;
+ }
+
+ $password['last_used'] = time();
+ $password['last_ip'] = $_SERVER['REMOTE_ADDR'];
+
+ $saved = static::set_user_application_passwords( $user_id, $passwords );
+
+ if ( ! $saved ) {
+ return new WP_Error( 'db_error', __( 'Could not save application password.' ) );
+ }
+
+ return true;
+ }
+
+ // Specified Application Password not found!
+ return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) );
+ }
+
+ /**
+ * Deletes an application password.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id User ID.
+ * @param string $uuid The password's uuid.
+ * @return true|WP_Error Whether the password was successfully found and deleted, a WP_Error otherwise.
+ */
+ public static function delete_application_password( $user_id, $uuid ) {
+ $passwords = static::get_user_application_passwords( $user_id );
+
+ foreach ( $passwords as $key => $item ) {
+ if ( $item['uuid'] === $uuid ) {
+ unset( $passwords[ $key ] );
+ $saved = static::set_user_application_passwords( $user_id, $passwords );
+
+ if ( ! $saved ) {
+ return new WP_Error( 'db_error', __( 'Could not delete application password.' ) );
+ }
+
+ /**
+ * Fires when an application password is deleted.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id The user ID.
+ * @param array $item The data about the application password.
+ */
+ do_action( 'wp_delete_application_password', $user_id, $item );
+
+ return true;
+ }
+ }
+
+ return new WP_Error( 'application_password_not_found', __( 'Could not find an application password with that id.' ) );
+ }
+
+ /**
+ * Deletes all application passwords for the given user.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id User ID.
+ * @return int|WP_Error The number of passwords that were deleted or a WP_Error on failure.
+ */
+ public static function delete_all_application_passwords( $user_id ) {
+ $passwords = static::get_user_application_passwords( $user_id );
+
+ if ( $passwords ) {
+ $saved = static::set_user_application_passwords( $user_id, array() );
+
+ if ( ! $saved ) {
+ return new WP_Error( 'db_error', __( 'Could not delete application passwords.' ) );
+ }
+
+ foreach ( $passwords as $item ) {
+ /** This action is documented in wp-includes/class-wp-application-passwords.php */
+ do_action( 'wp_delete_application_password', $user_id, $item );
+ }
+
+ return count( $passwords );
+ }
+
+ return 0;
+ }
+
+ /**
+ * Sets a users application passwords.
+ *
+ * @since 5.6.0
+ *
+ * @param int $user_id User ID.
+ * @param array $passwords Application passwords.
+ *
+ * @return bool
+ */
+ protected static function set_user_application_passwords( $user_id, $passwords ) {
+ return update_user_meta( $user_id, static::USERMETA_KEY_APPLICATION_PASSWORDS, $passwords );
+ }
+
+ /**
+ * Sanitizes and then splits a password into smaller chunks.
+ *
+ * @since 5.6.0
+ *
+ * @param string $raw_password The raw application password.
+ * @return string The chunked password.
+ */
+ public static function chunk_password( $raw_password ) {
+ $raw_password = preg_replace( '/[^a-z\d]/i', '', $raw_password );
+
+ return trim( chunk_split( $raw_password, 4, ' ' ) );
+ }
+}
diff --git a/wp-includes/class-wp-rewrite.php b/wp-includes/class-wp-rewrite.php
index 95a0386706..c5de10bb6d 100644
--- a/wp-includes/class-wp-rewrite.php
+++ b/wp-includes/class-wp-rewrite.php
@@ -1509,6 +1509,7 @@ class WP_Rewrite {
$rules = "\n";
$rules .= "RewriteEngine On\n";
+ $rules .= 'RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]';
$rules .= "RewriteBase $home_root\n";
// Prevent -f checks on index.php.
diff --git a/wp-includes/default-filters.php b/wp-includes/default-filters.php
index 4275d81677..dbc4fefb09 100644
--- a/wp-includes/default-filters.php
+++ b/wp-includes/default-filters.php
@@ -276,6 +276,9 @@ add_action( 'auth_cookie_expired', 'rest_cookie_collect_status' );
add_action( 'auth_cookie_bad_username', 'rest_cookie_collect_status' );
add_action( 'auth_cookie_bad_hash', 'rest_cookie_collect_status' );
add_action( 'auth_cookie_valid', 'rest_cookie_collect_status' );
+add_action( 'application_password_failed_authentication', 'rest_application_password_collect_status' );
+add_action( 'application_password_did_authenticate', 'rest_application_password_collect_status' );
+add_filter( 'rest_authentication_errors', 'rest_application_password_check_errors', 90 );
add_filter( 'rest_authentication_errors', 'rest_cookie_check_errors', 100 );
// Actions.
@@ -427,9 +430,11 @@ add_filter( 'heartbeat_nopriv_send', 'wp_auth_check' );
// Default authentication filters.
add_filter( 'authenticate', 'wp_authenticate_username_password', 20, 3 );
add_filter( 'authenticate', 'wp_authenticate_email_password', 20, 3 );
+add_filter( 'authenticate', 'wp_authenticate_application_password', 20, 3 );
add_filter( 'authenticate', 'wp_authenticate_spam_check', 99 );
add_filter( 'determine_current_user', 'wp_validate_auth_cookie' );
add_filter( 'determine_current_user', 'wp_validate_logged_in_cookie', 20 );
+add_filter( 'determine_current_user', 'wp_validate_application_password', 20 );
// Split term updates.
add_action( 'admin_init', '_wp_check_for_scheduled_split_terms' );
diff --git a/wp-includes/load.php b/wp-includes/load.php
index 702459d601..34f30bcb03 100644
--- a/wp-includes/load.php
+++ b/wp-includes/load.php
@@ -86,6 +86,47 @@ function wp_fix_server_vars() {
$_SERVER['PHP_SELF'] = preg_replace( '/(\?.*)?$/', '', $_SERVER['REQUEST_URI'] );
$PHP_SELF = $_SERVER['PHP_SELF'];
}
+
+ wp_populate_basic_auth_from_authorization_header();
+}
+
+/**
+ * Populates the Basic Auth server details from the Authorization header.
+ *
+ * Some servers running in CGI or FastCGI mode don't pass the Authorization
+ * header on to WordPress. If it's been rewritten to the `HTTP_AUTHORIZATION` header,
+ * fill in the proper $_SERVER variables instead.
+ *
+ * @since 5.6.0
+ */
+function wp_populate_basic_auth_from_authorization_header() {
+ // If we don't have anything to pull from, return early.
+ if ( ! isset( $_SERVER['HTTP_AUTHORIZATION'] ) && ! isset( $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] ) ) {
+ return;
+ }
+
+ // If either PHP_AUTH key is already set, do nothing.
+ if ( isset( $_SERVER['PHP_AUTH_USER'] ) || isset( $_SERVER['PHP_AUTH_PW'] ) ) {
+ return;
+ }
+
+ // From our prior conditional, one of these must be set.
+ $header = isset( $_SERVER['HTTP_AUTHORIZATION'] ) ? $_SERVER['HTTP_AUTHORIZATION'] : $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
+
+ // Test to make sure the pattern matches expected.
+ if ( ! preg_match( '%^Basic [a-z\d/+]*={0,2}$%i', $header ) ) {
+ return;
+ }
+
+ // Removing `Basic ` the token would start six characters in.
+ $token = substr( $header, 6 );
+ $userpass = base64_decode( $token );
+
+ list( $user, $pass ) = explode( ':', $userpass );
+
+ // Now shove them in the proper keys where we're expecting later on.
+ $_SERVER['PHP_AUTH_USER'] = $user;
+ $_SERVER['PHP_AUTH_PW'] = $pass;
}
/**
diff --git a/wp-includes/rest-api.php b/wp-includes/rest-api.php
index aed8a10491..0da4aeae36 100644
--- a/wp-includes/rest-api.php
+++ b/wp-includes/rest-api.php
@@ -209,6 +209,7 @@ function rest_api_default_filters() {
add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 );
add_filter( 'rest_pre_dispatch', 'rest_handle_options_request', 10, 3 );
+ add_filter( 'rest_index', 'rest_add_application_passwords_to_index' );
}
/**
@@ -264,6 +265,10 @@ function create_initial_rest_routes() {
$controller = new WP_REST_Users_Controller;
$controller->register_routes();
+ // Application Passwords
+ $controller = new WP_REST_Application_Passwords_Controller();
+ $controller->register_routes();
+
// Comments.
$controller = new WP_REST_Comments_Controller;
$controller->register_routes();
@@ -310,7 +315,6 @@ function create_initial_rest_routes() {
// Block Directory.
$controller = new WP_REST_Block_Directory_Controller();
$controller->register_routes();
-
}
/**
@@ -1034,6 +1038,80 @@ function rest_cookie_collect_status() {
$wp_rest_auth_cookie = true;
}
+/**
+ * Collects the status of authenticating with an application password.
+ *
+ * @since 5.6.0
+ *
+ * @global WP_User|WP_Error|null $wp_rest_application_password_status
+ *
+ * @param WP_Error $user_or_error The authenticated user or error instance.
+ */
+function rest_application_password_collect_status( $user_or_error ) {
+ global $wp_rest_application_password_status;
+
+ $wp_rest_application_password_status = $user_or_error;
+}
+
+/**
+ * Checks for errors when using application password-based authentication.
+ *
+ * @since 5.6.0
+ *
+ * @global WP_User|WP_Error|null $wp_rest_application_password_status
+ *
+ * @param WP_Error|null|true $result Error from another authentication handler,
+ * null if we should handle it, or another value if not.
+ * @return WP_Error|null|true WP_Error if the application password is invalid, the $result, otherwise true.
+ */
+function rest_application_password_check_errors( $result ) {
+ global $wp_rest_application_password_status;
+
+ if ( ! empty( $result ) ) {
+ return $result;
+ }
+
+ if ( is_wp_error( $wp_rest_application_password_status ) ) {
+ $data = $wp_rest_application_password_status->get_error_data();
+
+ if ( ! isset( $data['status'] ) ) {
+ $data['status'] = 401;
+ }
+
+ $wp_rest_application_password_status->add_data( $data );
+
+ return $wp_rest_application_password_status;
+ }
+
+ if ( $wp_rest_application_password_status instanceof WP_User ) {
+ return true;
+ }
+
+ return $result;
+}
+
+/**
+ * Adds Application Passwords info to the REST API index.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Response $response The index response object.
+ * @return WP_REST_Response
+ */
+function rest_add_application_passwords_to_index( $response ) {
+ if ( ! wp_is_application_passwords_available() ) {
+ return $response;
+ }
+
+ $response->data['authentication']['application-passwords'] = array(
+ 'endpoints' => array(
+ 'authorization' => admin_url( 'authorize-application.php' ),
+ ),
+ );
+
+ return $response;
+}
+
/**
* Retrieves the avatar urls in various sizes.
*
diff --git a/wp-includes/rest-api/class-wp-rest-server.php b/wp-includes/rest-api/class-wp-rest-server.php
index 20b029fca2..4c0555d3ad 100644
--- a/wp-includes/rest-api/class-wp-rest-server.php
+++ b/wp-includes/rest-api/class-wp-rest-server.php
@@ -223,11 +223,30 @@ class WP_REST_Server {
*
* @see WP_REST_Server::dispatch()
*
+ * @global WP_User $current_user The currently authenticated user.
+ *
* @param string $path Optional. The request route. If not set, `$_SERVER['PATH_INFO']` will be used.
* Default null.
* @return null|false Null if not served and a HEAD request, false otherwise.
*/
public function serve_request( $path = null ) {
+ /* @var WP_User|null $current_user */
+ global $current_user;
+
+ if ( $current_user instanceof WP_User && ! $current_user->exists() ) {
+ /*
+ * If there is no current user authenticated via other means, clear
+ * the cached lack of user, so that an authenticate check can set it
+ * properly.
+ *
+ * This is done because for authentications such as Application
+ * Passwords, we don't want it to be accepted unless the current HTTP
+ * request is an API request, which can't always be identified early
+ * enough in evaluation.
+ */
+ $current_user = null;
+ }
+
$content_type = isset( $_GET['_jsonp'] ) ? 'application/javascript' : 'application/json';
$this->send_header( 'Content-Type', $content_type . '; charset=' . get_option( 'blog_charset' ) );
$this->send_header( 'X-Robots-Tag', 'noindex' );
diff --git a/wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php b/wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php
new file mode 100644
index 0000000000..fdb496b412
--- /dev/null
+++ b/wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php
@@ -0,0 +1,656 @@
+namespace = 'wp/v2';
+ $this->rest_base = 'users/(?P(?:[\d]+|me))/application-passwords';
+ }
+
+ /**
+ * Registers the REST API routes for the application passwords controller.
+ *
+ * @since 5.6.0
+ */
+ public function register_routes() {
+ register_rest_route(
+ $this->namespace,
+ '/' . $this->rest_base,
+ array(
+ array(
+ 'methods' => WP_REST_Server::READABLE,
+ 'callback' => array( $this, 'get_items' ),
+ 'permission_callback' => array( $this, 'get_items_permissions_check' ),
+ 'args' => $this->get_collection_params(),
+ ),
+ array(
+ 'methods' => WP_REST_Server::CREATABLE,
+ 'callback' => array( $this, 'create_item' ),
+ 'permission_callback' => array( $this, 'create_item_permissions_check' ),
+ 'args' => $this->get_endpoint_args_for_item_schema(),
+ ),
+ array(
+ 'methods' => WP_REST_Server::DELETABLE,
+ 'callback' => array( $this, 'delete_items' ),
+ 'permission_callback' => array( $this, 'delete_items_permissions_check' ),
+ ),
+ 'schema' => array( $this, 'get_public_item_schema' ),
+ )
+ );
+
+ register_rest_route(
+ $this->namespace,
+ '/' . $this->rest_base . '/(?P[\w\-]+)',
+ array(
+ array(
+ 'methods' => WP_REST_Server::READABLE,
+ 'callback' => array( $this, 'get_item' ),
+ 'permission_callback' => array( $this, 'get_item_permissions_check' ),
+ 'args' => array(
+ 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
+ ),
+ ),
+ array(
+ 'methods' => WP_REST_Server::EDITABLE,
+ 'callback' => array( $this, 'update_item' ),
+ 'permission_callback' => array( $this, 'update_item_permissions_check' ),
+ 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
+ ),
+ array(
+ 'methods' => WP_REST_Server::DELETABLE,
+ 'callback' => array( $this, 'delete_item' ),
+ 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
+ ),
+ 'schema' => array( $this, 'get_public_item_schema' ),
+ )
+ );
+ }
+
+ /**
+ * Checks if a given request has access to get application passwords.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
+ */
+ public function get_items_permissions_check( $request ) {
+ return $this->do_permissions_check( $request );
+ }
+
+ /**
+ * Retrieves a collection of application passwords.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+ */
+ public function get_items( $request ) {
+ $user = $this->get_user( $request );
+
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
+
+ $passwords = WP_Application_Passwords::get_user_application_passwords( $user->ID );
+ $response = array();
+
+ foreach ( $passwords as $password ) {
+ $response[] = $this->prepare_response_for_collection(
+ $this->prepare_item_for_response( $password, $request )
+ );
+ }
+
+ return new WP_REST_Response( $response );
+ }
+
+ /**
+ * Checks if a given request has access to get a specific application password.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return true|WP_Error True if the request has read access for the item, WP_Error object otherwise.
+ */
+ public function get_item_permissions_check( $request ) {
+ return $this->do_permissions_check( $request );
+ }
+
+ /**
+ * Retrieves one application password from the collection.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+ */
+ public function get_item( $request ) {
+ $password = $this->get_application_password( $request );
+
+ if ( is_wp_error( $password ) ) {
+ return $password;
+ }
+
+ return $this->prepare_item_for_response( $password, $request );
+ }
+
+ /**
+ * Checks if a given request has access to create application passwords.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
+ */
+ public function create_item_permissions_check( $request ) {
+ return $this->do_permissions_check( $request );
+ }
+
+ /**
+ * Creates an application password.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+ */
+ public function create_item( $request ) {
+ $user = $this->get_user( $request );
+
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
+
+ $prepared = $this->prepare_item_for_database( $request );
+
+ if ( is_wp_error( $prepared ) ) {
+ return $prepared;
+ }
+
+ $created = WP_Application_Passwords::create_new_application_password( $user->ID, wp_slash( (array) $prepared ) );
+
+ if ( is_wp_error( $created ) ) {
+ return $created;
+ }
+
+ $password = $created[0];
+ $item = WP_Application_Passwords::get_user_application_password( $user->ID, $created[1]['uuid'] );
+
+ $item['new_password'] = WP_Application_Passwords::chunk_password( $password );
+ $fields_update = $this->update_additional_fields_for_object( $item, $request );
+
+ if ( is_wp_error( $fields_update ) ) {
+ return $fields_update;
+ }
+
+ /**
+ * Fires after a single application password is completely created or updated via the REST API.
+ *
+ * @since 5.6.0
+ *
+ * @param array $item Inserted or updated password item.
+ * @param WP_REST_Request $request Request object.
+ * @param bool $creating True when creating an application password, false when updating.
+ */
+ do_action( 'rest_after_insert_application_password', $item, $request, true );
+
+ $request->set_param( 'context', 'edit' );
+ $response = $this->prepare_item_for_response( $item, $request );
+
+ $response->set_status( 201 );
+ $response->header( 'Location', $response->get_links()['self'][0]['href'] );
+
+ return $response;
+ }
+
+ /**
+ * Checks if a given request has access to update application passwords.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return true|WP_Error True if the request has access to create items, WP_Error object otherwise.
+ */
+ public function update_item_permissions_check( $request ) {
+ return $this->do_permissions_check( $request );
+ }
+
+ /**
+ * Updates an application password.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+ */
+ public function update_item( $request ) {
+ $user = $this->get_user( $request );
+
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
+
+ $item = $this->get_application_password( $request );
+
+ if ( is_wp_error( $item ) ) {
+ return $item;
+ }
+
+ $prepared = $this->prepare_item_for_database( $request );
+
+ if ( is_wp_error( $prepared ) ) {
+ return $prepared;
+ }
+
+ $saved = WP_Application_Passwords::update_application_password( $user->ID, $item['uuid'], wp_slash( (array) $prepared ) );
+
+ if ( is_wp_error( $saved ) ) {
+ return $saved;
+ }
+
+ $fields_update = $this->update_additional_fields_for_object( $item, $request );
+
+ if ( is_wp_error( $fields_update ) ) {
+ return $fields_update;
+ }
+
+ $item = WP_Application_Passwords::get_user_application_password( $user->ID, $item['uuid'] );
+
+ /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-application-passwords-controller.php */
+ do_action( 'rest_after_insert_application_password', $item, $request, false );
+
+ $request->set_param( 'context', 'edit' );
+ return $this->prepare_item_for_response( $item, $request );
+ }
+
+ /**
+ * Checks if a given request has access to delete all application passwords.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
+ */
+ public function delete_items_permissions_check( $request ) {
+ return $this->do_permissions_check( $request );
+ }
+
+ /**
+ * Deletes all application passwords.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+ */
+ public function delete_items( $request ) {
+ $user = $this->get_user( $request );
+
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
+
+ $deleted = WP_Application_Passwords::delete_all_application_passwords( $user->ID );
+
+ if ( is_wp_error( $deleted ) ) {
+ return $deleted;
+ }
+
+ return new WP_REST_Response(
+ array(
+ 'deleted' => true,
+ 'count' => $deleted,
+ )
+ );
+ }
+
+ /**
+ * Checks if a given request has access to delete a specific application password.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return true|WP_Error True if the request has access to delete the item, WP_Error object otherwise.
+ */
+ public function delete_item_permissions_check( $request ) {
+ return $this->do_permissions_check( $request );
+ }
+
+ /**
+ * Deletes one application password.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Full details about the request.
+ * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+ */
+ public function delete_item( $request ) {
+ $user = $this->get_user( $request );
+
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
+
+ $password = $this->get_application_password( $request );
+
+ if ( is_wp_error( $password ) ) {
+ return $password;
+ }
+
+ $request->set_param( 'context', 'edit' );
+ $previous = $this->prepare_item_for_response( $password, $request );
+ $deleted = WP_Application_Passwords::delete_application_password( $user->ID, $password['uuid'] );
+
+ if ( is_wp_error( $deleted ) ) {
+ return $deleted;
+ }
+
+ return new WP_REST_Response(
+ array(
+ 'deleted' => true,
+ 'previous' => $previous->get_data(),
+ )
+ );
+ }
+
+ /**
+ * Performs a permissions check for the request.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request
+ * @return true|WP_Error
+ */
+ protected function do_permissions_check( $request ) {
+ $user = $this->get_user( $request );
+
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
+
+ if ( ! current_user_can( 'edit_user', $user->ID ) ) {
+ return new WP_Error(
+ 'rest_cannot_manage_application_passwords',
+ __( 'Sorry, you are not allowed to manage application passwords for this user.' ),
+ array( 'status' => rest_authorization_required_code() )
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Prepares an application password for a create or update operation.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request Request object.
+ * @return object|WP_Error The prepared item, or WP_Error object on failure.
+ */
+ protected function prepare_item_for_database( $request ) {
+ $prepared = (object) array(
+ 'name' => $request['name'],
+ );
+
+ /**
+ * Filters an application password before it is inserted via the REST API.
+ *
+ * @since 5.6.0
+ *
+ * @param stdClass $prepared An object representing a single application password prepared for inserting or updating the database.
+ * @param WP_REST_Request $request Request object.
+ */
+ return apply_filters( 'rest_pre_insert_application_password', $prepared, $request );
+ }
+
+ /**
+ * Prepares the application password for the REST response.
+ *
+ * @since 5.6.0
+ *
+ * @param array $item WordPress representation of the item.
+ * @param WP_REST_Request $request Request object.
+ * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
+ */
+ public function prepare_item_for_response( $item, $request ) {
+ $user = $this->get_user( $request );
+
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
+
+ $prepared = array(
+ 'uuid' => $item['uuid'],
+ 'name' => $item['name'],
+ 'created' => gmdate( 'Y-m-d\TH:i:s', $item['created'] ),
+ 'last_used' => $item['last_used'] ? gmdate( 'Y-m-d\TH:i:s', $item['last_used'] ) : null,
+ 'last_ip' => $item['last_ip'] ? $item['last_ip'] : null,
+ );
+
+ if ( isset( $item['new_password'] ) ) {
+ $prepared['password'] = $item['new_password'];
+ }
+
+ $prepared = $this->add_additional_fields_to_object( $prepared, $request );
+ $prepared = $this->filter_response_by_context( $prepared, $request['context'] );
+
+ $response = new WP_REST_Response( $prepared );
+ $response->add_links( $this->prepare_links( $user, $item ) );
+
+ /**
+ * Filters the REST API response for an application password.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Response $response The response object.
+ * @param array $item The application password array.
+ * @param WP_REST_Request $request The request object.
+ */
+ return apply_filters( 'rest_prepare_application_password', $response, $item, $request );
+ }
+
+ /**
+ * Prepares links for the object.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_User $user The requested user.
+ * @param array $item The application password.
+ * @return array The list of links.
+ */
+ protected function prepare_links( WP_User $user, $item ) {
+ return array(
+ 'self' => array(
+ 'href' => rest_url( sprintf( '%s/users/%d/application-passwords/%s', $this->namespace, $user->ID, $item['uuid'] ) ),
+ ),
+ );
+ }
+
+ /**
+ * Gets the requested user.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request The request object.
+ * @return WP_User|WP_Error The WordPress user associated with the request, or a WP_Error if none found.
+ */
+ protected function get_user( $request ) {
+ if ( ! wp_is_application_passwords_available() ) {
+ return new WP_Error(
+ 'application_passwords_disabled',
+ __( 'Application passwords are not enabled.' ),
+ array( 'status' => 500 )
+ );
+ }
+
+ $error = new WP_Error(
+ 'rest_user_invalid_id',
+ __( 'Invalid user ID.' ),
+ array( 'status' => 404 )
+ );
+
+ $id = $request['user_id'];
+
+ if ( 'me' === $id ) {
+ if ( ! is_user_logged_in() ) {
+ return new WP_Error(
+ 'rest_not_logged_in',
+ __( 'You are not currently logged in.' ),
+ array( 'status' => 401 )
+ );
+ }
+
+ $user = wp_get_current_user();
+ } else {
+ $id = (int) $id;
+
+ if ( $id <= 0 ) {
+ return $error;
+ }
+
+ $user = get_userdata( $id );
+ }
+
+ if ( empty( $user ) || ! $user->exists() ) {
+ return $error;
+ }
+
+ if ( is_multisite() && ! is_user_member_of_blog( $user->ID ) ) {
+ return $error;
+ }
+
+ if ( ! wp_is_application_passwords_available_for_user( $user ) ) {
+ return new WP_Error(
+ 'application_passwords_disabled_for_user',
+ __( 'Application passwords are not enabled for your account. Please contact the site administrator for assistance.' ),
+ array( 'status' => 500 )
+ );
+ }
+
+ return $user;
+ }
+
+ /**
+ * Gets the requested application password.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_REST_Request $request The request object.
+ * @return array|WP_Error The application password details if found, a WP_Error otherwise.
+ */
+ protected function get_application_password( $request ) {
+ $user = $this->get_user( $request );
+
+ if ( is_wp_error( $user ) ) {
+ return $user;
+ }
+
+ $password = WP_Application_Passwords::get_user_application_password( $user->ID, $request['uuid'] );
+
+ if ( ! $password ) {
+ return new WP_Error(
+ 'rest_application_password_not_found',
+ __( 'Application password not found.' ),
+ array( 'status' => 404 )
+ );
+ }
+
+ return $password;
+ }
+
+ /**
+ * Retrieves the query params for the collections.
+ *
+ * @since 5.6.0
+ *
+ * @return array Query parameters for the collection.
+ */
+ public function get_collection_params() {
+ return array(
+ 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
+ );
+ }
+
+ /**
+ * Retrieves the application password's schema, conforming to JSON Schema.
+ *
+ * @since 5.6.0
+ *
+ * @return array Item schema data.
+ */
+ public function get_item_schema() {
+ if ( $this->schema ) {
+ return $this->add_additional_fields_schema( $this->schema );
+ }
+
+ $this->schema = array(
+ '$schema' => 'http://json-schema.org/draft-04/schema#',
+ 'title' => 'application-password',
+ 'type' => 'object',
+ 'properties' => array(
+ 'uuid' => array(
+ 'description' => __( 'The unique identifier for the application password.' ),
+ 'type' => 'string',
+ 'format' => 'uuid',
+ 'context' => array( 'view', 'edit', 'embed' ),
+ 'readonly' => true,
+ ),
+ 'name' => array(
+ 'description' => __( 'The name of the application password.' ),
+ 'type' => 'string',
+ 'required' => true,
+ 'context' => array( 'view', 'edit', 'embed' ),
+ ),
+ 'password' => array(
+ 'description' => __( 'The generated password. Only available after adding an application.' ),
+ 'type' => 'string',
+ 'context' => array( 'edit' ),
+ 'readonly' => true,
+ ),
+ 'created' => array(
+ 'description' => __( 'The GMT date the application password was created.' ),
+ 'type' => 'string',
+ 'format' => 'date-time',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'last_used' => array(
+ 'description' => __( 'The GMT date the application password was last used.' ),
+ 'type' => array( 'string', 'null' ),
+ 'format' => 'date-time',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ 'last_ip' => array(
+ 'description' => __( 'The IP address the application password was last used by.' ),
+ 'type' => array( 'string', 'null' ),
+ 'format' => 'ip',
+ 'context' => array( 'view', 'edit' ),
+ 'readonly' => true,
+ ),
+ ),
+ );
+
+ return $this->add_additional_fields_schema( $this->schema );
+ }
+}
diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php
index 8d096e344d..9f616ef5e7 100644
--- a/wp-includes/script-loader.php
+++ b/wp-includes/script-loader.php
@@ -1067,6 +1067,12 @@ function wp_default_scripts( $scripts ) {
);
$scripts->set_translations( 'password-strength-meter' );
+ $scripts->add( 'application-passwords', "/wp-admin/js/application-passwords$suffix.js", array( 'jquery', 'wp-util', 'wp-api-request', 'wp-date', 'wp-i18n', 'wp-hooks', 'wp-a11y' ), false, 1 );
+ $scripts->set_translations( 'application-passwords' );
+
+ $scripts->add( 'auth-app', "/wp-admin/js/auth-app$suffix.js", array( 'jquery', 'wp-api-request', 'wp-i18n', 'wp-hooks' ), false, 1 );
+ $scripts->set_translations( 'auth-app' );
+
$scripts->add( 'user-profile', "/wp-admin/js/user-profile$suffix.js", array( 'jquery', 'password-strength-meter', 'wp-util' ), false, 1 );
$scripts->set_translations( 'user-profile' );
diff --git a/wp-includes/user.php b/wp-includes/user.php
index d2977e3467..09ca45a710 100644
--- a/wp-includes/user.php
+++ b/wp-includes/user.php
@@ -297,6 +297,176 @@ function wp_authenticate_cookie( $user, $username, $password ) {
return $user;
}
+/**
+ * Authenticates the user using an application password.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_User|WP_Error|null $input_user WP_User or WP_Error object if a previous
+ * callback failed authentication.
+ * @param string $username Username for authentication.
+ * @param string $password Password for authentication.
+ * @return WP_User|WP_Error WP_User on success, WP_Error on failure.
+ */
+function wp_authenticate_application_password( $input_user, $username, $password ) {
+ if ( $input_user instanceof WP_User ) {
+ return $input_user;
+ }
+
+ $is_api_request = ( ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) );
+
+ /**
+ * Filters whether this is an API request that Application Passwords can be used on.
+ *
+ * By default, Application Passwords is available for the REST API and XML-RPC.
+ *
+ * @since 5.6.0
+ *
+ * @param bool $is_api_request If this is an acceptable API request.
+ */
+ $is_api_request = apply_filters( 'application_password_is_api_request', $is_api_request );
+
+ if ( ! $is_api_request ) {
+ return $input_user;
+ }
+
+ $error = null;
+ $user = get_user_by( 'login', $username );
+
+ if ( ! $user && is_email( $username ) ) {
+ $user = get_user_by( 'email', $username );
+ }
+
+ // If the login name is invalid, short circuit.
+ if ( ! $user ) {
+ if ( is_email( $username ) ) {
+ $error = new WP_Error(
+ 'invalid_email',
+ __( 'Unknown email address. Check again or try your username.' )
+ );
+ } else {
+ $error = new WP_Error(
+ 'invalid_username',
+ __( 'Unknown username. Check again or try your email address.' )
+ );
+ }
+ } elseif ( ! wp_is_application_passwords_available_for_user( $user ) ) {
+ $error = new WP_Error(
+ 'application_passwords_disabled',
+ __( 'Application passwords are disabled for the requested user.' )
+ );
+ }
+
+ if ( $error ) {
+ /**
+ * Fires when an application password failed to authenticate the user.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_Error $error The authentication error.
+ */
+ do_action( 'application_password_failed_authentication', $error );
+
+ return $error;
+ }
+
+ /*
+ * Strip out anything non-alphanumeric. This is so passwords can be used with
+ * or without spaces to indicate the groupings for readability.
+ *
+ * Generated application passwords are exclusively alphanumeric.
+ */
+ $password = preg_replace( '/[^a-z\d]/i', '', $password );
+
+ $hashed_passwords = WP_Application_Passwords::get_user_application_passwords( $user->ID );
+
+ foreach ( $hashed_passwords as $key => $item ) {
+ if ( ! wp_check_password( $password, $item['password'], $user->ID ) ) {
+ continue;
+ }
+
+ $error = new WP_Error();
+
+ /**
+ * Fires when an application password has been successfully checked as valid.
+ *
+ * This allows for plugins to add additional constraints to prevent an application password from being used.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_Error $error The error object.
+ * @param WP_User $user The user authenticating.
+ * @param array $item The details about the application password.
+ * @param string $password The raw supplied password.
+ */
+ do_action( 'wp_authenticate_application_password_errors', $error, $user, $item, $password );
+
+ if ( is_wp_error( $error ) && $error->has_errors() ) {
+ /** This action is documented in wp-includes/user.php */
+ do_action( 'application_password_failed_authentication', $error );
+
+ return $error;
+ }
+
+ WP_Application_Passwords::record_application_password_usage( $user->ID, $item['uuid'] );
+
+ /**
+ * Fires after an application password was used for authentication.
+ *
+ * @since 5.6.0
+ *
+ * @param WP_User $user The user who was authenticated.
+ * @param array $item The application password used.
+ */
+ do_action( 'application_password_did_authenticate', $user, $item );
+
+ return $user;
+ }
+
+ $error = new WP_Error(
+ 'incorrect_password',
+ __( 'The provided password is an invalid application password.' )
+ );
+
+ /** This action is documented in wp-includes/user.php */
+ do_action( 'application_password_failed_authentication', $error );
+
+ return $error;
+}
+
+/**
+ * Validates the application password credentials passed via Basic Authentication.
+ *
+ * @since 5.6.0
+ *
+ * @param int|bool $input_user User ID if one has been determined, false otherwise.
+ * @return int|bool The authenticated user ID if successful, false otherwise.
+ */
+function wp_validate_application_password( $input_user ) {
+ // Don't authenticate twice.
+ if ( ! empty( $input_user ) ) {
+ return $input_user;
+ }
+
+ if ( ! wp_is_application_passwords_available() ) {
+ return $input_user;
+ }
+
+ // Check that we're trying to authenticate
+ if ( ! isset( $_SERVER['PHP_AUTH_USER'] ) ) {
+ return $input_user;
+ }
+
+ $authenticated = wp_authenticate_application_password( null, $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] );
+
+ if ( $authenticated instanceof WP_User ) {
+ return $authenticated->ID;
+ }
+
+ // If it wasn't a user what got returned, just pass on what we had received originally.
+ return $input_user;
+}
+
/**
* For Multisite blogs, check if the authenticated user has been marked as a
* spammer, or if the user's primary blog has been marked as spam.
@@ -3923,3 +4093,59 @@ function wp_get_user_request( $request_id ) {
return new WP_User_Request( $post );
}
+
+/**
+ * Checks if Application Passwords is globally available.
+ *
+ * By default, Application Passwords is available to all sites using SSL, but this function is
+ * filterable to adjust its availability.
+ *
+ * @since 5.6.0
+ *
+ * @return bool
+ */
+function wp_is_application_passwords_available() {
+ /**
+ * Filters whether Application Passwords is available.
+ *
+ * @since 5.6.0
+ *
+ * @param bool $available True if available, false otherwise.
+ */
+ return apply_filters( 'wp_is_application_passwords_available', is_ssl() );
+}
+
+/**
+ * Checks if Application Passwords is enabled for a specific user.
+ *
+ * By default all users can use Application Passwords, but this function is filterable to restrict
+ * availability to certain users.
+ *
+ * @since 5.6.0
+ *
+ * @param int|WP_User $user The user to check.
+ * @return bool
+ */
+function wp_is_application_passwords_available_for_user( $user ) {
+ if ( ! wp_is_application_passwords_available() ) {
+ return false;
+ }
+
+ if ( ! is_object( $user ) ) {
+ $user = get_userdata( $user );
+ }
+
+ if ( ! $user || ! $user->exists() ) {
+ return false;
+ }
+
+ /**
+ * Filters whether Application Passwords is available for a specific user.
+ *
+ * @since 5.6.0
+ *
+ * @param bool $available True if available, false otherwise.
+ * @param WP_User $user The user to check.
+ */
+ return apply_filters( 'wp_is_application_passwords_available_for_user', true, $user );
+}
diff --git a/wp-includes/version.php b/wp-includes/version.php
index 6e5209875c..4526b546aa 100644
--- a/wp-includes/version.php
+++ b/wp-includes/version.php
@@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
-$wp_version = '5.6-alpha-49108';
+$wp_version = '5.6-alpha-49109';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
diff --git a/wp-login.php b/wp-login.php
index 0135ecffb7..0ad2c039a8 100644
--- a/wp-login.php
+++ b/wp-login.php
@@ -1371,6 +1371,19 @@ switch ( $action ) {
$errors->add( 'updated', __( 'You have successfully updated WordPress! Please log back in to see what’s new.' ), 'message' );
} elseif ( WP_Recovery_Mode_Link_Service::LOGIN_ACTION_ENTERED === $action ) {
$errors->add( 'enter_recovery_mode', __( 'Recovery Mode Initialized. Please log in to continue.' ), 'message' );
+ } elseif ( isset( $_GET['redirect_to'] ) && false !== strpos( $_GET['redirect_to'], 'wp-admin/authorize-application.php' ) ) {
+ $query_component = wp_parse_url( $_GET['redirect_to'], PHP_URL_QUERY );
+ parse_str( $query_component, $query );
+
+ if ( ! empty( $query['app_name'] ) ) {
+ /* translators: 1: Website name, 2: Application name. */
+ $message = sprintf( 'Please log in to %1$s to authorize %2$s to connect to your account.', get_bloginfo( 'name', 'display' ), '' . esc_html( $query['app_name'] ) . '' );
+ } else {
+ /* translators: Website name. */
+ $message = sprintf( 'Please log in to %s to proceed with authorization.', get_bloginfo( 'name', 'display' ) );
+ }
+
+ $errors->add( 'authorize_application', $message, 'message' );
}
}
diff --git a/wp-settings.php b/wp-settings.php
index e21e51999b..f777b60a5e 100644
--- a/wp-settings.php
+++ b/wp-settings.php
@@ -236,6 +236,7 @@ require ABSPATH . WPINC . '/class-wp-widget-factory.php';
require ABSPATH . WPINC . '/nav-menu.php';
require ABSPATH . WPINC . '/nav-menu-template.php';
require ABSPATH . WPINC . '/admin-bar.php';
+require ABSPATH . WPINC . '/class-wp-application-passwords.php';
require ABSPATH . WPINC . '/rest-api.php';
require ABSPATH . WPINC . '/rest-api/class-wp-rest-server.php';
require ABSPATH . WPINC . '/rest-api/class-wp-rest-response.php';
@@ -259,6 +260,7 @@ require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-settings-controller
require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-themes-controller.php';
require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-plugins-controller.php';
require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-block-directory-controller.php';
+require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-application-passwords-controller.php';
require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-meta-fields.php';
require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-comment-meta-fields.php';
require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-post-meta-fields.php';