diff --git a/apps/twofactor_backupcodes/src/service/BackupCodesService.js b/apps/twofactor_backupcodes/src/service/BackupCodesService.js deleted file mode 100644 index aab6c512921..00000000000 --- a/apps/twofactor_backupcodes/src/service/BackupCodesService.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import Axios from '@nextcloud/axios' -import { generateUrl } from '@nextcloud/router' - -/** - * - */ -export function generateCodes() { - const url = generateUrl('/apps/twofactor_backupcodes/settings/create') - - return Axios.post(url, {}).then((resp) => resp.data) -} diff --git a/apps/twofactor_backupcodes/src/service/BackupCodesService.ts b/apps/twofactor_backupcodes/src/service/BackupCodesService.ts new file mode 100644 index 00000000000..47a7b20e884 --- /dev/null +++ b/apps/twofactor_backupcodes/src/service/BackupCodesService.ts @@ -0,0 +1,28 @@ +/** + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import axios from '@nextcloud/axios' +import { generateUrl } from '@nextcloud/router' + +export interface ITwoFactorBackupCodesState { + enabled: boolean + total: number + used: number +} + +export interface IApiResponse { + codes: string[] + state: ITwoFactorBackupCodesState +} + +/** + * Generate new backup codes + */ +export async function generateCodes(): Promise { + const url = generateUrl('/apps/twofactor_backupcodes/settings/create') + + const { data } = await axios.post(url) + return data +} diff --git a/apps/twofactor_backupcodes/src/service/PrintService.js b/apps/twofactor_backupcodes/src/service/PrintService.js deleted file mode 100644 index 4575628744a..00000000000 --- a/apps/twofactor_backupcodes/src/service/PrintService.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -/** - * @param {any} data - - */ -export function print(data) { - const name = OC.theme.name || 'Nextcloud' - const newTab = window.open('', t('twofactor_backupcodes', '{name} backup codes', { name })) - newTab.document.write('

' + t('twofactor_backupcodes', '{name} backup codes', { name }) + '

') - newTab.document.write('
' + data + '
') - newTab.print() - newTab.close() -} diff --git a/apps/twofactor_backupcodes/src/service/PrintService.ts b/apps/twofactor_backupcodes/src/service/PrintService.ts new file mode 100644 index 00000000000..3ba72e56e0c --- /dev/null +++ b/apps/twofactor_backupcodes/src/service/PrintService.ts @@ -0,0 +1,39 @@ +/*! + * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import { getCapabilities } from '@nextcloud/capabilities' +import { showError } from '@nextcloud/dialogs' +import { t } from '@nextcloud/l10n' + +/** + * Open a new tab and print the given backup codes + * + * @param data - The backup codes to print + */ +export function print(data: string[]): void { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const name = (getCapabilities() as any).theming.name || 'Nextcloud' + const newTab = window.open('', t('twofactor_backupcodes', '{name} backup codes', { name })) + if (!newTab) { + showError(t('twofactor_backupcodes', 'Unable to open a new tab for printing')) + throw new Error('Unable to open a new tab for printing') + } + + const heading = newTab.document.createElement('h1') + heading.textContent = t('twofactor_backupcodes', '{name} backup codes', { name }) + const pre = newTab.document.createElement('pre') + for (const code of data) { + const codeLine = newTab.document.createTextNode(code) + pre.appendChild(codeLine) + pre.appendChild(newTab.document.createElement('br')) + } + + newTab.document.body.innerHTML = '' + newTab.document.body.appendChild(heading) + newTab.document.body.appendChild(pre) + + newTab.print() + newTab.close() +} diff --git a/apps/twofactor_backupcodes/src/logger.ts b/apps/twofactor_backupcodes/src/service/logger.ts similarity index 100% rename from apps/twofactor_backupcodes/src/logger.ts rename to apps/twofactor_backupcodes/src/service/logger.ts diff --git a/apps/twofactor_backupcodes/src/settings.js b/apps/twofactor_backupcodes/src/settings.js index 77c9b64ab52..466a698fe16 100644 --- a/apps/twofactor_backupcodes/src/settings.js +++ b/apps/twofactor_backupcodes/src/settings.js @@ -3,17 +3,17 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import { loadState } from '@nextcloud/initial-state' +import { createPinia, PiniaVuePlugin } from 'pinia' import Vue from 'vue' import PersonalSettings from './views/PersonalSettings.vue' -import store from './store.js' Vue.prototype.t = t +Vue.use(PiniaVuePlugin) -const initialState = loadState('twofactor_backupcodes', 'state') -store.replaceState(initialState) - +const pinia = createPinia() const View = Vue.extend(PersonalSettings) -new View({ - store, -}).$mount('#twofactor-backupcodes-settings') +const app = new View({ + pinia, +}) + +app.$mount('#twofactor-backupcodes-settings') diff --git a/apps/twofactor_backupcodes/src/store.js b/apps/twofactor_backupcodes/src/store.js deleted file mode 100644 index 127bb2b3385..00000000000 --- a/apps/twofactor_backupcodes/src/store.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors - * SPDX-License-Identifier: AGPL-3.0-or-later - */ - -import Vue from 'vue' -import Vuex, { Store } from 'vuex' -import { generateCodes } from './service/BackupCodesService.js' - -Vue.use(Vuex) - -const state = { - enabled: false, - total: 0, - used: 0, - codes: [], -} - -const mutations = { - setEnabled(state, enabled) { - Vue.set(state, 'enabled', enabled) - }, - setTotal(state, total) { - Vue.set(state, 'total', total) - }, - setUsed(state, used) { - Vue.set(state, 'used', used) - }, - setCodes(state, codes) { - Vue.set(state, 'codes', codes) - }, -} - -const actions = { - generate({ commit }) { - commit('setEnabled', false) - - return generateCodes().then(({ codes, state }) => { - commit('setEnabled', state.enabled) - commit('setTotal', state.total) - commit('setUsed', state.used) - commit('setCodes', codes) - return true - }) - }, -} - -export default new Store({ - strict: !PRODUCTION, - state, - mutations, - actions, -}) diff --git a/apps/twofactor_backupcodes/src/store/index.ts b/apps/twofactor_backupcodes/src/store/index.ts new file mode 100644 index 00000000000..e8531bf8d06 --- /dev/null +++ b/apps/twofactor_backupcodes/src/store/index.ts @@ -0,0 +1,42 @@ +/** + * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import type { ITwoFactorBackupCodesState } from '../service/BackupCodesService.ts' + +import { loadState } from '@nextcloud/initial-state' +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { generateCodes } from '../service/BackupCodesService.ts' + +const initialState = loadState('twofactor_backupcodes', 'state') + +export const useStore = defineStore('twofactor_backupcodes', () => { + const enabled = ref(initialState.enabled) + const total = ref(initialState.total) + const used = ref(initialState.used) + const codes = ref([]) + + /** + * Generate new backup codes and update the store state + */ + async function generate(): Promise { + enabled.value = false + + const { codes: newCodes, state } = await generateCodes() + enabled.value = state.enabled + total.value = state.total + used.value = state.used + codes.value = newCodes + } + + return { + enabled, + total, + used, + codes, + + generate, + } +}) diff --git a/apps/twofactor_backupcodes/src/views/PersonalSettings.vue b/apps/twofactor_backupcodes/src/views/PersonalSettings.vue index 28eb58bdb1a..347054ab1f5 100644 --- a/apps/twofactor_backupcodes/src/views/PersonalSettings.vue +++ b/apps/twofactor_backupcodes/src/views/PersonalSettings.vue @@ -59,11 +59,13 @@