mirror of
https://github.com/Bubka/2FAuth.git
synced 2025-06-19 11:26:48 +02:00
Set up the Start view
This commit is contained in:
parent
bde05233c5
commit
c389378dc3
@ -210,12 +210,12 @@ class Form {
|
||||
* @param {Object} config (axios config)
|
||||
* @return {Promise}
|
||||
*/
|
||||
upload (url, formData, config = {}) {
|
||||
upload (url, config = {}) {
|
||||
this.startProcessing()
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// (Form.axios || axios).request({ url: this.route(url), method, data, ...config })
|
||||
this.axios.request({ url: this.route(url), method: 'post', data: formData, header: {'Content-Type' : 'multipart/form-data'}, ...config })
|
||||
// https://www.npmjs.com/package/axios#-automatic-serialization-to-formdata
|
||||
this.axios.post(this.route(url), this.data(), { headers: {'Content-Type' : 'multipart/form-data'}, ...config })
|
||||
.then(response => {
|
||||
this.finishProcessing()
|
||||
|
||||
@ -227,9 +227,9 @@ class Form {
|
||||
if (error.response) {
|
||||
this.errors.set(this.extractErrors(error.response))
|
||||
}
|
||||
if (error.response?.status != 422) {
|
||||
// if (error.response?.status != 422) {
|
||||
reject(error)
|
||||
}
|
||||
// }
|
||||
})
|
||||
})
|
||||
}
|
||||
|
18
resources/js_vue3/router/index.js
vendored
18
resources/js_vue3/router/index.js
vendored
@ -2,12 +2,12 @@ import { createRouter, createWebHistory } from 'vue-router'
|
||||
import middlewarePipeline from "@/router/middlewarePipeline";
|
||||
import { useUserStore } from '@/stores/user'
|
||||
|
||||
// import Start from './views/Start.vue'
|
||||
// import Capture from './views/Capture.vue'
|
||||
import Start from '../views/Start.vue'
|
||||
import Accounts from '../views/Accounts.vue'
|
||||
// import CreateAccount from './views/twofaccounts/Create.vue'
|
||||
import Capture from '../views/twofaccounts/Capture.vue'
|
||||
import CreateAccount from '../views/twofaccounts/Create.vue'
|
||||
// import EditAccount from './views/twofaccounts/Edit.vue'
|
||||
// import ImportAccount from './views/twofaccounts/Import.vue'
|
||||
import ImportAccount from '../views/twofaccounts/Import.vue'
|
||||
// import QRcodeAccount from './views/twofaccounts/QRcode.vue'
|
||||
// import Groups from './views/Groups.vue'
|
||||
// import CreateGroup from './views/groups/Create.vue'
|
||||
@ -33,12 +33,12 @@ import noEmptyError from './middlewares/noEmptyError'
|
||||
const router = createRouter({
|
||||
history: createWebHistory('/'),
|
||||
routes: [
|
||||
// { path: '/start', name: 'start', component: Start, meta: { middlewares: [authGuard] }, props: true },
|
||||
// { path: '/capture', name: 'capture', component: Capture, meta: { middlewares: [authGuard] }, props: true },
|
||||
{ path: '/start', name: 'start', component: Start, meta: { middlewares: [authGuard] } },
|
||||
{ path: '/capture', name: 'capture', component: Capture, meta: { middlewares: [authGuard] } },
|
||||
|
||||
{ path: '/accounts', name: 'accounts', component: Accounts, meta: { middlewares: [authGuard] }, alias: '/', props: true },
|
||||
// { path: '/account/create', name: 'createAccount', component: CreateAccount, meta: { middlewares: [authGuard] } },
|
||||
// { path: '/account/import', name: 'importAccounts', component: ImportAccount, meta: { middlewares: [authGuard] } },
|
||||
{ path: '/accounts', name: 'accounts', component: Accounts, meta: { middlewares: [authGuard] }, alias: '/' },
|
||||
{ path: '/account/create', name: 'createAccount', component: CreateAccount, meta: { middlewares: [authGuard] } },
|
||||
{ path: '/account/import', name: 'importAccounts', component: ImportAccount, meta: { middlewares: [authGuard] } },
|
||||
// { path: '/account/:twofaccountId/edit', name: 'editAccount', component: EditAccount, meta: { middlewares: [authGuard] } },
|
||||
// { path: '/account/:twofaccountId/qrcode', name: 'showQRcode', component: QRcodeAccount, meta: { middlewares: [authGuard] } },
|
||||
|
||||
|
19
resources/js_vue3/stores/bus.js
vendored
Normal file
19
resources/js_vue3/stores/bus.js
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useBusStore = defineStore({
|
||||
id: 'bus',
|
||||
|
||||
state: () => {
|
||||
return {
|
||||
migrationUri: null,
|
||||
decodedUri: null,
|
||||
goBackTo: null,
|
||||
returnTo: null,
|
||||
initialEditMode: null,
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
||||
},
|
||||
})
|
16
resources/js_vue3/stores/data.js
vendored
Normal file
16
resources/js_vue3/stores/data.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useDataStore = defineStore({
|
||||
id: 'data',
|
||||
|
||||
state: () => {
|
||||
return {
|
||||
twofaccounts: [],
|
||||
groups: [],
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
||||
},
|
||||
})
|
123
resources/js_vue3/views/Start.vue
Normal file
123
resources/js_vue3/views/Start.vue
Normal file
@ -0,0 +1,123 @@
|
||||
<script setup>
|
||||
import Form from '@/components/formElements/Form'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { useBusStore } from '@/stores/bus'
|
||||
import { useDataStore } from '@/stores/data'
|
||||
import { useNotifyStore } from '@/stores/notify'
|
||||
import { UseColorMode } from '@vueuse/components'
|
||||
|
||||
const router = useRouter()
|
||||
const user = useUserStore()
|
||||
const bus = useBusStore()
|
||||
const notify = useNotifyStore()
|
||||
const data = useDataStore()
|
||||
const { twofaccounts } = storeToRefs(data)
|
||||
|
||||
const qrcodeInput = ref(null)
|
||||
const qrcodeInputLabel = ref(null)
|
||||
const form = reactive(new Form({
|
||||
qrcode: null,
|
||||
inputFormat: 'fileUpload',
|
||||
}))
|
||||
|
||||
|
||||
/**
|
||||
* Upload the submitted QR code file to the backend for decoding, then route the user
|
||||
* to the Create or Import form with decoded URI to prefill the form
|
||||
*/
|
||||
function submitQrCode() {
|
||||
form.qrcode = qrcodeInput.value.files[0]
|
||||
|
||||
form.upload('/api/v1/qrcode/decode', { returnError: true }).then(response => {
|
||||
console.log(response.data)
|
||||
if (response.data.data.slice(0, 33).toLowerCase() === "otpauth-migration://offline?data=") {
|
||||
bus.migrationUri = response.data.data
|
||||
router.push({ name: 'importAccounts' })
|
||||
}
|
||||
else {
|
||||
bus.decodedUri = response.data.data
|
||||
router.push({ name: 'createAccount' })
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
notify.alert({ text: trans(error.response.data.message) })
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Push user to the dedicated capture view for live scan
|
||||
*/
|
||||
function capture() {
|
||||
router.push({ name: 'capture' });
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if( user.preferences.useDirectCapture && user.preferences.defaultCaptureMode === 'upload' ) {
|
||||
qrcodeInputLabel.value.click()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- static landing UI -->
|
||||
<div class="container has-text-centered">
|
||||
<div class="columns quick-uploader">
|
||||
<!-- trailer phrase that invite to add an account -->
|
||||
<div class="column is-full quick-uploader-header" :class="{ 'is-invisible' : twofaccounts.length !== 0 }">
|
||||
{{ $t('twofaccounts.no_account_here') }}<br>
|
||||
{{ $t('twofaccounts.add_first_account') }}
|
||||
</div>
|
||||
<!-- Livescan button -->
|
||||
<div class="column is-full quick-uploader-button" >
|
||||
<div class="quick-uploader-centerer">
|
||||
<!-- upload a qr code (with basic file field and backend decoding) -->
|
||||
<label role="button" tabindex="0" v-if="user.preferences.useBasicQrcodeReader" class="button is-link is-medium is-rounded is-main" ref="qrcodeInputLabel" @keyup.enter="qrcodeInputLabel.click()">
|
||||
<input aria-hidden="true" tabindex="-1" class="file-input" type="file" accept="image/*" v-on:change="submitQrCode" ref="qrcodeInput">
|
||||
{{ $t('twofaccounts.forms.upload_qrcode') }}
|
||||
</label>
|
||||
<!-- scan button that launch camera stream -->
|
||||
<button v-else class="button is-link is-medium is-rounded is-main" @click="capture()">
|
||||
{{ $t('twofaccounts.forms.scan_qrcode') }}
|
||||
</button>
|
||||
<FieldError v-if="form.hasAny" :error="form.errors.get('qrcode')" :field="'qrcode'" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- alternative methods -->
|
||||
<div class="column is-full">
|
||||
<UseColorMode v-slot="{ mode }">
|
||||
<div class="block" :class="mode == 'dark' ? 'has-text-light':'has-text-grey-dark'">{{ $t('twofaccounts.forms.alternative_methods') }}</div>
|
||||
</UseColorMode>
|
||||
<!-- upload a qr code -->
|
||||
<div class="block has-text-link" v-if="!user.preferences.useBasicQrcodeReader">
|
||||
<label role="button" tabindex="0" class="button is-link is-outlined is-rounded" ref="qrcodeInputLabel" @keyup.enter="qrcodeInputLabel.click()">
|
||||
<input aria-hidden="true" tabindex="-1" class="file-input" type="file" accept="image/*" v-on:change="submitQrCode" ref="qrcodeInput">
|
||||
{{ $t('twofaccounts.forms.upload_qrcode') }}
|
||||
</label>
|
||||
</div>
|
||||
<!-- link to advanced form -->
|
||||
<div class="block has-text-link">
|
||||
<RouterLink class="button is-link is-outlined is-rounded" :to="{ name: 'createAccount' }" >
|
||||
{{ $t('twofaccounts.forms.use_advanced_form') }}
|
||||
</RouterLink>
|
||||
</div>
|
||||
<!-- link to import view -->
|
||||
<div class="block has-text-link">
|
||||
<RouterLink id="btnImport" class="button is-link is-outlined is-rounded" :to="{ name: 'importAccounts' }" >
|
||||
{{ $t('twofaccounts.import.import') }}
|
||||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Footer -->
|
||||
<VueFooter :showButtons="true" >
|
||||
<!-- back button -->
|
||||
<p class="control" v-if="twofaccounts.length > 0">
|
||||
<UseColorMode v-slot="{ mode }">
|
||||
<RouterLink id="lnkBack" class="button is-rounded" :class="{'is-dark' : mode == 'dark'}" :to="{ name: 'accounts' }" >
|
||||
{{ $t('commons.back') }}
|
||||
</RouterLink>
|
||||
</UseColorMode>
|
||||
</p>
|
||||
</VueFooter>
|
||||
</div>
|
||||
</template>
|
Loading…
x
Reference in New Issue
Block a user