Updated JS in main branch

This commit is contained in:
dqj
2026-02-04 13:09:22 +09:00
parent 89ea8a48fc
commit 03ce446b8a
2 changed files with 424 additions and 169 deletions

View File

@@ -1,3 +1,12 @@
/**
*
* @file dfido2-lib.js
* @description FIDO2 library of amipro FIDO2 Server
* @version 2025-12-12
* @author Amipro Co., Ltd. (https://www.amipro.me/)
* @license Copyright (c) Amipro Co., Ltd. All rights reserved.
*/
const DFIDO2_LIB_LOCALSTG_NAME_USER_SESSION = 'fido2_user_session'
const DFIDO2_LIB_LOCALSTG_NAME_REGISTERED = 'dfido2_lib_registered'
const DFIDO2_LIB_LOCALSTG_NAME_SVR_URL = 'dfido2_lib_svr_url'

View File

@@ -1,3 +1,12 @@
/**
*
* @file fido2-ui-sdk.js
* @description FIDO2 UI SDK of amipro FIDO2 Server
* @version 2025-12-12
* @author Amipro Co., Ltd. (https://www.amipro.me/)
* @license Copyright (c) Amipro Co., Ltd. All rights reserved.
*/
(function(window) {
'use strict';
@@ -34,11 +43,13 @@
showDeleteButton: true,
showUserInfo: true,
showSessionStatus: true,
showRecoveryButton: true,
},
callbacks: {},
rpId: null,
autoRefresh: true,
refreshInterval: 5000,
recoverySessionId: null,
};
const DEFAULT_I18N = {
@@ -449,6 +460,78 @@
'ko': '비밀번호를 입력하세요',
'ru': 'Пожалуйста, введите пароль',
'it': 'Per favore inserisci password'
},
'title_recovery': {
'en-US': 'Device Recovery',
'zh-CN': '设备恢复',
'ja': 'デバイス回復',
'es': 'Recuperación de dispositivo',
'de': 'Gerätewiederherstellung',
'fr': 'Récupération de dispositif',
'pt': 'Recuperação de dispositivo',
'ko': '장치 복구',
'ru': 'Восстановление устройства',
'it': 'Ripristino dispositivo'
},
'msg_recovery_success': {
'en-US': 'Device recovered successfully',
'zh-CN': '设备恢复成功',
'ja': 'デバイス回復完了',
'es': 'Dispositivo recuperado exitosamente',
'de': 'Gerät erfolgreich wiederhergestellt',
'fr': 'Appareil récupéré avec succès',
'pt': 'Dispositivo recuperado com sucesso',
'ko': '장치 복구 완료',
'ru': 'Устройство успешно восстановлено',
'it': 'Dispositivo ripristinato con successo'
},
'msg_recovery_failed': {
'en-US': 'Recovery failed',
'zh-CN': '恢复失败',
'ja': '回復失敗',
'es': 'Recuperación fallida',
'de': 'Wiederherstellung fehlgeschlagen',
'fr': 'Échec de la récupération',
'pt': 'Falha na recuperação',
'ko': '복구 실패',
'ru': 'Ошибка восстановления',
'it': 'Ripristino fallito'
},
'msg_recovery_user_found': {
'en-US': 'Recovery session verified for user: {user}',
'zh-CN': '已验证恢复会话,用户: {user}',
'ja': 'ユーザー {user} の回復セッションが確認されました',
'es': 'Sesión de recuperación verificada para el usuario: {user}',
'de': 'Wiederherstellungssitzung für Benutzer verifiziert: {user}',
'fr': 'Session de récupération vérifiée pour l\'utilisateur: {user}',
'pt': 'Sessão de recuperação verificada para o usuário: {user}',
'ko': '사용자 {user}의 복구 세션 확인됨',
'ru': 'Сессия восстановления подтверждена для пользователя: {user}',
'it': 'Sessione di ripristino verificata per l\'utente: {user}'
},
'btn_start_recovery': {
'en-US': 'Start Recovery',
'zh-CN': '开始恢复',
'ja': '回復を開始',
'es': 'Iniciar recuperación',
'de': 'Wiederherstellung starten',
'fr': 'Démarrer la récupération',
'pt': 'Iniciar recuperação',
'ko': '복구 시작',
'ru': 'Начать восстановление',
'it': 'Avvia ripristino'
},
'btn_cancel': {
'en-US': 'Cancel',
'zh-CN': '取消',
'ja': 'キャンセル',
'es': 'Cancelar',
'de': 'Abbrechen',
'fr': 'Annuler',
'pt': 'Cancelar',
'ko': '취소',
'ru': 'Отмена',
'it': 'Annulla'
}
};
@@ -1286,6 +1369,8 @@
this.devices = [];
this.refreshTimer = null;
this.sessionStatus = false;
this.recoveryMode = false;
this.recoveryUser = null;
}
DeviceManager.prototype.getSessionUserId = function() {
@@ -1395,7 +1480,6 @@
DeviceManager.prototype.checkSession = async function() {
try {
// Simply validate session with server, same as devices.html does
const sessionOk = await validSession(this.config.rpId);
this.sessionStatus = !!sessionOk;
this.eventManager.emit('sessionStatusChanged', this.sessionStatus);
@@ -1407,6 +1491,112 @@
}
};
DeviceManager.prototype.getRegistrationUser = async function(regSessionId) {
try {
const response = await fetch(getServerUrl() + '/reg/username', {
method: 'POST',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ session_id: regSessionId })
});
const resp = await response.json();
return resp;
} catch (err) {
console.log(err);
return { status: 'failed', errorMessage: err.message };
}
};
DeviceManager.prototype.startRecovery = async function(recoverySessionId) {
try {
if (!recoverySessionId) {
throw new Error('Recovery session ID is required');
}
const result = await this.getRegistrationUser(recoverySessionId);
if (result && result.status === 'ok' && result.username) {
this.recoveryMode = true;
this.recoveryUser = {
username: result.username,
displayName: result.displayname || result.username,
sessionId: recoverySessionId
};
this.config.userId = result.username;
this.eventManager.emit('recoveryStarted', this.recoveryUser);
return {
success: true,
user: this.recoveryUser
};
} else {
throw new Error(result.errorMessage || 'Invalid recovery session');
}
} catch (error) {
this.eventManager.emit('error', error);
throw error;
}
};
DeviceManager.prototype.finishRecovery = async function(displayName) {
try {
if (!this.recoveryMode || !this.recoveryUser) {
throw new Error('Not in recovery mode');
}
const effectiveDisplayName = displayName || this.recoveryUser.displayName || 'RecoveredDevice-' + this.recoveryUser.username;
const result = await registerFido2(this.recoveryUser.username, effectiveDisplayName, this.config.rpId);
if (result.status === 'ok') {
const wasRecoveryMode = this.recoveryMode;
const recoveredUser = this.recoveryUser;
this.recoveryMode = false;
this.recoveryUser = null;
await this.loadDevices();
this.eventManager.emit('deviceAdded', result);
this.eventManager.emit('recoveryCompleted', {
user: recoveredUser,
device: result
});
return {
success: true,
user: recoveredUser,
device: result
};
} else {
throw new Error(result.errorMessage || 'Failed to add device during recovery');
}
} catch (error) {
this.eventManager.emit('error', error);
throw error;
}
};
DeviceManager.prototype.cancelRecovery = function() {
if (this.recoveryMode) {
const canceledUser = this.recoveryUser;
this.recoveryMode = false;
this.recoveryUser = null;
this.eventManager.emit('recoveryCanceled', canceledUser);
return true;
}
return false;
};
DeviceManager.prototype.isInRecoveryMode = function() {
return this.recoveryMode;
};
DeviceManager.prototype.getRecoveryUser = function() {
return this.recoveryUser;
};
DeviceManager.prototype.parseDeviceDescription = function(device) {
if (device.desc && device.desc.length > 0) {
return device.desc;
@@ -1510,20 +1700,24 @@
UIRenderer.prototype._getModalHTML = function(uniqueId, sessionStatusId, addBtnId, devicesListId) {
const theme = this.config.theme;
const dm = window.Fido2UIManager ? window.Fido2UIManager.deviceManager : null;
const isRecoveryMode = dm ? dm.isInRecoveryMode() : false;
const modalTitle = isRecoveryMode ? this.i18n.getText('title_recovery') : this.i18n.getText('my_devices');
return `
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content fido2-sdk-card">
<div class="modal-header fido2-sdk-header">
${theme.logo ? `<img src="${theme.logo}" class="fido2-sdk-logo" alt="Logo">` : ''}
<h5 class="modal-title fido2-sdk-text">${this.i18n.getText('my_devices')}</h5>
${this.config.features.showSessionStatus ? `<span class="badge fido2-sdk-status-badge" id="${sessionStatusId}"></span>` : ''}
<h5 class="modal-title fido2-sdk-text">${modalTitle}</h5>
${this.config.features.showSessionStatus && !isRecoveryMode ? `<span class="badge fido2-sdk-status-badge" id="${sessionStatusId}"></span>` : ''}
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body fido2-sdk-container">
${this._getBodyHTML(uniqueId, addBtnId, devicesListId)}
</div>
<div class="modal-footer">
${isRecoveryMode ? `<button type="button" class="btn btn-secondary fido2-sdk-btn" id="fido2CancelRecoveryBtn_${uniqueId}">${this.i18n.getText('btn_cancel')}</button>` : ''}
<button type="button" class="btn btn-secondary fido2-sdk-btn" data-bs-dismiss="modal">${this.i18n.getText('btn_close')}</button>
</div>
</div>
@@ -1535,41 +1729,57 @@
const features = this.config.features;
const dm = window.Fido2UIManager ? window.Fido2UIManager.deviceManager : null;
const userId = dm ? dm.getEffectiveUserId() : (this.config.userId || '');
const isRecoveryMode = dm ? dm.isInRecoveryMode() : false;
const recoveryUser = dm ? dm.getRecoveryUser() : null;
let html = '';
if (features.showUserInfo && userId) {
html += `<div class="fido2-sdk-user-info mb-3 fido2-sdk-text">
<strong>${this.i18n.getText('title_welcome')}:</strong> ${userId}
</div>`;
}
if (features.showAddButton) {
if (isRecoveryMode && recoveryUser) {
html += `
<button type="button" class="btn btn-info mb-3 fido2-sdk-btn fido2-sdk-btn-primary" id="${addBtnId}">
${this.i18n.getText('btn_add')}
<div class="alert alert-success mb-3 fido2-sdk-text">
<strong>${this.i18n.getText('msg_recovery_user_found').replace('{user}', recoveryUser.displayName || recoveryUser.username)}</strong>
</div>
`;
html += `
<button type="button" class="btn btn-success mb-3 fido2-sdk-btn fido2-sdk-btn-primary" id="fido2StartRecoveryBtn_${uniqueId}">
${this.i18n.getText('btn_start_recovery')}
</button>
`;
}
} else {
if (features.showUserInfo && userId) {
html += `<div class="fido2-sdk-user-info mb-3 fido2-sdk-text">
<strong>${this.i18n.getText('title_welcome')}:</strong> ${userId}
</div>`;
}
html += `
<div class="table-responsive">
<table class="table table-striped fido2-sdk-table">
<thead>
<tr>
<th>${this.i18n.getText('title_device')}</th>
<th>${this.i18n.getText('title_time')}</th>
${features.showDeleteButton ? `<th>${this.i18n.getText('title_act')}</th>` : ''}
</tr>
</thead>
<tbody id="${devicesListId}">
<tr>
<td colspan="3" class="text-center fido2-sdk-text">${this.i18n.getText('title_empty_list')}</td>
</tr>
</tbody>
</table>
</div>
`;
if (features.showAddButton) {
html += `
<button type="button" class="btn btn-info mb-3 fido2-sdk-btn fido2-sdk-btn-primary" id="${addBtnId}">
${this.i18n.getText('btn_add')}
</button>
`;
}
html += `
<div class="table-responsive">
<table class="table table-striped fido2-sdk-table">
<thead>
<tr>
<th>${this.i18n.getText('title_device')}</th>
<th>${this.i18n.getText('title_time')}</th>
${features.showDeleteButton ? `<th>${this.i18n.getText('title_act')}</th>` : ''}
</tr>
</thead>
<tbody id="${devicesListId}">
<tr>
<td colspan="3" class="text-center fido2-sdk-text">${this.i18n.getText('title_empty_list')}</td>
</tr>
</tbody>
</table>
</div>
`;
}
return html;
};
@@ -1591,6 +1801,28 @@
});
}
const startRecoveryBtn = container.querySelector('[id^="fido2StartRecoveryBtn_"]');
if (startRecoveryBtn) {
startRecoveryBtn.replaceWith(startRecoveryBtn.cloneNode(true));
const newStartRecoveryBtn = container.querySelector('[id^="fido2StartRecoveryBtn_"]');
if (newStartRecoveryBtn) {
newStartRecoveryBtn.addEventListener('click', () => {
this.eventManager.emit('startRecovery');
});
}
}
const cancelRecoveryBtn = container.querySelector('[id^="fido2CancelRecoveryBtn_"]');
if (cancelRecoveryBtn) {
cancelRecoveryBtn.replaceWith(cancelRecoveryBtn.cloneNode(true));
const newCancelRecoveryBtn = container.querySelector('[id^="fido2CancelRecoveryBtn_"]');
if (newCancelRecoveryBtn) {
newCancelRecoveryBtn.addEventListener('click', () => {
this.eventManager.emit('cancelRecovery');
});
}
}
container.querySelectorAll('[data-fido2-action="delete"]').forEach(btn => {
btn.addEventListener('click', (e) => {
e.preventDefault();
@@ -1665,6 +1897,54 @@
}
};
UIRenderer.prototype.updateRecoveryUI = function() {
const container = this.modalElement || this.containerElement;
if (!container) return;
const dm = window.Fido2UIManager ? window.Fido2UIManager.deviceManager : null;
if (!dm) return;
const isRecoveryMode = dm.isInRecoveryMode();
const uniqueId = this._uniqueId;
const titleEl = container.querySelector('.modal-title');
if (titleEl) {
titleEl.textContent = isRecoveryMode ? this.i18n.getText('title_recovery') : this.i18n.getText('my_devices');
}
const sessionBadge = container.querySelector('[id^="fido2SessionStatus_"]');
if (sessionBadge) {
sessionBadge.style.display = isRecoveryMode ? 'none' : 'inline';
}
const modalBody = container.querySelector('.modal-body');
if (modalBody) {
modalBody.innerHTML = this._getBodyHTML(uniqueId, 'fido2AddDeviceBtn_' + uniqueId, 'fido2DevicesList_' + uniqueId);
}
const modalFooter = container.querySelector('.modal-footer');
if (modalFooter) {
if (isRecoveryMode) {
let cancelBtn = modalFooter.querySelector('[id^="fido2CancelRecoveryBtn_"]');
if (!cancelBtn) {
cancelBtn = document.createElement('button');
cancelBtn.type = 'button';
cancelBtn.className = 'btn btn-secondary fido2-sdk-btn';
cancelBtn.id = 'fido2CancelRecoveryBtn_' + uniqueId;
cancelBtn.textContent = this.i18n.getText('btn_cancel');
modalFooter.insertBefore(cancelBtn, modalFooter.firstChild);
}
} else {
const cancelBtn = modalFooter.querySelector('[id^="fido2CancelRecoveryBtn_"]');
if (cancelBtn) {
cancelBtn.remove();
}
}
}
this._bindEvents(uniqueId, 'fido2AddDeviceBtn_' + uniqueId, 'fido2DevicesList_' + uniqueId);
};
UIRenderer.prototype.close = function() {
if (this.modalElement) {
const bootstrapModal = window.bootstrap.Modal.getInstance(this.modalElement);
@@ -1685,137 +1965,6 @@
this.containerElement = null;
};
UIRenderer.prototype.renderStandalone = function() {
if (this.config.container) {
const container = typeof this.config.container === 'string'
? document.querySelector(this.config.container)
: this.config.container;
if (container) {
container.innerHTML = this._getStandaloneBodyHTML();
this.containerElement = container;
this.themeManager.applyTheme(container);
this._bindEvents();
return container;
}
}
document.body.innerHTML = this._getStandaloneBodyHTML();
document.body.className = 'fido2-sdk-standalone';
this.containerElement = document.body;
this.themeManager.applyTheme(document.body);
this._bindEvents();
return document.body;
};
UIRenderer.prototype._getStandaloneBodyHTML = function() {
const theme = this.config.theme;
const dm = window.Fido2UIManager ? window.Fido2UIManager.deviceManager : null;
const userId = dm ? dm.getEffectiveUserId() : (this.config.userId || '');
return `
<div class="container fido2-sdk-container">
<div class="card fido2-sdk-card">
<div class="card-header fido2-sdk-header d-flex justify-content-between align-items-center">
<div>
${theme.logo ? `<img src="${theme.logo}" class="fido2-sdk-logo me-2" alt="Logo">` : ''}
<h4 class="mb-0 fido2-sdk-text">${this.i18n.getText('my_devices')}</h4>
</div>
${this.config.features.showSessionStatus ? '<span class="badge fido2-sdk-status-badge" id="fido2SessionStatus"></span>' : ''}
</div>
<div class="card-body fido2-sdk-body">
${this.config.features.showUserInfo && userId ? `
<div class="alert alert-info fido2-sdk-user-info fido2-sdk-text">
<strong>${this.i18n.getText('title_welcome')}:</strong> ${userId}
</div>
` : ''}
${this.config.features.showAddButton ? `
<button type="button" class="btn btn-info mt-2 mb-3 fido2-sdk-btn fido2-sdk-btn-primary" id="fido2AddDeviceBtn">
${this.i18n.getText('btn_add')}
</button>
` : ''}
<div class="table-responsive mt-2">
<table class="table table-striped fido2-sdk-table">
<thead>
<tr>
<th>${this.i18n.getText('title_device')}</th>
<th>${this.i18n.getText('title_time')}</th>
${this.config.features.showDeleteButton ? `<th>${this.i18n.getText('title_act')}</th>` : ''}
</tr>
</thead>
<tbody id="fido2DevicesList">
<tr>
<td colspan="3" class="text-center fido2-sdk-text">${this.i18n.getText('title_empty_list')}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
`;
};
UIRenderer.prototype._getStandaloneHTML = function() {
const theme = this.config.theme;
const dm = window.Fido2UIManager ? window.Fido2UIManager.deviceManager : null;
const userId = dm ? dm.getEffectiveUserId() : (this.config.userId || '');
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${this.i18n.getText('my_devices')}</title>
<link rel="stylesheet" href="files/bootstrap.css">
<link rel="stylesheet" href="files/boxicons.css">
<link rel="stylesheet" href="files/fido2-ui-sdk.css">
</head>
<body class="fido2-sdk-standalone">
<div class="container fido2-sdk-container">
<div class="card fido2-sdk-card">
<div class="card-header fido2-sdk-header d-flex justify-content-between align-items-center">
<div>
${theme.logo ? `<img src="${theme.logo}" class="fido2-sdk-logo me-2" alt="Logo">` : ''}
<h4 class="mb-0 fido2-sdk-text">${this.i18n.getText('my_devices')}</h4>
</div>
${this.config.features.showSessionStatus ? '<span class="badge fido2-sdk-status-badge" id="fido2SessionStatus"></span>' : ''}
</div>
<div class="card-body fido2-sdk-body">
${this.config.features.showUserInfo && userId ? `
<div class="alert alert-info fido2-sdk-user-info fido2-sdk-text">
<strong>${this.i18n.getText('title_welcome')}:</strong> ${userId}
</div>
` : ''}
${this.config.features.showAddButton ? `
<button type="button" class="btn btn-info mt-2 mb-3 fido2-sdk-btn fido2-sdk-btn-primary" id="fido2AddDeviceBtn">
${this.i18n.getText('btn_add')}
</button>
` : ''}
<div class="table-responsive mt-2">
<table class="table table-striped fido2-sdk-table">
<thead>
<tr>
<th>${this.i18n.getText('title_device')}</th>
<th>${this.i18n.getText('title_time')}</th>
${this.config.features.showDeleteButton ? `<th>${this.i18n.getText('title_act')}</th>` : ''}
</tr>
</thead>
<tbody id="fido2DevicesList">
<tr>
<td colspan="3" class="text-center fido2-sdk-text">${this.i18n.getText('title_empty_list')}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
`;
};
function Fido2UIManager() {
this.config = null;
@@ -1888,11 +2037,7 @@
const mode = manager.config.mode;
if (mode === 'standalone') {
manager.uiRenderer.renderStandalone();
} else {
manager.uiRenderer.renderModal();
}
manager.uiRenderer.renderModal();
manager._bindInternalEvents();
manager._loadInitialData();
@@ -1944,6 +2089,43 @@
self.uiRenderer.updateSessionStatus(isValid);
});
this.eventManager.on('startRecovery', async () => {
const recoveryBtn = document.querySelector('[id^="fido2StartRecoveryBtn_"]');
if (recoveryBtn) recoveryBtn.disabled = true;
try {
const result = await self.deviceManager.finishRecovery();
if (result.success) {
alert(self.i18n.getText('msg_recovery_success'));
self.uiRenderer.updateDevicesList(self.deviceManager.devices);
await self.deviceManager.checkSession();
self.uiRenderer.updateSessionStatus(self.deviceManager.sessionStatus);
}
} catch (error) {
console.error('Recovery error:', error);
alert(error.message || self.i18n.getText('msg_recovery_failed'));
} finally {
if (recoveryBtn) recoveryBtn.disabled = false;
}
});
this.eventManager.on('cancelRecovery', async () => {
self.deviceManager.cancelRecovery();
self.close();
});
this.eventManager.on('recoveryStarted', (user) => {
console.log('Recovery started for user:', user);
self.uiRenderer.updateRecoveryUI();
});
this.eventManager.on('recoveryCompleted', (result) => {
console.log('Recovery completed:', result);
});
this.eventManager.on('recoveryCanceled', (user) => {
console.log('Recovery canceled for user:', user);
});
this.eventManager.on('error', (error) => {
console.error('FIDO2 SDK Error:', error);
});
@@ -1951,10 +2133,21 @@
Fido2UIManager.prototype._loadInitialData = async function() {
try {
await this.deviceManager.loadDevices();
await this.deviceManager.checkSession();
if (this.config.recoverySessionId) {
await this.deviceManager.startRecovery(this.config.recoverySessionId);
this.uiRenderer.cleanup();
this.uiRenderer.renderModal();
this._bindInternalEvents();
} else {
await this.deviceManager.loadDevices();
await this.deviceManager.checkSession();
}
} catch (error) {
console.error('Initial data load error:', error);
if (this.config.recoverySessionId) {
alert(error.message || this.i18n.getText('msg_recovery_failed'));
this.close();
}
}
};
@@ -1990,6 +2183,39 @@
this.initialized = false;
};
Fido2UIManager.prototype.renderDeviceManagerWithRecovery = function(config) {
const recoveryConfig = Object.assign({}, config, {
recoverySessionId: config.recoverySessionId || config.recoverySessionId
});
return this.renderDeviceManager(recoveryConfig);
};
Fido2UIManager.prototype.renderFromUrlParams = function(config) {
const url = new URL(window.location.href);
const params = url.searchParams;
const regSessionId = params.get('rid');
if (regSessionId) {
return this.renderDeviceManagerWithRecovery(Object.assign({}, config, {
recoverySessionId: regSessionId
}));
} else {
return this.renderDeviceManager(config);
}
};
Fido2UIManager.prototype.startRecovery = function(recoverySessionId, displayName) {
return this.deviceManager.finishRecovery(displayName);
};
Fido2UIManager.prototype.isRecoveryMode = function() {
return this.deviceManager ? this.deviceManager.isInRecoveryMode() : false;
};
Fido2UIManager.prototype.getRecoveryUser = function() {
return this.deviceManager ? this.deviceManager.getRecoveryUser() : null;
};
Fido2UIManager.prototype.renderLogin = function(config) {
if (!window.bootstrap) {
throw new Error('Bootstrap is required. Please include Bootstrap JS before fido2-ui-sdk.js');
@@ -2005,6 +2231,8 @@
window.Fido2UIManager = new Fido2UIManager();
window.Fido2UIManager.renderDeviceManager = Fido2UIManager.prototype.renderDeviceManager;
window.Fido2UIManager.renderLogin = Fido2UIManager.prototype.renderLogin;
window.Fido2UIManager.renderDeviceManagerWithRecovery = Fido2UIManager.prototype.renderDeviceManagerWithRecovery;
window.Fido2UIManager.renderFromUrlParams = Fido2UIManager.prototype.renderFromUrlParams;
window.Fido2UIManager.close = function() {
if (window.Fido2UIManager && window.Fido2UIManager.close) {
window.Fido2UIManager.close();
@@ -2025,6 +2253,24 @@
window.Fido2UIManager.destroy();
}
};
window.Fido2UIManager.isRecoveryMode = function() {
if (window.Fido2UIManager && window.Fido2UIManager.isRecoveryMode) {
return window.Fido2UIManager.isRecoveryMode();
}
return false;
};
window.Fido2UIManager.getRecoveryUser = function() {
if (window.Fido2UIManager && window.Fido2UIManager.getRecoveryUser) {
return window.Fido2UIManager.getRecoveryUser();
}
return null;
};
window.Fido2UIManager.startRecovery = function(recoverySessionId, displayName) {
if (window.Fido2UIManager && window.Fido2UIManager.startRecovery) {
return window.Fido2UIManager.startRecovery(recoverySessionId, displayName);
}
return Promise.reject(new Error('Recovery not initialized'));
};
console.log('FIDO2 UI SDK v' + FIDO2_UI_VERSION + ' loaded');
})(window);