Client with UI

This commit is contained in:
dqj
2026-01-17 18:29:04 +09:00
parent 44a35fb45a
commit db2b608606
7 changed files with 2705 additions and 5 deletions

541
modal-demo.html Normal file
View File

@@ -0,0 +1,541 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FIDO2 UI SDK - Modal Demo</title>
<link rel="stylesheet" href="files/core.css">
<link rel="stylesheet" href="files/theme-default.css">
<link rel="stylesheet" href="files/demo.css">
<link rel="stylesheet" href="files/boxicons.css">
<link rel="stylesheet" href="files/fido2-ui-sdk.css">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
margin: 0;
padding: 40px 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.demo-header {
background: rgba(255, 255, 255, 0.95);
border-radius: 12px;
padding: 40px;
margin-bottom: 30px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
}
.demo-header h1 {
color: #333;
margin: 0 0 10px;
font-size: 32px;
}
.demo-header p {
color: #666;
margin: 0 0 20px;
font-size: 16px;
}
.demo-section {
background: rgba(255, 255, 255, 0.95);
border-radius: 12px;
padding: 30px;
margin-bottom: 30px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
}
.demo-section h2 {
color: #333;
margin: 0 0 20px;
font-size: 24px;
}
.demo-section p {
color: #666;
margin-bottom: 20px;
}
.demo-btn {
padding: 12px 32px;
font-size: 16px;
font-weight: 500;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
margin-right: 12px;
margin-bottom: 12px;
}
.demo-btn-primary {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.demo-btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}
.demo-btn-secondary {
background: #f8f9fa;
color: #333;
border: 1px solid #dee2e6;
}
.demo-btn-secondary:hover {
background: #e9ecef;
}
.code-block {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
padding: 20px;
margin: 20px 0;
overflow-x: auto;
}
.code-block code {
font-family: 'Courier New', monospace;
font-size: 14px;
line-height: 1.6;
color: #333;
}
.feature-list {
list-style: none;
padding: 0;
margin: 0;
}
.feature-list li {
padding: 12px 0;
border-bottom: 1px solid #e9ecef;
color: #666;
}
.feature-list li:last-child {
border-bottom: none;
}
.feature-list i {
color: #28a745;
margin-right: 10px;
}
#log-container {
background: #1e1e1e;
color: #d4d4d4;
border-radius: 8px;
padding: 20px;
max-height: 300px;
overflow-y: auto;
font-family: 'Courier New', monospace;
font-size: 13px;
line-height: 1.6;
}
.log-entry {
padding: 4px 0;
border-bottom: 1px solid #333;
}
.log-entry:last-child {
border-bottom: none;
}
.log-time {
color: #569cd6;
margin-right: 8px;
}
.log-type-info {
color: #4ec9b0;
}
.log-type-success {
color: #6a9955;
}
.log-type-error {
color: #f48771;
}
</style>
<script src="files/jquery.js"></script>
<script src="files/popper.js"></script>
<script src="files/bootstrap.js"></script>
<script src="files/dfido2-lib.js"></script>
<script src="files/fido2-ui-sdk.js"></script>
<script src="files/amipro_utils.js"></script>
<script>
const i18n_messages = new Map();
var lang_map = new Map();
lang_map.set("en-US", "🔐 FIDO2 UI SDK - Modal Demo");
lang_map.set("zh-CN", "🔐 FIDO2 UI SDK - 模态框演示");
lang_map.set("ja", "🔐 FIDO2 UI SDK - モーダル デモ");
i18n_messages.set("msg_title", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Demonstrate how to use FIDO2 UI SDK to manage devices in a popup window");
lang_map.set("zh-CN", "演示如何使用 FIDO2 UI SDK 在弹出窗口中管理设备");
lang_map.set("ja", "FIDO2 UI SDK を使用してポップアップ ウィンドウでデバイスを管理する方法をデモします");
i18n_messages.set("msg_subtitle", lang_map);
lang_map = new Map();
lang_map.set("en-US", "📌 Quick Start");
lang_map.set("zh-CN", "📌 快速开始");
lang_map.set("ja", "📌 クイック スタート");
i18n_messages.set("msg_section_quick_title", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Click the button below to open the device manager modal:");
lang_map.set("zh-CN", "点击下面的按钮打开设备管理模态框:");
lang_map.set("ja", "以下のボタンを押してデバイス管理モーダルを開いてください:");
i18n_messages.set("msg_quick_desc", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Manage Devices");
lang_map.set("zh-CN", "管理设备");
lang_map.set("ja", "デバイス管理");
i18n_messages.set("msg_btn_manage", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Custom Style");
lang_map.set("zh-CN", "自定义样式");
lang_map.set("ja", "カスタム スタイル");
i18n_messages.set("msg_btn_custom", lang_map);
lang_map = new Map();
lang_map.set("en-US", "💻 Code Examples");
lang_map.set("zh-CN", "💻 代码示例");
lang_map.set("ja", "💻 コード例");
i18n_messages.set("msg_section_code_title", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Simplest integration:");
lang_map.set("zh-CN", "最简单的集成方式:");
lang_map.set("ja", "最も簡単な統合:");
i18n_messages.set("msg_code_simple", lang_map);
lang_map = new Map();
lang_map.set("en-US", "With theme customization:");
lang_map.set("zh-CN", "带主题定制:");
lang_map.set("ja", "テーマのカスタマイズあり:");
i18n_messages.set("msg_code_theme", lang_map);
lang_map = new Map();
lang_map.set("en-US", "✨ Features");
lang_map.set("zh-CN", "✨ 功能特性");
lang_map.set("ja", "✨ 機能");
i18n_messages.set("msg_section_features_title", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Popup mode, stay on current page");
lang_map.set("zh-CN", "弹出窗口模式,不离开当前页面");
lang_map.set("ja", "ポップアップ モードで現在のページに留まる");
i18n_messages.set("msg_feature_1", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Add/delete FIDO2 devices support");
lang_map.set("zh-CN", "支持添加/删除 FIDO2 设备");
lang_map.set("ja", "FIDO2 デバイスの追加/削除サポート");
i18n_messages.set("msg_feature_2", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Real-time device list display");
lang_map.set("zh-CN", "实时显示设备列表");
lang_map.set("ja", "リアルタイム デバイスリスト表示");
i18n_messages.set("msg_feature_3", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Session status monitoring");
lang_map.set("zh-CN", "会话状态监控");
lang_map.set("ja", "セッション ステータス監視");
i18n_messages.set("msg_feature_4", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Theme color and style customization");
lang_map.set("zh-CN", "主题色和样式定制");
lang_map.set("ja", "テーマの色とスタイルのカスタマイズ");
i18n_messages.set("msg_feature_5", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Multi-language support (Chinese/English/Japanese)");
lang_map.set("zh-CN", "多语言支持(中/英/日)");
lang_map.set("ja", "多言語対応(中/英/日)");
i18n_messages.set("msg_feature_6", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Event callback system");
lang_map.set("zh-CN", "事件回调系统");
lang_map.set("ja", "イベント コールバック システム");
i18n_messages.set("msg_feature_7", lang_map);
lang_map = new Map();
lang_map.set("en-US", "📊 Event Log");
lang_map.set("zh-CN", "📊 事件日志");
lang_map.set("ja", "📊 イベント ログ");
i18n_messages.set("msg_section_log_title", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Clear Log");
lang_map.set("zh-CN", "清空日志");
lang_map.set("ja", "ログをクリア");
i18n_messages.set("msg_btn_clear", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Opening default device manager...");
lang_map.set("zh-CN", "打开默认设备管理器...");
lang_map.set("ja", "デフォルト デバイス マネージャーを開いています...");
i18n_messages.set("msg_log_open_default", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Opening custom style device manager...");
lang_map.set("zh-CN", "打开自定义样式设备管理器...");
lang_map.set("ja", "カスタム スタイル デバイス マネージャーを開いています...");
i18n_messages.set("msg_log_open_custom", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Device manager initialized successfully");
lang_map.set("zh-CN", "设备管理器初始化完成");
lang_map.set("ja", "デバイス マネージャーの初期化が完了しました");
i18n_messages.set("msg_log_init", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Custom style device manager initialized successfully");
lang_map.set("zh-CN", "自定义样式设备管理器初始化完成");
lang_map.set("ja", "カスタム スタイル デバイス マネージャーの初期化が完了しました");
i18n_messages.set("msg_log_init_custom", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Device added successfully");
lang_map.set("zh-CN", "设备添加成功");
lang_map.set("ja", "デバイスの追加が完了しました");
i18n_messages.set("msg_log_device_added", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Device deleted successfully");
lang_map.set("zh-CN", "设备删除成功");
lang_map.set("ja", "デバイスの削除が完了しました");
i18n_messages.set("msg_log_device_deleted", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Device list loaded, total");
lang_map.set("zh-CN", "设备列表加载完成,共");
lang_map.set("ja", "デバイスリストが読み込まれました。合計");
i18n_messages.set("msg_log_devices_loaded", lang_map);
lang_map = new Map();
lang_map.set("en-US", "devices");
lang_map.set("zh-CN", "个设备");
lang_map.set("ja", "デバイス");
i18n_messages.set("msg_log_devices_suffix", lang_map);
lang_map = new Map();
lang_map.set("en-US", "An error occurred");
lang_map.set("zh-CN", "发生错误");
lang_map.set("ja", "エラーが発生しました");
i18n_messages.set("msg_log_error", lang_map);
lang_map = new Map();
lang_map.set("en-US", "Device manager closed");
lang_map.set("zh-CN", "设备管理器已关闭");
lang_map.set("ja", "デバイス マネージャーが閉じられました");
i18n_messages.set("msg_log_closed", lang_map);
window.onload = function() {
setI18NText(i18n_messages);
};
</script>
</head>
<body>
<div class="container">
<div class="demo-header">
<h1 id="msg_title">🔐 FIDO2 UI SDK - Modal Demo</h1>
<p id="msg_subtitle">Demonstrate how to use FIDO2 UI SDK to manage devices in a popup window</p>
</div>
<div class="demo-section">
<h2 id="msg_section_quick_title">📌 Quick Start</h2>
<p id="msg_quick_desc">Click the button below to open the device manager modal:</p>
<button class="demo-btn demo-btn-primary" onclick="openDeviceManager()">
<i class="bx bx-device"></i> <span id="msg_btn_manage">Manage Devices</span>
</button>
<button class="demo-btn demo-btn-secondary" onclick="openCustomDeviceManager()">
<i class="bx bx-palette"></i> <span id="msg_btn_custom">Custom Style</span>
</button>
</div>
<div class="demo-section">
<h2 id="msg_section_code_title">💻 Code Examples</h2>
<p id="msg_code_simple">Simplest integration:</p>
<div class="code-block">
<code>Fido2UIManager.renderDeviceManager({
container: '#device-container',
mode: 'modal',
serverUrl: SERVER_URL
});</code>
</div>
<p id="msg_code_theme">With theme customization:</p>
<div class="code-block">
<code>Fido2UIManager.renderDeviceManager({
container: '#device-container',
mode: 'modal',
serverUrl: SERVER_URL,
theme: {
primaryColor: '#ce59d9',
backgroundColor: '#f8f9fa'
},
language: 'zh-CN'
});</code>
</div>
</div>
<div class="demo-section">
<h2 id="msg_section_features_title">✨ Features</h2>
<ul class="feature-list">
<li><i class="bx bx-check-circle"></i> <span id="msg_feature_1">Popup mode, stay on current page</span></li>
<li><i class="bx bx-check-circle"></i> <span id="msg_feature_2">Add/delete FIDO2 devices support</span></li>
<li><i class="bx bx-check-circle"></i> <span id="msg_feature_3">Real-time device list display</span></li>
<li><i class="bx bx-check-circle"></i> <span id="msg_feature_4">Session status monitoring</span></li>
<li><i class="bx bx-check-circle"></i> <span id="msg_feature_5">Theme color and style customization</span></li>
<li><i class="bx bx-check-circle"></i> <span id="msg_feature_6">Multi-language support (Chinese/English/Japanese)</span></li>
<li><i class="bx bx-check-circle"></i> <span id="msg_feature_7">Event callback system</span></li>
</ul>
</div>
<div class="demo-section">
<h2 id="msg_section_log_title">📊 Event Log</h2>
<div id="log-container"></div>
<button class="demo-btn demo-btn-secondary" onclick="clearLog()" style="margin-top: 15px;">
<span id="msg_btn_clear">Clear Log</span>
</button>
</div>
</div>
<div id="device-container"></div>
<script>
const SERVER_URL = 'https://local.dqj-macpro.com';
function getBrowserLanguage() {
const lang = window.navigator.language || window.navigator.userLanguage;
const supportedLangs = ['en-US', 'zh-CN', 'ja'];
if (supportedLangs.includes(lang)) {
return lang;
}
return 'en-US';
}
const CURRENT_LANG = getBrowserLanguage();//'https://fido2.amipro.me';
function openDeviceManager() {
clearLog();
log('info', getI18NText(i18n_messages, 'msg_log_open_default'));
Fido2UIManager.renderDeviceManager({
container: '#device-container',
mode: 'modal',
serverUrl: SERVER_URL,
language: CURRENT_LANG,
callbacks: {
onInit: function(manager) {
log('success', getI18NText(i18n_messages, 'msg_log_init'));
},
onDeviceAdded: function(device) {
log('success', getI18NText(i18n_messages, 'msg_log_device_added') + ': ' + JSON.stringify(device));
},
onDeviceDeleted: function(deviceId) {
log('success', getI18NText(i18n_messages, 'msg_log_device_deleted') + ': ' + deviceId);
},
onDeviceListLoaded: function(devices) {
log('info', getI18NText(i18n_messages, 'msg_log_devices_loaded') + ' ' + devices.length + ' ' + getI18NText(i18n_messages, 'msg_log_devices_suffix'));
},
onError: function(error) {
log('error', getI18NText(i18n_messages, 'msg_log_error') + ': ' + error.message);
},
onClose: function() {
log('info', getI18NText(i18n_messages, 'msg_log_closed'));
}
}
});
}
function openCustomDeviceManager() {
clearLog();
log('info', getI18NText(i18n_messages, 'msg_log_open_custom'));
Fido2UIManager.renderDeviceManager({
container: '#device-container',
mode: 'modal',
serverUrl: SERVER_URL,
language: CURRENT_LANG,
theme: {
logo: 'files/favicon.ico',
primaryColor: '#ce59d9',
backgroundColor: '#faf5ff',
textColor: '#6b21a8',
borderRadius: '12px'
},
features: {
showAddButton: true,
showDeleteButton: true,
showUserInfo: true,
showSessionStatus: true
},
callbacks: {
onInit: function(manager) {
log('success', getI18NText(i18n_messages, 'msg_log_init_custom'));
},
onDeviceAdded: function(device) {
log('success', getI18NText(i18n_messages, 'msg_log_device_added') + ': ' + JSON.stringify(device));
},
onDeviceDeleted: function(deviceId) {
log('success', getI18NText(i18n_messages, 'msg_log_device_deleted') + ': ' + deviceId);
},
onDeviceListLoaded: function(devices) {
log('info', getI18NText(i18n_messages, 'msg_log_devices_loaded') + ' ' + devices.length + ' ' + getI18NText(i18n_messages, 'msg_log_devices_suffix'));
},
onError: function(error) {
log('error', getI18NText(i18n_messages, 'msg_log_error') + ': ' + error.message);
},
onClose: function() {
log('info', getI18NText(i18n_messages, 'msg_log_closed'));
}
}
});
}
function log(type, message) {
const container = document.getElementById('log-container');
const entry = document.createElement('div');
entry.className = 'log-entry';
const time = new Date().toLocaleTimeString('zh-CN');
const typeClass = 'log-type-' + type;
entry.innerHTML = `<span class="log-time">[${time}]</span><span class="${typeClass}">[${type.toUpperCase()}]</span> ${message}`;
container.appendChild(entry);
container.scrollTop = container.scrollHeight;
}
function clearLog() {
document.getElementById('log-container').innerHTML = '';
}
</script>
</body>
</html>