mirror of
https://github.com/Bubka/2FAuth.git
synced 2025-02-13 09:00:56 +01:00
Add plain text field to the Import view - Closes #288
This commit is contained in:
parent
4ef3efd6ce
commit
4491852568
75
resources/js/components/formElements/FormTextarea.vue
Normal file
75
resources/js/components/formElements/FormTextarea.vue
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<script setup>
|
||||||
|
import { useIdGenerator } from '@/composables/helpers'
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
inheritAttrs: false
|
||||||
|
})
|
||||||
|
|
||||||
|
const { inputId } = useIdGenerator(props.inputType, props.fieldName)
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: [String, Number, Boolean],
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
fieldName: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
fieldError: [String],
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
help: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
hasOffset: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
isDisabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
maxLength: {
|
||||||
|
type: Number,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
isIndented: Boolean,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="mb-3" :class="{ 'pt-3' : hasOffset, 'is-flex' : isIndented }">
|
||||||
|
<div v-if="isIndented" class="mx-2 pr-1" :style="{ 'opacity': isDisabled ? '0.5' : '1' }">
|
||||||
|
<FontAwesomeIcon class="has-text-grey" :icon="['fas', 'chevron-right']" transform="rotate-135"/>
|
||||||
|
</div>
|
||||||
|
<div class="field" :class="{ 'is-flex-grow-5' : isIndented }">
|
||||||
|
<label :for="inputId" class="label" v-html="$t(label)"></label>
|
||||||
|
<div class="control" :class="{ 'has-icons-left' : leftIcon, 'has-icons-right': rightIcon }">
|
||||||
|
<textarea
|
||||||
|
:disabled="isDisabled"
|
||||||
|
:id="inputId"
|
||||||
|
class="textarea"
|
||||||
|
:class="size"
|
||||||
|
:value="modelValue"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
v-bind="$attrs"
|
||||||
|
v-on:input="$emit('update:modelValue', $event.target.value)"
|
||||||
|
v-on:change="$emit('change:modelValue', $event.target.value)"
|
||||||
|
:maxlength="maxLength"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<FieldError v-if="fieldError != undefined" :error="fieldError" :field="fieldName" />
|
||||||
|
<p class="help" v-html="$t(help)" v-if="help"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
2
resources/js/icons.js
vendored
2
resources/js/icons.js
vendored
@ -47,6 +47,7 @@ import {
|
|||||||
faVideoSlash,
|
faVideoSlash,
|
||||||
faChevronRight,
|
faChevronRight,
|
||||||
faSlash,
|
faSlash,
|
||||||
|
faAlignLeft,
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -109,6 +110,7 @@ library.add(
|
|||||||
faOpenid,
|
faOpenid,
|
||||||
faPaperPlane,
|
faPaperPlane,
|
||||||
faSlash,
|
faSlash,
|
||||||
|
faAlignLeft
|
||||||
);
|
);
|
||||||
|
|
||||||
export default FontAwesomeIcon
|
export default FontAwesomeIcon
|
@ -1,5 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import Form from '@/components/formElements/Form'
|
import Form from '@/components/formElements/Form'
|
||||||
|
import FormTextarea from '@/components/formElements/FormTextarea.vue'
|
||||||
import twofaccountService from '@/services/twofaccountService'
|
import twofaccountService from '@/services/twofaccountService'
|
||||||
import OtpDisplay from '@/components/OtpDisplay.vue'
|
import OtpDisplay from '@/components/OtpDisplay.vue'
|
||||||
import Spinner from '@/components/Spinner.vue'
|
import Spinner from '@/components/Spinner.vue'
|
||||||
@ -17,6 +18,8 @@
|
|||||||
const otpDisplay = ref(null)
|
const otpDisplay = ref(null)
|
||||||
const fileInput = ref(null)
|
const fileInput = ref(null)
|
||||||
const qrcodeInput = ref(null)
|
const qrcodeInput = ref(null)
|
||||||
|
const directInput = ref(null)
|
||||||
|
const directInputError = ref(null)
|
||||||
const form = reactive(new Form({
|
const form = reactive(new Form({
|
||||||
service: '',
|
service: '',
|
||||||
account: '',
|
account: '',
|
||||||
@ -86,6 +89,7 @@
|
|||||||
exportedAccounts.value.push(data)
|
exportedAccounts.value.push(data)
|
||||||
})
|
})
|
||||||
notifyValidAccountFound()
|
notifyValidAccountFound()
|
||||||
|
directInput.value = directInputError.value = null
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
notify.alert({ text: trans(error.response.data.message) })
|
notify.alert({ text: trans(error.response.data.message) })
|
||||||
@ -225,6 +229,18 @@
|
|||||||
notify.success({ text: trans('twofaccounts.import.x_valid_accounts_found', { count: importableCount.value }) })
|
notify.success({ text: trans('twofaccounts.import.x_valid_accounts_found', { count: importableCount.value }) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits the directInput form to the backend
|
||||||
|
*/
|
||||||
|
function submitDirectInput() {
|
||||||
|
directInputError.value = null
|
||||||
|
|
||||||
|
if (! directInput.value) {
|
||||||
|
directInputError.value = trans('validation.required', { attribute: 'Direct input' })
|
||||||
|
}
|
||||||
|
else migrate(directInput.value)
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -295,6 +311,33 @@
|
|||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="block">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="media">
|
||||||
|
<div class="media-left">
|
||||||
|
<figure class="image is-32x32">
|
||||||
|
<UseColorMode v-slot="{ mode }">
|
||||||
|
<FontAwesomeIcon :icon="['fas', 'align-left']" size="2x" :class="mode == 'dark' ? 'has-text-grey-darker' : 'has-text-grey-lighter'" />
|
||||||
|
</UseColorMode>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
<div class="media-content">
|
||||||
|
<p class="title is-5 has-text-grey" v-html="$t('twofaccounts.import.direct_input')" />
|
||||||
|
<p class="subtitle is-6 is-size-7-mobile">{{ $t('twofaccounts.import.expected_format_for_direct_input') }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<FormTextarea v-model="directInput" :fieldError="directInputError" fieldName="payload" rows="5" :size="'is-small'" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="card-footer">
|
||||||
|
<a role="button" tabindex="0" class="card-footer-item is-relative" @click.stop="submitDirectInput">
|
||||||
|
{{ $t('commons.submit') }}
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Supported migration resources -->
|
<!-- Supported migration resources -->
|
||||||
@ -331,6 +374,12 @@
|
|||||||
<td></td>
|
<td></td>
|
||||||
<td><FontAwesomeIcon :icon="['fas', 'circle-check']" /></td>
|
<td><FontAwesomeIcon :icon="['fas', 'circle-check']" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>FreeOTP+</th>
|
||||||
|
<td><FontAwesomeIcon :icon="['fas', 'circle-check']" /></td>
|
||||||
|
<td></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>2FAuth</th>
|
<th>2FAuth</th>
|
||||||
<td></td>
|
<td></td>
|
||||||
|
@ -143,9 +143,11 @@
|
|||||||
'scan' => 'Scan',
|
'scan' => 'Scan',
|
||||||
'supported_formats_for_qrcode_upload' => 'Accepted: jpg, jpeg, png, bmp, gif, svg, or webp',
|
'supported_formats_for_qrcode_upload' => 'Accepted: jpg, jpeg, png, bmp, gif, svg, or webp',
|
||||||
'supported_formats_for_file_upload' => 'Accepted: Plain text, json, 2fas',
|
'supported_formats_for_file_upload' => 'Accepted: Plain text, json, 2fas',
|
||||||
|
'expected_format_for_direct_input' => 'Expected: A list of otpauth URI, one by line',
|
||||||
'supported_migration_formats' => 'Supported migration formats',
|
'supported_migration_formats' => 'Supported migration formats',
|
||||||
'qr_code' => 'QR Code',
|
'qr_code' => 'QR Code',
|
||||||
'text_file' => 'Text file',
|
'text_file' => 'Text file',
|
||||||
|
'direct_input' => 'Direct input',
|
||||||
'plain_text' => 'Plain text',
|
'plain_text' => 'Plain text',
|
||||||
'parsing_data' => 'Parsing data...',
|
'parsing_data' => 'Parsing data...',
|
||||||
'issuer' => 'Issuer',
|
'issuer' => 'Issuer',
|
||||||
|
Loading…
Reference in New Issue
Block a user