| | |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :xs="24"> |
| | | <el-form-item label="通行密钥"> |
| | | <div class="mfa-panel"> |
| | | <div class="mfa-head"> |
| | | <div class="mfa-title">设备生物识别 / 安全密钥登录</div> |
| | | <div class="mfa-actions"> |
| | | <el-button |
| | | v-if="!form.passkeyBound" |
| | | type="primary" |
| | | plain |
| | | icon="el-icon-key" |
| | | @click="openPasskeyRegisterDialog">绑定通行密钥</el-button> |
| | | <el-button |
| | | v-else |
| | | type="danger" |
| | | plain |
| | | icon="el-icon-delete" |
| | | @click="openPasskeyRemoveDialog">解绑通行密钥</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="mfa-meta"> |
| | | <div class="mfa-meta-item"> |
| | | <div class="mfa-meta-label">绑定状态</div> |
| | | <div class="mfa-meta-value">{{ form.passkeyBound ? '已绑定' : '未绑定' }}</div> |
| | | </div> |
| | | <div class="mfa-meta-item"> |
| | | <div class="mfa-meta-label">显示名称</div> |
| | | <div class="mfa-meta-value">{{ form.passkeyName || '--' }}</div> |
| | | </div> |
| | | <div class="mfa-meta-item"> |
| | | <div class="mfa-meta-label">绑定时间</div> |
| | | <div class="mfa-meta-value">{{ form.passkeyBoundTime$ || '--' }}</div> |
| | | </div> |
| | | </div> |
| | | <div class="mfa-tip"> |
| | | <span v-if="form.passkeyBound">最近使用:{{ form.passkeyLastUsedTime$ || '--' }}</span> |
| | | <span v-else>绑定后可直接使用设备指纹、人脸或安全密钥登录。该能力要求浏览器支持通行密钥,且系统以 HTTPS 或 localhost 打开。</span> |
| | | </div> |
| | | </div> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | | <div class="footer-bar"> |
| | | <el-button type="primary" :loading="saving" @click="handleSave">确认修改</el-button> |
| | |
| | | </div> |
| | | </el-form> |
| | | </el-dialog> |
| | | |
| | | <el-dialog |
| | | class="mfa-dialog" |
| | | :title="passkeyDialogMode === 'register' ? '绑定通行密钥' : '解绑通行密钥'" |
| | | :visible.sync="passkeyDialogVisible" |
| | | width="520px" |
| | | :close-on-click-modal="false" |
| | | @close="closePasskeyDialog" |
| | | append-to-body> |
| | | <div class="mfa-setup"> |
| | | <div v-if="passkeyDialogMode === 'register'" class="mfa-setup-tip">绑定时会弹出系统级身份验证窗口,请使用当前设备的人脸、指纹、PIN 或安全密钥完成确认。若浏览器或环境不支持,无法启用该能力。</div> |
| | | <div v-else class="mfa-setup-tip">解绑前请输入当前密码确认。解绑后将不能再用当前通行密钥直接登录。</div> |
| | | </div> |
| | | <el-form |
| | | ref="passkeyForm" |
| | | class="password-form" |
| | | :model="passkeyForm" |
| | | :rules="passkeyRules" |
| | | label-width="112px" |
| | | size="small" |
| | | @submit.native.prevent> |
| | | <el-form-item v-if="passkeyDialogMode === 'register'" label="显示名称" prop="name"> |
| | | <el-input v-model.trim="passkeyForm.name" maxlength="100" autocomplete="off" placeholder="例如:办公室电脑"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="当前密码" prop="currentPassword"> |
| | | <el-input v-model="passkeyForm.currentPassword" type="password" show-password autocomplete="off"></el-input> |
| | | </el-form-item> |
| | | <div class="mfa-footer"> |
| | | <el-button @click="closePasskeyDialog">关闭</el-button> |
| | | <el-button type="primary" :loading="passkeySubmitting" @click="handlePasskeySubmit">保存</el-button> |
| | | </div> |
| | | </el-form> |
| | | </el-dialog> |
| | | </div> |
| | | </body> |
| | | <script type="text/javascript" src="../static/js/jquery/jquery-3.3.1.min.js"></script> |
| | | <script type="text/javascript" src="../static/js/tools/md5.js"></script> |
| | | <script type="text/javascript" src="../static/js/common.js"></script> |
| | | <script type="text/javascript" src="../static/js/webauthn-utils.js"></script> |
| | | <script type="text/javascript" src="../static/vue/js/vue.min.js"></script> |
| | | <script type="text/javascript" src="../static/vue/element/element.js"></script> |
| | | <script type="text/javascript" src="../static/js/detail/detail.js?v=20260311_detail_mfa"></script> |
| | | <script type="text/javascript" src="../static/js/detail/detail.js?v=20260311_detail_passkey"></script> |
| | | </html> |