profile: hasPasskey

This commit is contained in:
Girish Ramakrishnan
2026-03-16 17:20:22 +05:30
parent 1c8aa7440c
commit 67500a7689
5 changed files with 14 additions and 49 deletions
+3 -6
View File
@@ -459,12 +459,9 @@ onMounted(async () => {
ready.value = true;
// when done, redirect the user to setup 2fa if it is mandatory and neither totp (totpEnabled) nor passkey is setup
if (config.value.mandatory2FA && !profile.value.totpEnabled) {
const [error, result] = await profileModel.getPasskey();
if (error) return window.cloudron.onError(error);
if (!result) return window.location.href = VIEWS.PROFILE;
// when done, redirect the user to setup 2fa if it is mandatory and neither totp nor passkey is setup
if (config.value.mandatory2FA && !profile.value.totpEnabled && !profile.value.hasPasskey) {
return window.location.href = VIEWS.PROFILE;
}
});
-11
View File
@@ -234,17 +234,6 @@ function create() {
if (error || result.status !== 201) return [error || result];
return [null, result.body];
},
async getPasskey() {
let error, result;
try {
result = await fetcher.get(`${API_ORIGIN}/api/v1/profile/passkey`, { access_token: accessToken });
} catch (e) {
error = e;
}
if (error || result.status !== 200) return [error || result];
return [null, result.body.passkey];
},
async getPasskeyRegistrationOptions() {
let error, result;
try {
+8 -19
View File
@@ -100,15 +100,8 @@ async function onRevokeAllWebAndCliTokens() {
await profileModel.logout();
}
const userPasskey = ref(null);
const enableTwoFADialog = useTemplateRef('enableTwoFADialog');
const has2FA = computed(() => profile.value.totpEnabled || !!userPasskey.value);
async function loadPasskey() {
const [error, result] = await profileModel.getPasskey();
if (error) return console.error('Failed to load passkey', error);
userPasskey.value = result;
}
const has2FA = computed(() => profile.value.totpEnabled || profile.value.hasPasskey);
async function onOpenTwoFASetupDialog(method) {
enableTwoFADialog.value.open(method);
@@ -116,7 +109,6 @@ async function onOpenTwoFASetupDialog(method) {
async function onEnableTwoFASuccess() {
await refreshProfile();
await loadPasskey();
}
async function onTwoFADisable(method) {
@@ -125,7 +117,6 @@ async function onTwoFADisable(method) {
async function onTwoFADisableSuccess() {
await refreshProfile();
await loadPasskey();
}
// Init
@@ -161,10 +152,8 @@ onMounted(async () => {
webadminTokens.value = result.filter(function (c) { return c.clientId === TOKEN_TYPES.ID_WEBADMIN || c.clientId === TOKEN_TYPES.ID_DEVELOPMENT || c.clientId === 'dashboard' || c.clientId === 'development'; });
cliTokens.value = result.filter(function (c) { return c.clientId === TOKEN_TYPES.ID_CLI; });
await loadPasskey();
// check if we should show the 2fa setup
if (config.value.mandatory2FA && !profile.value.totpEnabled && !userPasskey.value) {
if (config.value.mandatory2FA && !profile.value.totpEnabled && !profile.value.hasPasskey) {
onOpenTwoFASetupDialog();
}
});
@@ -232,9 +221,9 @@ onMounted(async () => {
<FormGroup>
<label>{{ $t('profile.twoFactorAuth.totpTitle') }}</label>
<div v-if="profile.totpEnabled">{{ $t('profile.twoFactorAuth.totpEnabled') }}</div>
<div v-else>{{ $t('profile.notSet') }}</div>
<div v-else-if="profile.id">{{ $t('profile.notSet') }}</div>
</FormGroup>
<div style="display: flex; align-items: center">
<div v-if="profile.id" style="display: flex; align-items: center">
<Button tool plain v-if="profile.totpEnabled" @click="onTwoFADisable('totp')">{{ $t('main.action.disable') }}</Button>
<Button tool plain v-else @click="onOpenTwoFASetupDialog('totp')">{{ $t('main.action.setup') }}</Button>
</div>
@@ -243,11 +232,11 @@ onMounted(async () => {
<SettingsItem v-if="!profile.source || !config.external2FA">
<FormGroup>
<label>{{ $t('profile.twoFactorAuth.passkeyTitle') }}</label>
<div v-if="userPasskey">{{ $t('profile.twoFactorAuth.passkeyEnabled') }}</div>
<div v-else>{{ $t('profile.notSet') }}</div>
<div v-if="profile.hasPasskey">{{ $t('profile.twoFactorAuth.passkeyEnabled') }}</div>
<div v-else-if="profile.id">{{ $t('profile.notSet') }}</div>
</FormGroup>
<div style="display: flex; align-items: center">
<Button tool plain v-if="userPasskey" @click="onTwoFADisable('passkey')">{{ $t('main.action.disable') }}</Button>
<div v-if="profile.id" style="display: flex; align-items: center">
<Button tool plain v-if="profile.hasPasskey" @click="onTwoFADisable('passkey')">{{ $t('main.action.disable') }}</Button>
<Button tool plain v-else @click="onOpenTwoFASetupDialog('passkey')">{{ $t('main.action.setup') }}</Button>
</div>
</SettingsItem>