PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 4.0.0
WP 2FA – Two-factor authentication for WordPress v4.0.0
4.0.0 1.7.1 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.8.0 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0 3.0.1 3.1.0 3.1.1 3.1.1.2 trunk 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.6.2 1.7.0
wp-2fa / templates / passkeys / user-profile-table.php
wp-2fa / templates / passkeys Last commit date
index.php 5 days ago setup-modal.php 5 days ago success-modal.php 5 days ago user-profile-table.php 5 days ago
user-profile-table.php
237 lines
1 <?php
2 /**
3 * Passkeys User Profile Table Template
4 *
5 * Variables expected in scope (set before include):
6 * $section_title string Section heading text.
7 * $section_description_html string Pre-escaped description HTML.
8 * $public_key_credentials array Array of passkey data arrays.
9 * $add_button bool Whether to show the "Add a Passkey" button.
10 * $user WP_User The user whose profile is displayed.
11 * $date_format string WordPress date format.
12 * $time_format string WordPress time format.
13 *
14 * @package wp2fa
15 * @since 4.0.0
16 */
17
18 defined( 'ABSPATH' ) || exit;
19
20 use WP2FA\Methods\Passkeys;
21 use WP2FA\WP2FA;
22 ?>
23 <tr><td colspan="2" style="padding: 0;">
24 <div class="wp-2fa-admin">
25 <h2 class="wp-2fa-admin--heading">
26 <?php echo \esc_html( $section_title ); ?>
27 </h2>
28 <p class="description">
29 <?php echo \wp_kses_post( $section_description_html ); ?>
30 </p>
31
32 <?php if ( empty( $public_key_credentials ) ) : ?>
33 <p class="wp-2fa-passkey-empty-message">
34 <strong><?php \esc_html_e( 'No Passkeys yet!', 'wp-2fa' ); ?></strong> <?php \esc_html_e( 'Create your first Passkey by clicking the button below.', 'wp-2fa' ); ?>
35 </p>
36 <?php endif; ?>
37
38 <?php if ( $add_button && \wp_get_current_user()->ID === $user->ID ) : ?>
39 <?php $passkey_btn_class = empty( WP2FA::get_wp2fa_white_label_setting( 'enable_wizard_styling' ) ) ? 'button button-primary' : 'wp2fa-profile__btn wp2fa-profile__btn--primary'; ?>
40 <a href="#" class="<?php echo \esc_attr( $passkey_btn_class ); ?>" data-open-configure-2fa-wizard-passkey><?php \esc_html_e( 'Add a Passkey', 'wp-2fa' ); ?></a>
41 <?php endif; ?>
42
43 <?php if ( ! empty( $public_key_credentials ) ) : ?>
44 <table class="wp-list-table wp-2fa-passkey-list-table widefat fixed striped table-view-list" id="wp-2fa-passkey-table">
45 <thead>
46 <tr>
47 <th class="manage-column column-name column-primary sortable asc" scope="col" data-sort-type="text">
48 <a href="#">
49 <span><?php \esc_html_e( 'Name', 'wp-2fa' ); ?></span>
50 <span class="sorting-indicators">
51 <span class="sorting-indicator asc" aria-hidden="true"></span>
52 <span class="sorting-indicator desc" aria-hidden="true"></span>
53 </span>
54 </a>
55 </th>
56 <th class="manage-column column-status sortable asc" scope="col" data-sort-type="text">
57 <a href="#">
58 <span><?php \esc_html_e( 'Status', 'wp-2fa' ); ?></span>
59 <span class="sorting-indicators">
60 <span class="sorting-indicator asc" aria-hidden="true"></span>
61 <span class="sorting-indicator desc" aria-hidden="true"></span>
62 </span>
63 </a>
64 </th>
65 <th class="manage-column column-created-date sortable asc" scope="col" data-sort-type="numeric">
66 <a href="#">
67 <span><?php \esc_html_e( 'Created', 'wp-2fa' ); ?></span>
68 <span class="sorting-indicators">
69 <span class="sorting-indicator asc" aria-hidden="true"></span>
70 <span class="sorting-indicator desc" aria-hidden="true"></span>
71 </span>
72 </a>
73 </th>
74 <th class="manage-column column-last-used-date sortable asc" scope="col" data-sort-type="numeric">
75 <a href="#">
76 <span><?php \esc_html_e( 'Last used', 'wp-2fa' ); ?></span>
77 <span class="sorting-indicators">
78 <span class="sorting-indicator asc" aria-hidden="true"></span>
79 <span class="sorting-indicator desc" aria-hidden="true"></span>
80 </span>
81 </a>
82 </th>
83 <th class="manage-column column-action" scope="col"><?php \esc_html_e( 'Actions', 'wp-2fa' ); ?></th>
84 </tr>
85 </thead>
86 <tfoot>
87 <tr>
88 <th class="manage-column column-name column-primary sortable asc" scope="col" data-sort-type="text">
89 <a href="#">
90 <span><?php \esc_html_e( 'Name', 'wp-2fa' ); ?></span>
91 <span class="sorting-indicators">
92 <span class="sorting-indicator asc" aria-hidden="true"></span>
93 <span class="sorting-indicator desc" aria-hidden="true"></span>
94 </span>
95 </a>
96 </th>
97 <th class="manage-column column-status sortable asc" scope="col" data-sort-type="text">
98 <a href="#">
99 <span><?php \esc_html_e( 'Status', 'wp-2fa' ); ?></span>
100 <span class="sorting-indicators">
101 <span class="sorting-indicator asc" aria-hidden="true"></span>
102 <span class="sorting-indicator desc" aria-hidden="true"></span>
103 </span>
104 </a>
105 </th>
106 <th class="manage-column column-created-date sortable asc" scope="col" data-sort-type="numeric">
107 <a href="#">
108 <span><?php \esc_html_e( 'Created', 'wp-2fa' ); ?></span>
109 <span class="sorting-indicators">
110 <span class="sorting-indicator asc" aria-hidden="true"></span>
111 <span class="sorting-indicator desc" aria-hidden="true"></span>
112 </span>
113 </a>
114 </th>
115 <th class="manage-column column-last-used-date sortable asc" scope="col" data-sort-type="numeric">
116 <a href="#">
117 <span><?php \esc_html_e( 'Last used', 'wp-2fa' ); ?></span>
118 <span class="sorting-indicators">
119 <span class="sorting-indicator asc" aria-hidden="true"></span>
120 <span class="sorting-indicator desc" aria-hidden="true"></span>
121 </span>
122 </a>
123 </th>
124 <th class="manage-column column-action" scope="col"><?php \esc_html_e( 'Actions', 'wp-2fa' ); ?></th>
125 </tr>
126 </tfoot>
127 <tbody>
128
129 <?php
130 foreach ( $public_key_credentials as $public_key_credential ) :
131 $extra_data = $public_key_credential;
132 $fingerprint = \ParagonIE_Sodium_Core_Base64_UrlSafe::encodeUnpadded( $extra_data['credential_id'] );
133
134 // Determine status text and CSS class.
135 if ( ! empty( $extra_data['revoked'] ) ) {
136 $status_text = \esc_html__( 'Revoked', 'wp-2fa' );
137 $status_class = 'wp-2fa-passkey-status--revoked';
138 } elseif ( $extra_data['enabled'] ) {
139 $status_text = \esc_html__( 'Enabled', 'wp-2fa' );
140 $status_class = 'wp-2fa-passkey-status--enabled';
141 } else {
142 $status_text = \esc_html__( 'Disabled', 'wp-2fa' );
143 $status_class = 'wp-2fa-passkey-status--disabled';
144 }
145
146 // Enable/Disable button text.
147 $btn_text = $extra_data['enabled']
148 ? \esc_html__( 'Disable', 'wp-2fa' )
149 : \esc_html__( 'Enable', 'wp-2fa' );
150
151 // Date values.
152 $created_timestamp = (int) ( $extra_data['created'] ?? 0 );
153 $last_used_timestamp = (int) ( $extra_data['last_used'] ?? 0 );
154 ?>
155 <tr>
156 <td data-field="name"
157 data-id="<?php echo \esc_attr( $fingerprint ); ?>"
158 data-label="<?php echo \esc_attr__( 'Name', 'wp-2fa' ); ?>"
159 data-sort-value="<?php echo \esc_attr( $extra_data['name'] ?? '' ); ?>">
160 <?php echo \esc_html( $extra_data['name'] ?? '' ); ?>
161 </td>
162 <td data-label="<?php echo \esc_attr__( 'Status', 'wp-2fa' ); ?>"
163 data-sort-value="<?php echo \esc_attr( $status_text ); ?>">
164 <span class="wp-2fa-passkey-status <?php echo \esc_attr( $status_class ); ?>">
165 <?php echo \esc_html( $status_text ); ?>
166 </span>
167 </td>
168 <td data-label="<?php echo \esc_attr__( 'Created', 'wp-2fa' ); ?>"
169 data-sort-value="<?php echo \esc_attr( $created_timestamp ); ?>">
170 <?php
171 if ( $created_timestamp > 0 ) {
172 $event_datetime_utc = \gmdate( 'Y-m-d H:i:s', $created_timestamp );
173 $event_date = \get_date_from_gmt( $event_datetime_utc, $date_format );
174 $event_time = \get_date_from_gmt( $event_datetime_utc, $time_format );
175 echo \esc_html( $event_date );
176 echo '<br>';
177 echo \esc_html( $event_time );
178 }
179 ?>
180 </td>
181 <td data-label="<?php echo \esc_attr__( 'Last used', 'wp-2fa' ); ?>"
182 data-sort-value="<?php echo \esc_attr( $last_used_timestamp ); ?>">
183 <?php
184 if ( empty( $extra_data['last_used'] ) ) {
185 \esc_html_e( 'Not used yet', 'wp-2fa' );
186 } else {
187 $event_datetime_utc = \gmdate( 'Y-m-d H:i:s', $last_used_timestamp );
188 $event_date = \get_date_from_gmt( $event_datetime_utc, $date_format );
189 $event_time = \get_date_from_gmt( $event_datetime_utc, $time_format );
190 echo \esc_html( $event_date );
191 echo '<br>';
192 echo \esc_html( $event_time );
193 }
194 ?>
195 </td>
196 <td data-label="<?php echo \esc_attr__( 'Actions', 'wp-2fa' ); ?>">
197 <?php
198 $is_owner = \wp_get_current_user()->ID === $user->ID;
199 $is_admin = \current_user_can( 'manage_options' );
200
201 // Enable/Disable: visible to owner and administrators.
202 if ( $is_owner || $is_admin ) {
203 printf(
204 '<button type="button" data-id="%1$s" name="%2$s" class="button-link disable enable_styling" aria-label="%3$s" data-nonce="%4$s" data-userid="%5$s">%6$s</button>',
205 \esc_attr( $fingerprint ),
206 \esc_attr( $extra_data['name'] ?? '' ),
207 /* translators: %1$s: the action (Enable/Disable), %2$s: the passkey name. */
208 \esc_attr( sprintf( __( '%1$s %2$s', 'wp-2fa' ), $btn_text, $extra_data['name'] ?? '' ) ),
209 \esc_attr( \wp_create_nonce( 'wp2fa-user-passkey-enable' ) ),
210 \esc_attr( (string) $user->ID ),
211 $btn_text // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
212 );
213 }
214
215 // Revoke: visible only to the passkey owner.
216 if ( $is_owner ) {
217 printf(
218 '<button type="button" data-id="%1$s" name="%2$s" class="button-link delete enable_styling" aria-label="%3$s" data-nonce="%4$s" data-userid="%5$s">%6$s</button>',
219 \esc_attr( $fingerprint ),
220 \esc_attr( $extra_data['name'] ?? '' ),
221 /* translators: %s: the passkey's given name. */
222 \esc_attr( sprintf( __( 'Revoke %s', 'wp-2fa' ), $extra_data['name'] ?? '' ) ),
223 \esc_attr( \wp_create_nonce( 'wp2fa-user-passkey-revoke' ) ),
224 \esc_attr( (string) $user->ID ),
225 \esc_html__( 'Revoke', 'wp-2fa' )
226 );
227 }
228 ?>
229 </td>
230 </tr>
231 <?php endforeach; ?>
232 </tbody>
233 </table>
234 <?php endif; ?>
235 </div>
236 </td></tr>
237