-
-
-
-
-
-
- {{ $t('setting.passkeyAdd') }}
-
- {{ passkeyCountText }}
-
-
-
-
-
-
-
-
- {{ scope.row.lastUsedAt || '-' }}
-
-
-
-
-
- {{ $t('commons.button.delete') }}
+
+
+
+
+
+
+
+ {{ $t('setting.passkeyAdd') }}
-
-
-
+ {{ passkeyCountText }}
+
+
+
+
+
+
+ {{ scope.row.lastUsedAt || '-' }}
+
+
+
+
+
+ {{ $t('commons.button.delete') }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('commons.button.save') }}
+
+
+
+ {{ $t('setting.passkeyTrustedProxiesHelper') }}
+
+
+ {{ $t('setting.allowIPEgs') }}
+
+
+
+
+
{{ $t('commons.button.cancel') }}
@@ -38,10 +57,12 @@
import { computed, reactive, ref } from 'vue';
import { ElMessageBox } from 'element-plus';
import {
+ getSettingInfo,
passkeyRegisterBegin,
passkeyRegisterFinish,
passkeyList as fetchPasskeyList,
passkeyDelete,
+ updateSetting,
} from '@/api/modules/setting';
import i18n from '@/lang';
import { MsgError, MsgSuccess } from '@/utils/message';
@@ -49,16 +70,19 @@ import { Setting } from '@/api/interface/setting';
import { base64UrlToBuffer, bufferToBase64Url } from '@/utils/util';
interface DrawerParams {
- sslStatus: string;
+ bindDomain: string;
supported: boolean;
}
+const activeTab = ref('keys');
const drawerVisible = ref(false);
const passkeyLoading = ref(false);
+const savePasskeyProxyLoading = ref(false);
const passkeyList = ref([]);
const passkeyForm = reactive({ name: '' });
+const passkeyTrustedProxies = ref('');
const passkeySupported = ref(false);
-const sslStatus = ref('Disable');
+const hasBindDomain = ref(false);
const passkeyMaxCount = 5;
const passkeyCountText = computed(() => {
@@ -67,7 +91,7 @@ const passkeyCountText = computed(() => {
const canRegisterPasskey = computed(() => {
return (
- sslStatus.value !== 'Disable' &&
+ hasBindDomain.value &&
passkeySupported.value &&
passkeyList.value.length < passkeyMaxCount &&
passkeyForm.name.trim().length > 0
@@ -75,12 +99,22 @@ const canRegisterPasskey = computed(() => {
});
const acceptParams = async (params: DrawerParams) => {
- sslStatus.value = params.sslStatus;
+ hasBindDomain.value = params.bindDomain.trim().length > 0;
passkeySupported.value = params.supported;
drawerVisible.value = true;
+ await loadPasskeyTrustedProxies();
await loadPasskeys();
};
+const loadPasskeyTrustedProxies = async () => {
+ try {
+ const res = await getSettingInfo();
+ passkeyTrustedProxies.value = res.data.passkeyTrustedProxies || '';
+ } catch (error) {
+ passkeyTrustedProxies.value = '';
+ }
+};
+
const loadPasskeys = async () => {
passkeyLoading.value = true;
try {
@@ -94,7 +128,7 @@ const loadPasskeys = async () => {
};
const registerPasskey = async () => {
- if (sslStatus.value === 'Disable') {
+ if (!hasBindDomain.value) {
MsgError(i18n.global.t('setting.passkeyRequireSSL'));
return;
}
@@ -150,6 +184,18 @@ const removePasskey = async (id: string) => {
});
};
+const onSavePasskeyTrustedProxies = async () => {
+ savePasskeyProxyLoading.value = true;
+ await updateSetting({ key: 'PasskeyTrustedProxies', value: passkeyTrustedProxies.value })
+ .then(() => {
+ MsgSuccess(i18n.global.t('commons.msg.operationSuccess'));
+ loadPasskeyTrustedProxies();
+ })
+ .finally(() => {
+ savePasskeyProxyLoading.value = false;
+ });
+};
+
const normalizePasskeyCreation = (publicKey: Record): PublicKeyCredentialCreationOptions => {
const request = { ...publicKey };
request.challenge = base64UrlToBuffer(request.challenge);