Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>pull/57515/head
parent
ab8e4e60ea
commit
108858daef
@ -1,32 +0,0 @@ |
||||
/** |
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-FileCopyrightText: 2014-2015 ownCloud, Inc. |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
/** |
||||
* @namespace OC |
||||
*/ |
||||
OC.Encryption = _.extend(OC.Encryption || {}, { |
||||
displayEncryptionWarning: function() { |
||||
if (!OC.currentUser || !OC.Notification.isHidden()) { |
||||
return |
||||
} |
||||
|
||||
$.get( |
||||
OC.generateUrl('/apps/encryption/ajax/getStatus'), |
||||
function(result) { |
||||
if (result.status === 'interactionNeeded') { |
||||
OC.Notification.show(result.data.message) |
||||
} |
||||
}, |
||||
) |
||||
}, |
||||
}) |
||||
window.addEventListener('DOMContentLoaded', function() { |
||||
// wait for other apps/extensions to register their event handlers and file actions
|
||||
// in the "ready" clause
|
||||
_.defer(function() { |
||||
OC.Encryption.displayEncryptionWarning() |
||||
}) |
||||
}) |
||||
@ -1,80 +0,0 @@ |
||||
/** |
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-FileCopyrightText: 2013-2015 ownCloud, Inc. |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
window.addEventListener('DOMContentLoaded', function() { |
||||
$('input:button[name="enableRecoveryKey"]').click(function() { |
||||
const recoveryStatus = $(this).attr('status') |
||||
const newRecoveryStatus = (1 + parseInt(recoveryStatus)) % 2 |
||||
const buttonValue = $(this).attr('value') |
||||
|
||||
const recoveryPassword = $('#encryptionRecoveryPassword').val() |
||||
const confirmPassword = $('#repeatEncryptionRecoveryPassword').val() |
||||
OC.msg.startSaving('#encryptionSetRecoveryKey .msg') |
||||
$.post( |
||||
OC.generateUrl('/apps/encryption/ajax/adminRecovery'), |
||||
{ |
||||
adminEnableRecovery: newRecoveryStatus, |
||||
recoveryPassword, |
||||
confirmPassword, |
||||
}, |
||||
).done(function(data) { |
||||
OC.msg.finishedSuccess('#encryptionSetRecoveryKey .msg', data.data.message) |
||||
|
||||
if (newRecoveryStatus === 0) { |
||||
$('p[name="changeRecoveryPasswordBlock"]').addClass('hidden') |
||||
$('input:button[name="enableRecoveryKey"]').attr('value', 'Enable recovery key') |
||||
$('input:button[name="enableRecoveryKey"]').attr('status', '0') |
||||
} else { |
||||
$('input:password[name="changeRecoveryPassword"]').val('') |
||||
$('p[name="changeRecoveryPasswordBlock"]').removeClass('hidden') |
||||
$('input:button[name="enableRecoveryKey"]').attr('value', 'Disable recovery key') |
||||
$('input:button[name="enableRecoveryKey"]').attr('status', '1') |
||||
} |
||||
}) |
||||
.fail(function(jqXHR) { |
||||
$('input:button[name="enableRecoveryKey"]').attr('value', buttonValue) |
||||
$('input:button[name="enableRecoveryKey"]').attr('status', recoveryStatus) |
||||
OC.msg.finishedError('#encryptionSetRecoveryKey .msg', JSON.parse(jqXHR.responseText).data.message) |
||||
}) |
||||
}) |
||||
|
||||
$('#repeatEncryptionRecoveryPassword').keyup(function(event) { |
||||
if (event.keyCode == 13) { |
||||
$('#enableRecoveryKey').click() |
||||
} |
||||
}) |
||||
|
||||
// change recovery password
|
||||
|
||||
$('button:button[name="submitChangeRecoveryKey"]').click(function() { |
||||
const oldRecoveryPassword = $('#oldEncryptionRecoveryPassword').val() |
||||
const newRecoveryPassword = $('#newEncryptionRecoveryPassword').val() |
||||
const confirmNewPassword = $('#repeatedNewEncryptionRecoveryPassword').val() |
||||
OC.msg.startSaving('#encryptionChangeRecoveryKey .msg') |
||||
$.post( |
||||
OC.generateUrl('/apps/encryption/ajax/changeRecoveryPassword'), |
||||
{ |
||||
oldPassword: oldRecoveryPassword, |
||||
newPassword: newRecoveryPassword, |
||||
confirmPassword: confirmNewPassword, |
||||
}, |
||||
).done(function(data) { |
||||
OC.msg.finishedSuccess('#encryptionChangeRecoveryKey .msg', data.data.message) |
||||
}) |
||||
.fail(function(jqXHR) { |
||||
OC.msg.finishedError('#encryptionChangeRecoveryKey .msg', JSON.parse(jqXHR.responseText).data.message) |
||||
}) |
||||
}) |
||||
|
||||
$('#encryptHomeStorage').change(function() { |
||||
$.post( |
||||
OC.generateUrl('/apps/encryption/ajax/setEncryptHomeStorage'), |
||||
{ |
||||
encryptHomeStorage: this.checked, |
||||
}, |
||||
) |
||||
}) |
||||
}) |
||||
@ -1,64 +0,0 @@ |
||||
/** |
||||
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-FileCopyrightText: 2013-2015 ownCloud, Inc. |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
OC.Encryption = _.extend(OC.Encryption || {}, { |
||||
updatePrivateKeyPassword: function() { |
||||
const oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val() |
||||
const newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val() |
||||
OC.msg.startSaving('#ocDefaultEncryptionModule .msg') |
||||
$.post( |
||||
OC.generateUrl('/apps/encryption/ajax/updatePrivateKeyPassword'), |
||||
{ |
||||
oldPassword: oldPrivateKeyPassword, |
||||
newPassword: newPrivateKeyPassword, |
||||
}, |
||||
).done(function(data) { |
||||
OC.msg.finishedSuccess('#ocDefaultEncryptionModule .msg', data.message) |
||||
}).fail(function(jqXHR) { |
||||
OC.msg.finishedError('#ocDefaultEncryptionModule .msg', JSON.parse(jqXHR.responseText).message) |
||||
}) |
||||
}, |
||||
}) |
||||
|
||||
window.addEventListener('DOMContentLoaded', function() { |
||||
// Trigger ajax on recoveryAdmin status change
|
||||
$('input:radio[name="userEnableRecovery"]').change(function() { |
||||
const recoveryStatus = $(this).val() |
||||
OC.msg.startAction('#userEnableRecovery .msg', 'Updating recovery keys. This can take some time...') |
||||
$.post( |
||||
OC.generateUrl('/apps/encryption/ajax/userSetRecovery'), |
||||
{ |
||||
userEnableRecovery: recoveryStatus, |
||||
}, |
||||
).done(function(data) { |
||||
OC.msg.finishedSuccess('#userEnableRecovery .msg', data.data.message) |
||||
}) |
||||
.fail(function(jqXHR) { |
||||
OC.msg.finishedError('#userEnableRecovery .msg', JSON.parse(jqXHR.responseText).data.message) |
||||
}) |
||||
// Ensure page is not reloaded on form submit
|
||||
return false |
||||
}) |
||||
|
||||
// update private key password
|
||||
|
||||
$('input:password[name="changePrivateKeyPassword"]').keyup(function(event) { |
||||
const oldPrivateKeyPassword = $('input:password[id="oldPrivateKeyPassword"]').val() |
||||
const newPrivateKeyPassword = $('input:password[id="newPrivateKeyPassword"]').val() |
||||
if (newPrivateKeyPassword !== '' && oldPrivateKeyPassword !== '') { |
||||
$('button:button[name="submitChangePrivateKeyPassword"]').removeAttr('disabled') |
||||
if (event.which === 13) { |
||||
OC.Encryption.updatePrivateKeyPassword() |
||||
} |
||||
} else { |
||||
$('button:button[name="submitChangePrivateKeyPassword"]').attr('disabled', 'true') |
||||
} |
||||
}) |
||||
|
||||
$('button:button[name="submitChangePrivateKeyPassword"]').click(function() { |
||||
OC.Encryption.updatePrivateKeyPassword() |
||||
}) |
||||
}) |
||||
@ -0,0 +1,46 @@ |
||||
<!-- |
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
- SPDX-License-Identifier: AGPL-3.0-or-later |
||||
--> |
||||
|
||||
<script setup lang="ts"> |
||||
import axios from '@nextcloud/axios' |
||||
import { t } from '@nextcloud/l10n' |
||||
import { generateUrl } from '@nextcloud/router' |
||||
import { watchDebounced } from '@vueuse/core' |
||||
import { ref, watch } from 'vue' |
||||
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch' |
||||
|
||||
const encryptHomeStorage = defineModel<boolean>({ required: true }) |
||||
const isSavingHomeStorageEncryption = ref(false) |
||||
|
||||
watch(encryptHomeStorage, () => { |
||||
isSavingHomeStorageEncryption.value = true |
||||
}) |
||||
watchDebounced(encryptHomeStorage, async (encryptHomeStorage, oldValue) => { |
||||
if (encryptHomeStorage === oldValue) { |
||||
// user changed their mind (likely quickly toggled), do nothing |
||||
isSavingHomeStorageEncryption.value = false |
||||
return |
||||
} |
||||
|
||||
try { |
||||
await axios.post( |
||||
generateUrl('/apps/encryption/ajax/setEncryptHomeStorage'), |
||||
{ encryptHomeStorage }, |
||||
) |
||||
} finally { |
||||
isSavingHomeStorageEncryption.value = false |
||||
} |
||||
}, { debounce: 800 }) |
||||
</script> |
||||
|
||||
<template> |
||||
<NcCheckboxRadioSwitch |
||||
v-model="encryptHomeStorage" |
||||
:loading="isSavingHomeStorageEncryption" |
||||
:description="t('encryption', 'Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted')" |
||||
type="switch"> |
||||
{{ t('encryption', 'Encrypt the home storage') }} |
||||
</NcCheckboxRadioSwitch> |
||||
</template> |
||||
@ -0,0 +1,93 @@ |
||||
<!-- |
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
- SPDX-License-Identifier: AGPL-3.0-or-later |
||||
--> |
||||
|
||||
<script setup lang="ts"> |
||||
import axios from '@nextcloud/axios' |
||||
import { showSuccess } from '@nextcloud/dialogs' |
||||
import { t } from '@nextcloud/l10n' |
||||
import { generateUrl } from '@nextcloud/router' |
||||
import { computed, ref, useTemplateRef } from 'vue' |
||||
import NcButton from '@nextcloud/vue/components/NcButton' |
||||
import NcFormGroup from '@nextcloud/vue/components/NcFormGroup' |
||||
import NcNoteCard from '@nextcloud/vue/components/NcNoteCard' |
||||
import NcPasswordField from '@nextcloud/vue/components/NcPasswordField' |
||||
import { logger } from '../utils/logger.ts' |
||||
|
||||
const recoveryEnabled = defineModel<boolean>({ required: true }) |
||||
const formElement = useTemplateRef('form') |
||||
|
||||
const isLoading = ref(false) |
||||
const hasError = ref(false) |
||||
|
||||
const password = ref('') |
||||
const confirmPassword = ref('') |
||||
const passwordMatch = computed(() => password.value === confirmPassword.value) |
||||
|
||||
/** |
||||
* Handle the form submission to enable or disable the admin recovery key |
||||
*/ |
||||
async function onSubmit() { |
||||
if (isLoading.value) { |
||||
return |
||||
} |
||||
|
||||
if (!passwordMatch.value) { |
||||
return |
||||
} |
||||
|
||||
hasError.value = false |
||||
isLoading.value = true |
||||
try { |
||||
const { data } = await axios.post( |
||||
generateUrl('/apps/encryption/ajax/adminRecovery'), |
||||
{ |
||||
adminEnableRecovery: !recoveryEnabled.value, |
||||
recoveryPassword: password.value, |
||||
confirmPassword: confirmPassword.value, |
||||
}, |
||||
) |
||||
recoveryEnabled.value = !recoveryEnabled.value |
||||
password.value = confirmPassword.value = '' |
||||
formElement.value?.reset() |
||||
if (data.data.message) { |
||||
showSuccess(data.data.message) |
||||
} |
||||
} catch (error) { |
||||
hasError.value = true |
||||
logger.error('Failed to update recovery key settings', { error }) |
||||
} finally { |
||||
isLoading.value = false |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<form ref="form" @submit.prevent="onSubmit"> |
||||
<NcFormGroup |
||||
:label="recoveryEnabled ? t('encryption', 'Disable recovery key') : t('encryption', 'Enable recovery key')" |
||||
:description="t('encryption', 'The recovery key is an additional encryption key used to encrypt files. It is used to recover files from an account if the password is forgotten.')"> |
||||
<NcPasswordField |
||||
v-model="password" |
||||
required |
||||
name="password" |
||||
:label="t('encryption', 'Recovery key password')" /> |
||||
<NcPasswordField |
||||
v-model="confirmPassword" |
||||
required |
||||
name="confirmPassword" |
||||
:error="!!confirmPassword && !passwordMatch" |
||||
:helper-text="(passwordMatch || !confirmPassword) ? '' : t('encryption', 'Passwords do not match fields')" |
||||
:label="t('encryption', 'Repeat recovery key password')" /> |
||||
|
||||
<NcButton type="submit" :variant="recoveryEnabled ? 'error' : 'primary'"> |
||||
{{ recoveryEnabled ? t('encryption', 'Disable recovery key') : t('encryption', 'Enable recovery key') }} |
||||
</NcButton> |
||||
|
||||
<NcNoteCard v-if="hasError" type="error"> |
||||
{{ t('encryption', 'An error occurred while updating the recovery key settings. Please try again.') }} |
||||
</NcNoteCard> |
||||
</NcFormGroup> |
||||
</form> |
||||
</template> |
||||
@ -0,0 +1,98 @@ |
||||
<!-- |
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
- SPDX-License-Identifier: AGPL-3.0-or-later |
||||
--> |
||||
|
||||
<script setup lang="ts"> |
||||
import axios from '@nextcloud/axios' |
||||
import { t } from '@nextcloud/l10n' |
||||
import { generateUrl } from '@nextcloud/router' |
||||
import { computed, ref, useTemplateRef } from 'vue' |
||||
import NcButton from '@nextcloud/vue/components/NcButton' |
||||
import NcFormGroup from '@nextcloud/vue/components/NcFormGroup' |
||||
import NcNoteCard from '@nextcloud/vue/components/NcNoteCard' |
||||
import NcPasswordField from '@nextcloud/vue/components/NcPasswordField' |
||||
import { logger } from '../utils/logger.ts' |
||||
|
||||
const formElement = useTemplateRef('form') |
||||
|
||||
const isLoading = ref(false) |
||||
const hasError = ref(false) |
||||
|
||||
const oldPassword = ref('') |
||||
const password = ref('') |
||||
const confirmPassword = ref('') |
||||
const passwordMatch = computed(() => password.value === confirmPassword.value) |
||||
|
||||
/** |
||||
* Handle the form submission to change the admin recovery key password |
||||
*/ |
||||
async function onSubmit() { |
||||
if (isLoading.value) { |
||||
return |
||||
} |
||||
|
||||
if (!passwordMatch.value) { |
||||
return |
||||
} |
||||
|
||||
hasError.value = false |
||||
isLoading.value = true |
||||
try { |
||||
await axios.post( |
||||
generateUrl('/apps/encryption/ajax/changeRecoveryPassword'), |
||||
{ |
||||
oldPassword: oldPassword.value, |
||||
newPassword: password.value, |
||||
confirmPassword: confirmPassword.value, |
||||
}, |
||||
) |
||||
oldPassword.value = password.value = confirmPassword.value = '' |
||||
formElement.value?.reset() |
||||
} catch (error) { |
||||
hasError.value = true |
||||
logger.error('Failed to update recovery key settings', { error }) |
||||
} finally { |
||||
isLoading.value = false |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<form ref="form" :class="$style.settingsAdminRecoveryKeyChange" @submit.prevent="onSubmit"> |
||||
<NcFormGroup |
||||
:label="t('encryption', 'Change recovery key password')"> |
||||
<NcPasswordField |
||||
v-model="oldPassword" |
||||
required |
||||
name="oldPassword" |
||||
:label="t('encryption', 'Old recovery key password')" /> |
||||
<NcPasswordField |
||||
v-model="password" |
||||
required |
||||
name="password" |
||||
:label="t('encryption', 'New recovery key password')" /> |
||||
<NcPasswordField |
||||
v-model="confirmPassword" |
||||
required |
||||
name="confirmPassword" |
||||
:error="!passwordMatch && !!confirmPassword" |
||||
:helper-text="(passwordMatch || !confirmPassword) ? '' : t('encryption', 'Passwords do not match fields')" |
||||
:label="t('encryption', 'Repeat new recovery key password')" /> |
||||
|
||||
<NcButton type="submit" variant="primary"> |
||||
{{ t('encryption', 'Change recovery key password') }} |
||||
</NcButton> |
||||
|
||||
<NcNoteCard v-if="hasError" type="error"> |
||||
{{ t('encryption', 'An error occurred while changing the recovery key password. Please try again.') }} |
||||
</NcNoteCard> |
||||
</NcFormGroup> |
||||
</form> |
||||
</template> |
||||
|
||||
<style module> |
||||
.settingsAdminRecoveryKeyChange { |
||||
margin-top: var(--clickable-area-small); |
||||
} |
||||
</style> |
||||
@ -0,0 +1,80 @@ |
||||
<!-- |
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
- SPDX-License-Identifier: AGPL-3.0-or-later |
||||
--> |
||||
|
||||
<script setup lang="ts"> |
||||
import axios, { isAxiosError } from '@nextcloud/axios' |
||||
import { showError } from '@nextcloud/dialogs' |
||||
import { t } from '@nextcloud/l10n' |
||||
import { generateUrl } from '@nextcloud/router' |
||||
import { NcButton, NcFormGroup, NcNoteCard, NcPasswordField } from '@nextcloud/vue' |
||||
import { ref, useTemplateRef } from 'vue' |
||||
|
||||
defineProps<{ |
||||
recoveryEnabledForUser: boolean |
||||
}>() |
||||
|
||||
const emit = defineEmits<{ |
||||
updated: [] |
||||
}>() |
||||
|
||||
const formElement = useTemplateRef('form') |
||||
|
||||
const isLoading = ref(false) |
||||
const hasError = ref(false) |
||||
const oldPrivateKeyPassword = ref('') |
||||
const newPrivateKeyPassword = ref('') |
||||
|
||||
/** |
||||
* Handle the form submission to change the private key password |
||||
*/ |
||||
async function onSubmit() { |
||||
if (isLoading.value) { |
||||
return |
||||
} |
||||
|
||||
isLoading.value = true |
||||
hasError.value = false |
||||
try { |
||||
await axios.post( |
||||
generateUrl('/apps/encryption/ajax/updatePrivateKeyPassword'), |
||||
{ |
||||
oldPassword: oldPrivateKeyPassword.value, |
||||
newPassword: newPrivateKeyPassword.value, |
||||
}, |
||||
) |
||||
oldPrivateKeyPassword.value = newPrivateKeyPassword.value = '' |
||||
formElement.value?.reset() |
||||
emit('updated') |
||||
} catch (error) { |
||||
if (isAxiosError(error) && error.response && error.response.data?.data?.message) { |
||||
showError(error.response.data.data.message) |
||||
} |
||||
hasError.value = true |
||||
} finally { |
||||
isLoading.value = false |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<form ref="form" @submit.prevent="onSubmit"> |
||||
<NcFormGroup |
||||
:label="t('encryption', 'Update private key password')" |
||||
:description="t('encryption', 'Your private key password no longer matches your log-in password. Set your old private key password to your current log-in password.')"> |
||||
<NcNoteCard v-if="recoveryEnabledForUser"> |
||||
{{ t('encryption', 'If you do not remember your old password you can ask your administrator to recover your files.') }} |
||||
</NcNoteCard> |
||||
|
||||
<NcPasswordField :label="t('encryption', 'Old log-in password')" /> |
||||
<NcPasswordField :label="t('encryption', 'Current log-in password')" /> |
||||
|
||||
<NcButton |
||||
type="submit" |
||||
variant="primary"> |
||||
{{ t('encryption', 'Update') }} |
||||
</NcButton> |
||||
</NcFormGroup> |
||||
</form> |
||||
</template> |
||||
@ -0,0 +1,54 @@ |
||||
<!-- |
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
- SPDX-License-Identifier: AGPL-3.0-or-later |
||||
--> |
||||
|
||||
<script setup lang="ts"> |
||||
import axios, { isAxiosError } from '@nextcloud/axios' |
||||
import { showError, showLoading } from '@nextcloud/dialogs' |
||||
import { t } from '@nextcloud/l10n' |
||||
import { generateUrl } from '@nextcloud/router' |
||||
import { watchDebounced } from '@vueuse/core' |
||||
import { ref, watch } from 'vue' |
||||
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch' |
||||
|
||||
const userEnableRecovery = defineModel<boolean>({ required: true }) |
||||
const isLoading = ref(false) |
||||
|
||||
watch(userEnableRecovery, () => { |
||||
isLoading.value = true |
||||
}) |
||||
watchDebounced([userEnableRecovery], async ([newValue], [oldValue]) => { |
||||
if (newValue === oldValue) { |
||||
// user changed their mind (likely quickly toggled), do nothing |
||||
isLoading.value = false |
||||
return |
||||
} |
||||
|
||||
const toast = showLoading(t('encryption', 'Updating recovery keys. This can take some time…')) |
||||
try { |
||||
await axios.post( |
||||
generateUrl('/apps/encryption/ajax/userSetRecovery'), |
||||
{ userEnableRecovery: userEnableRecovery.value }, |
||||
) |
||||
} catch (error) { |
||||
userEnableRecovery.value = oldValue |
||||
if (isAxiosError(error) && error.response && error.response.data?.data?.message) { |
||||
showError(error.response.data.data.message) |
||||
} |
||||
} finally { |
||||
toast.hideToast() |
||||
isLoading.value = false |
||||
} |
||||
}, { debounce: 800 }) |
||||
</script> |
||||
|
||||
<template> |
||||
<NcCheckboxRadioSwitch |
||||
v-model="userEnableRecovery" |
||||
type="switch" |
||||
:loading="isLoading" |
||||
:description="t('encryption', 'Enabling this option will allow you to reobtain access to your encrypted files in case of password loss')"> |
||||
{{ t('encryption', 'Enable password recovery') }} |
||||
</NcCheckboxRadioSwitch> |
||||
</template> |
||||
@ -0,0 +1,21 @@ |
||||
/*! |
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
import { getCurrentUser } from '@nextcloud/auth' |
||||
import axios from '@nextcloud/axios' |
||||
import { showWarning } from '@nextcloud/dialogs' |
||||
import { generateUrl } from '@nextcloud/router' |
||||
|
||||
window.addEventListener('DOMContentLoaded', async function() { |
||||
if (getCurrentUser() === null) { |
||||
// skip for public pages
|
||||
return |
||||
} |
||||
|
||||
const { data } = await axios.get(generateUrl('/apps/encryption/ajax/getStatus')) |
||||
if (data.status === 'interactionNeeded') { |
||||
showWarning(data.data.message) |
||||
} |
||||
}) |
||||
@ -0,0 +1,10 @@ |
||||
/*! |
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
import { createApp } from 'vue' |
||||
import SettingsAdmin from './views/SettingsAdmin.vue' |
||||
|
||||
const app = createApp(SettingsAdmin) |
||||
app.mount('#encryption-settings-section') |
||||
@ -0,0 +1,10 @@ |
||||
/*! |
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
import { createApp } from 'vue' |
||||
import SettingsPersonal from './views/SettingsPersonal.vue' |
||||
|
||||
const app = createApp(SettingsPersonal) |
||||
app.mount('#encryption-settings-section') |
||||
@ -0,0 +1,10 @@ |
||||
/*! |
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
import { getLoggerBuilder } from '@nextcloud/logger' |
||||
|
||||
export const logger = getLoggerBuilder() |
||||
.setApp('encryption') |
||||
.build() |
||||
@ -0,0 +1,10 @@ |
||||
/*! |
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
export const InitStatus = Object.freeze({ |
||||
NotInitialized: '0', |
||||
InitExecuted: '1', |
||||
InitSuccessful: '2', |
||||
}) |
||||
@ -0,0 +1,40 @@ |
||||
<!-- |
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
- SPDX-License-Identifier: AGPL-3.0-or-later |
||||
--> |
||||
|
||||
<script setup lang="ts"> |
||||
import { loadState } from '@nextcloud/initial-state' |
||||
import { t } from '@nextcloud/l10n' |
||||
import { NcNoteCard, NcSettingsSection } from '@nextcloud/vue' |
||||
import { ref } from 'vue' |
||||
import SettingsAdminHomeStorage from '../components/SettingsAdminHomeStorage.vue' |
||||
import SettingsAdminRecoveryKey from '../components/SettingsAdminRecoveryKey.vue' |
||||
import SettingsAdminRecoveryKeyChange from '../components/SettingsAdminRecoveryKeyChange.vue' |
||||
import { InitStatus } from '../utils/types.ts' |
||||
|
||||
const adminSettings = loadState<{ |
||||
recoveryEnabled: boolean |
||||
masterKeyEnabled: boolean |
||||
encryptHomeStorage: boolean |
||||
initStatus: typeof InitStatus[keyof typeof InitStatus] |
||||
}>('encryption', 'adminSettings') |
||||
|
||||
const encryptHomeStorage = ref(adminSettings.encryptHomeStorage!) |
||||
const recoveryEnabled = ref(adminSettings.recoveryEnabled!) |
||||
</script> |
||||
|
||||
<template> |
||||
<NcSettingsSection :name="t('encryption', 'Default encryption module')"> |
||||
<NcNoteCard v-if="adminSettings.initStatus === InitStatus.NotInitialized && !adminSettings.masterKeyEnabled" type="warning"> |
||||
{{ t('encryption', 'Encryption app is enabled but your keys are not initialized, please log-out and log-in again') }} |
||||
</NcNoteCard> |
||||
|
||||
<template v-else> |
||||
<SettingsAdminHomeStorage v-model="encryptHomeStorage" /> |
||||
<br> |
||||
<SettingsAdminRecoveryKey v-if="adminSettings.masterKeyEnabled" v-model="recoveryEnabled" /> |
||||
<SettingsAdminRecoveryKeyChange v-if="adminSettings.masterKeyEnabled && recoveryEnabled" /> |
||||
</template> |
||||
</NcSettingsSection> |
||||
</template> |
||||
@ -0,0 +1,60 @@ |
||||
<!-- |
||||
- SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
- SPDX-License-Identifier: AGPL-3.0-or-later |
||||
--> |
||||
|
||||
<script setup lang="ts"> |
||||
import axios from '@nextcloud/axios' |
||||
import { showInfo } from '@nextcloud/dialogs' |
||||
import { loadState } from '@nextcloud/initial-state' |
||||
import { t } from '@nextcloud/l10n' |
||||
import { generateUrl } from '@nextcloud/router' |
||||
import { ref } from 'vue' |
||||
import NcNoteCard from '@nextcloud/vue/components/NcNoteCard' |
||||
import NcSettingsSection from '@nextcloud/vue/components/NcSettingsSection' |
||||
import SettingsPersonalChangePrivateKey from '../components/SettingsPersonalChangePrivateKey.vue' |
||||
import SettingsPersonalEnableRecovery from '../components/SettingsPersonalEnableRecovery.vue' |
||||
import { logger } from '../utils/logger.ts' |
||||
import { InitStatus } from '../utils/types.ts' |
||||
|
||||
const personalSettings = loadState<{ |
||||
recoveryEnabled: boolean |
||||
recoveryEnabledForUser: boolean |
||||
privateKeySet: boolean |
||||
initialized: typeof InitStatus[keyof typeof InitStatus] |
||||
}>('encryption', 'personalSettings') |
||||
|
||||
const initialized = ref(personalSettings.initialized) |
||||
const recoveryEnabledForUser = ref(personalSettings.recoveryEnabledForUser) |
||||
|
||||
/** |
||||
* Reload encryption status |
||||
*/ |
||||
async function reloadStatus() { |
||||
try { |
||||
const { data } = await axios.get(generateUrl('/apps/encryption/ajax/getStatus')) |
||||
initialized.value = data.initStatus |
||||
if (data.data.message) { |
||||
showInfo(data.data.message) |
||||
} |
||||
} catch (error) { |
||||
logger.error('Failed to fetch current encryption status', { error }) |
||||
} |
||||
} |
||||
</script> |
||||
|
||||
<template> |
||||
<NcSettingsSection :name="t('encryption', 'Basic encryption module')"> |
||||
<NcNoteCard v-if="initialized === InitStatus.NotInitialized" type="warning"> |
||||
{{ t('encryption', 'Encryption app is enabled but your keys are not initialized, please log-out and log-in again') }} |
||||
</NcNoteCard> |
||||
|
||||
<SettingsPersonalChangePrivateKey |
||||
v-else-if="initialized === InitStatus.InitExecuted" |
||||
:recovery-enabled-for-user |
||||
@updated="reloadStatus" /> |
||||
<SettingsPersonalEnableRecovery |
||||
v-else-if="personalSettings.recoveryEnabled && personalSettings.privateKeySet" |
||||
v-model="recoveryEnabledForUser" /> |
||||
</NcSettingsSection> |
||||
</template> |
||||
@ -1,83 +0,0 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc. |
||||
* SPDX-License-Identifier: AGPL-3.0-only |
||||
*/ |
||||
/** @var array $_ */ |
||||
/** @var \OCP\IL10N $l */ |
||||
\OCP\Util::addScript('encryption', 'settings-admin', 'core'); |
||||
style('encryption', 'settings-admin'); |
||||
?> |
||||
<form id="ocDefaultEncryptionModule" class="sub-section"> |
||||
<h3><?php p($l->t('Default encryption module')); ?></h3>
|
||||
<?php if (!$_['initStatus'] && $_['masterKeyEnabled'] === false): ?> |
||||
<?php p($l->t('Encryption app is enabled but your keys are not initialized, please log-out and log-in again')); ?> |
||||
<?php else: ?> |
||||
<p id="encryptHomeStorageSetting"> |
||||
<input type="checkbox" class="checkbox" name="encrypt_home_storage" id="encryptHomeStorage" |
||||
value="1" <?php if ($_['encryptHomeStorage']) { |
||||
print_unescaped('checked="checked"'); |
||||
} ?> /> |
||||
<label for="encryptHomeStorage"><?php p($l->t('Encrypt the home storage'));?></label></br>
|
||||
<em><?php p($l->t('Enabling this option encrypts all files stored on the main storage, otherwise only files on external storage will be encrypted')); ?></em>
|
||||
</p> |
||||
<br /> |
||||
<?php if ($_['masterKeyEnabled'] === false): ?> |
||||
<p id="encryptionSetRecoveryKey"> |
||||
<?php $_['recoveryEnabled'] === '0' ? p($l->t('Enable recovery key')) : p($l->t('Disable recovery key')); ?> |
||||
<span class="msg"></span> |
||||
<br/> |
||||
<em> |
||||
<?php p($l->t('The recovery key is an additional encryption key used to encrypt files. It is used to recover files from an account if the password is forgotten.')) ?> |
||||
</em> |
||||
<br/> |
||||
<input type="password" |
||||
name="encryptionRecoveryPassword" |
||||
id="encryptionRecoveryPassword" |
||||
placeholder="<?php p($l->t('Recovery key password')); ?>"/>
|
||||
<input type="password" |
||||
name="encryptionRecoveryPassword" |
||||
id="repeatEncryptionRecoveryPassword" |
||||
placeholder="<?php p($l->t('Repeat recovery key password')); ?>"/>
|
||||
<input type="button" |
||||
name="enableRecoveryKey" |
||||
id="enableRecoveryKey" |
||||
status="<?php p($_['recoveryEnabled']) ?>"
|
||||
value="<?php $_['recoveryEnabled'] === '0' ? p($l->t('Enable recovery key')) : p($l->t('Disable recovery key')); ?>"/>
|
||||
</p> |
||||
<br/><br/> |
||||
|
||||
<p name="changeRecoveryPasswordBlock" id="encryptionChangeRecoveryKey" <?php if ($_['recoveryEnabled'] === '0') { |
||||
print_unescaped('class="hidden"'); |
||||
}?>> |
||||
<?php p($l->t('Change recovery key password:')); ?> |
||||
<span class="msg"></span> |
||||
<br/> |
||||
<input |
||||
type="password" |
||||
name="changeRecoveryPassword" |
||||
id="oldEncryptionRecoveryPassword" |
||||
placeholder="<?php p($l->t('Old recovery key password')); ?>"/>
|
||||
<br /> |
||||
<input |
||||
type="password" |
||||
name="changeRecoveryPassword" |
||||
id="newEncryptionRecoveryPassword" |
||||
placeholder="<?php p($l->t('New recovery key password')); ?>"/>
|
||||
<input |
||||
type="password" |
||||
name="changeRecoveryPassword" |
||||
id="repeatedNewEncryptionRecoveryPassword" |
||||
placeholder="<?php p($l->t('Repeat new recovery key password')); ?>"/>
|
||||
|
||||
<button |
||||
type="button" |
||||
name="submitChangeRecoveryKey"> |
||||
<?php p($l->t('Change Password')); ?> |
||||
</button> |
||||
</p> |
||||
<?php endif; ?> |
||||
<?php endif; ?> |
||||
</form> |
||||
@ -1,79 +0,0 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-FileCopyrightText: 2016 ownCloud, Inc. |
||||
* SPDX-License-Identifier: AGPL-3.0-only |
||||
*/ |
||||
/** @var array $_ */ |
||||
/** @var \OCP\IL10N $l */ |
||||
\OCP\Util::addScript('encryption', 'settings-personal', 'core'); |
||||
?> |
||||
<form id="ocDefaultEncryptionModule" class="section"> |
||||
<h2 data-anchor-name="basic-encryption-module"><?php p($l->t('Basic encryption module')); ?></h2>
|
||||
|
||||
<?php if ($_['initialized'] === \OCA\Encryption\Session::NOT_INITIALIZED): ?> |
||||
|
||||
<?php p($l->t('Encryption App is enabled, but your keys are not initialized. Please log-out and log-in again.')); ?> |
||||
|
||||
<?php elseif ($_['initialized'] === \OCA\Encryption\Session::INIT_EXECUTED): ?> |
||||
<p> |
||||
<a name="changePKPasswd" /> |
||||
<label for="changePrivateKeyPasswd"> |
||||
<em><?php p($l->t('Your private key password no longer matches your log-in password.')); ?></em>
|
||||
</label> |
||||
<br /> |
||||
<?php p($l->t('Set your old private key password to your current log-in password:')); ?> |
||||
<?php if ($_['recoveryEnabledForUser']): |
||||
p(' ' . $l->t('If you do not remember your old password you can ask your administrator to recover your files.')); |
||||
endif; ?> |
||||
<br /> |
||||
<input |
||||
type="password" |
||||
name="changePrivateKeyPassword" |
||||
id="oldPrivateKeyPassword" /> |
||||
<label for="oldPrivateKeyPassword"><?php p($l->t('Old log-in password')); ?></label>
|
||||
<br /> |
||||
<input |
||||
type="password" |
||||
name="changePrivateKeyPassword" |
||||
id="newPrivateKeyPassword" /> |
||||
<label for="newRecoveryPassword"><?php p($l->t('Current log-in password')); ?></label>
|
||||
<br /> |
||||
<button |
||||
type="button" |
||||
name="submitChangePrivateKeyPassword" |
||||
disabled><?php p($l->t('Update Private Key Password')); ?> |
||||
</button> |
||||
<span class="msg"></span> |
||||
</p> |
||||
|
||||
<?php elseif ($_['recoveryEnabled'] && $_['privateKeySet'] && $_['initialized'] === \OCA\Encryption\Session::INIT_SUCCESSFUL): ?> |
||||
<br /> |
||||
<p id="userEnableRecovery"> |
||||
<label for="userEnableRecovery"><?php p($l->t('Enable password recovery:')); ?></label>
|
||||
<span class="msg"></span> |
||||
<br /> |
||||
<em><?php p($l->t('Enabling this option will allow you to reobtain access to your encrypted files in case of password loss')); ?></em>
|
||||
<br /> |
||||
<input |
||||
type="radio" |
||||
class="radio" |
||||
id="userEnableRecoveryCheckbox" |
||||
name="userEnableRecovery" |
||||
value="1" |
||||
<?php echo($_['recoveryEnabledForUser'] ? 'checked="checked"' : ''); ?> />
|
||||
<label for="userEnableRecoveryCheckbox"><?php p($l->t('Enabled')); ?></label>
|
||||
<br /> |
||||
|
||||
<input |
||||
type="radio" |
||||
class="radio" |
||||
id="userDisableRecoveryCheckbox" |
||||
name="userEnableRecovery" |
||||
value="0" |
||||
<?php echo($_['recoveryEnabledForUser'] === false ? 'checked="checked"' : ''); ?> />
|
||||
<label for="userDisableRecoveryCheckbox"><?php p($l->t('Disabled')); ?></label>
|
||||
</p> |
||||
<?php endif; ?> |
||||
</form> |
||||
@ -0,0 +1,10 @@ |
||||
<?php |
||||
|
||||
/** |
||||
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors |
||||
* SPDX-License-Identifier: AGPL-3.0-or-later |
||||
*/ |
||||
|
||||
?> |
||||
|
||||
<div id="encryption-settings-section"></div> |
||||
@ -0,0 +1 @@ |
||||
../../../apps/encryption |
||||
Loading…
Reference in new issue