@adminforth/two-factors-auth 1.0.22 → 1.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/Changelog.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## [1.0.19] - 2024-12-02
2
+
3
+ ### Fixed
4
+
5
+ - Fixed copy hash for 2fa
1
6
 
2
7
  ## [1.0.18] - 2024-09-13
3
8
 
@@ -17,14 +17,13 @@
17
17
  <div class="my-4 flex justify-center items-center">
18
18
  <v-otp-input
19
19
  ref="code"
20
- input-classes="h-10 w-10 border border-[2px] rounded-md flex otp-input dark:bg-gray-700 dark:text-gray-400 font-bold"
20
+ input-classes="bg-gray-50 text-center flex justify-center otp-input border leading-none border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-10 h-10 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
21
21
  :conditionalClass="['one', 'two', 'three', 'four', 'five', 'six']"
22
22
  inputType="number"
23
23
  :num-inputs="6"
24
24
  v-model:value="bindValue"
25
25
  :should-auto-focus="true"
26
26
  :should-focus-order="true"
27
- @on-change="handleOnChange"
28
27
  @on-complete="handleOnComplete"
29
28
  />
30
29
  </div>
@@ -98,13 +97,12 @@
98
97
 
99
98
  onMounted(async () => {
100
99
  coreStore.getPublicConfig();
101
- window.addEventListener('keydown', handleKeydown);
100
+ window.addEventListener('paste', handlePaste);
102
101
  });
103
102
 
104
103
  onBeforeUnmount(() => {
105
- window.removeEventListener('keydown', handleKeydown);
104
+ window.removeEventListener('paste', handlePaste);
106
105
  });
107
-
108
106
 
109
107
  async function sendCode (value) {
110
108
  inProgress.value = true;
@@ -129,16 +127,14 @@
129
127
  // }
130
128
  // })
131
129
 
132
- function handleKeydown(event) {
133
- if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
134
- event.preventDefault();
135
- navigator.clipboard.readText().then((pastedData) => {
136
- if (pastedData) {
137
- fillInput(pastedData);
138
- }
139
- }).catch(err => {
140
- console.error('Failed to read clipboard contents: ', err);
141
- });
130
+ function handlePaste(event) {
131
+ event.preventDefault();
132
+ if (event.target.classList.contains('otp-input')) {
133
+ return;
134
+ }
135
+ const pastedText = event.clipboardData?.getData('text') || '';
136
+ if (pastedText.length === 6) {
137
+ code.value?.fillInput(pastedText);
142
138
  }
143
139
  }
144
140
  </script>
@@ -22,15 +22,15 @@
22
22
  <div class="w-full max-w-[46rem]">
23
23
  <div class="relative">
24
24
  <label for="npm-install-copy-text" class="sr-only">Label</label>
25
- <input id="npm-install-copy-text" type="text" class="col-span-10 bg-gray-50 border border-gray-300 text-gray-500 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full px-2.5 py-4 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500" :value="totp.newSecret" disabled readonly>
26
- <button data-copy-to-clipboard-target="npm-install-copy-text" class="absolute end-2.5 top-1/2 -translate-y-1/2 text-gray-900 dark:text-gray-400 hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-600 dark:hover:bg-gray-700 rounded-lg py-2 px-2.5 inline-flex items-center justify-center bg-white border-gray-200 border">
27
- <span id="default-message" class="inline-flex items-center">
25
+ <input id="npm-install-copy-text" type="text" class="col-span-10 bg-gray-50 border border-gray-300 text-gray-500 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full px-2.5 py-4 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500 pr-20" :value="totp.newSecret" readonly>
26
+ <button @click="onCopyClick" data-copy-to-clipboard-target="npm-install-copy-text" class="absolute end-2.5 top-1/2 -translate-y-1/2 text-gray-900 dark:text-gray-400 hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-600 dark:hover:bg-gray-700 rounded-lg py-2 px-2.5 inline-flex items-center justify-center bg-white border-gray-200 border">
27
+ <span v-if="isCopied === false" id="default-message" class="inline-flex items-center">
28
28
  <svg class="w-3 h-3 me-1.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 18 20">
29
29
  <path d="M16 1h-3.278A1.992 1.992 0 0 0 11 0H7a1.993 1.993 0 0 0-1.722 1H2a2 2 0 0 0-2 2v15a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2Zm-3 14H5a1 1 0 0 1 0-2h8a1 1 0 0 1 0 2Zm0-4H5a1 1 0 0 1 0-2h8a1 1 0 1 1 0 2Zm0-5H5a1 1 0 0 1 0-2h2V2h4v2h2a1 1 0 1 1 0 2Z"/>
30
30
  </svg>
31
- <span @click="onCopyClick" class="text-xs font-semibold">Copy</span>
31
+ <span class="text-xs font-semibold">Copy</span>
32
32
  </span>
33
- <span id="success-message" class="hidden inline-flex items-center">
33
+ <span v-if="isCopied === true" id="success-message" class="inline-flex items-center">
34
34
  <svg class="w-3 h-3 text-lightPrimary dark:text-darkPrimary me-1.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 12">
35
35
  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5.917 5.724 10.5 15 1.5"/>
36
36
  </svg>
@@ -43,7 +43,7 @@
43
43
  <div class="my-4 flex justify-center items-center">
44
44
  <v-otp-input
45
45
  ref="code"
46
- input-classes="h-10 w-10 border border-[2px] rounded-md flex otp-input dark:bg-gray-700 dark:text-gray-400 font-bold"
46
+ input-classes="bg-gray-50 text-center flex justify-center otp-input border leading-none border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-10 h-10 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
47
47
  :conditionalClass="['one', 'two', 'three', 'four', 'five', 'six']"
48
48
  inputType="number"
49
49
  :num-inputs="6"
@@ -52,7 +52,6 @@
52
52
  @on-complete="handleOnComplete"
53
53
  />
54
54
  </div>
55
-
56
55
  <!-- <Vue2FACodeInput v-model="code" autofocus /> -->
57
56
  <Button @click="()=>{router.push('./login')}"
58
57
  class="w-full">Cancel
@@ -67,7 +66,7 @@
67
66
  </template>
68
67
 
69
68
 
70
- <script setup>
69
+ <script setup lang="ts">
71
70
 
72
71
  import { onMounted, onBeforeUnmount, ref, watchEffect,computed,watch } from 'vue';
73
72
  import { useCoreStore } from '@/stores/core';
@@ -81,14 +80,11 @@ import Vue2FACodeInput from '@loltech/vue3-2fa-code-input';
81
80
  import VOtpInput from "vue3-otp-input";
82
81
 
83
82
  const code = ref(null);
83
+ const isCopied = ref<boolean>(false);
84
84
  const handleOnComplete = (value) => {
85
85
  sendCode(value);
86
86
  };
87
87
 
88
- const fillInput = (value) => {
89
- code.value?.fillInput(value);
90
- };
91
-
92
88
  const router = useRouter();
93
89
  const inProgress = ref(false);
94
90
 
@@ -97,9 +93,6 @@ const user = useUserStore();
97
93
 
98
94
  // use this simple function to automatically focus on the next input
99
95
 
100
-
101
-
102
-
103
96
  const showPw = ref(false);
104
97
 
105
98
  const error = ref(null);
@@ -129,16 +122,11 @@ function parseJwt(token) {
129
122
  }
130
123
 
131
124
  function onCopyClick(){
125
+ isCopied.value = true;
126
+ navigator.clipboard.writeText(totp.value.newSecret);
132
127
  window.adminforth.alert({message: 'Copied to clipboard', variant: 'success'})
133
128
  }
134
129
 
135
- // watch(code, async (nv)=>{
136
- // if (nv){
137
- // console.log(code.value);
138
- // sendCode();
139
- // }
140
- // })
141
-
142
130
  onMounted(async () => {
143
131
  coreStore.getPublicConfig()
144
132
  const resp = await callAdminForthApi({
@@ -151,11 +139,12 @@ onMounted(async () => {
151
139
 
152
140
  totp.value=parseJwt(totpJWT.value);
153
141
 
154
- window.addEventListener('keydown', handleKeydown);
142
+
143
+ window.addEventListener('paste', handlePaste);
155
144
  });
156
145
 
157
146
  onBeforeUnmount(() => {
158
- window.removeEventListener('keydown', handleKeydown);
147
+ window.removeEventListener('paste', handlePaste);
159
148
  });
160
149
 
161
150
  async function sendCode (value) {
@@ -178,22 +167,19 @@ async function sendCode (value) {
178
167
  }
179
168
 
180
169
 
181
- function handleKeydown(event) {
182
- if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
183
- event.preventDefault();
184
- navigator.clipboard.readText().then((pastedData) => {
185
- if (pastedData) {
186
- fillInput(pastedData);
187
- }
188
- }).catch(err => {
189
- console.error('Failed to read clipboard contents: ', err);
190
- });
170
+ function handlePaste(event) {
171
+ event.preventDefault();
172
+ if (event.target.classList.contains('otp-input')) {
173
+ return;
174
+ }
175
+ const pastedText = event.clipboardData?.getData('text') || '';
176
+ if (pastedText.length === 6) {
177
+ code.value?.fillInput(pastedText);
191
178
  }
192
179
  }
193
180
  </script>
194
181
  <style>
195
182
  .otp-input {
196
183
  margin: 0 5px;
197
-
198
184
  }
199
185
  </style>
@@ -17,14 +17,13 @@
17
17
  <div class="my-4 flex justify-center items-center">
18
18
  <v-otp-input
19
19
  ref="code"
20
- input-classes="h-10 w-10 border border-[2px] rounded-md flex otp-input dark:bg-gray-700 dark:text-gray-400 font-bold"
20
+ input-classes="bg-gray-50 text-center flex justify-center otp-input border leading-none border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-10 h-10 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
21
21
  :conditionalClass="['one', 'two', 'three', 'four', 'five', 'six']"
22
22
  inputType="number"
23
23
  :num-inputs="6"
24
24
  v-model:value="bindValue"
25
25
  :should-auto-focus="true"
26
26
  :should-focus-order="true"
27
- @on-change="handleOnChange"
28
27
  @on-complete="handleOnComplete"
29
28
  />
30
29
  </div>
@@ -98,13 +97,12 @@
98
97
 
99
98
  onMounted(async () => {
100
99
  coreStore.getPublicConfig();
101
- window.addEventListener('keydown', handleKeydown);
100
+ window.addEventListener('paste', handlePaste);
102
101
  });
103
102
 
104
103
  onBeforeUnmount(() => {
105
- window.removeEventListener('keydown', handleKeydown);
104
+ window.removeEventListener('paste', handlePaste);
106
105
  });
107
-
108
106
 
109
107
  async function sendCode (value) {
110
108
  inProgress.value = true;
@@ -129,16 +127,14 @@
129
127
  // }
130
128
  // })
131
129
 
132
- function handleKeydown(event) {
133
- if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
134
- event.preventDefault();
135
- navigator.clipboard.readText().then((pastedData) => {
136
- if (pastedData) {
137
- fillInput(pastedData);
138
- }
139
- }).catch(err => {
140
- console.error('Failed to read clipboard contents: ', err);
141
- });
130
+ function handlePaste(event) {
131
+ event.preventDefault();
132
+ if (event.target.classList.contains('otp-input')) {
133
+ return;
134
+ }
135
+ const pastedText = event.clipboardData?.getData('text') || '';
136
+ if (pastedText.length === 6) {
137
+ code.value?.fillInput(pastedText);
142
138
  }
143
139
  }
144
140
  </script>
@@ -22,15 +22,15 @@
22
22
  <div class="w-full max-w-[46rem]">
23
23
  <div class="relative">
24
24
  <label for="npm-install-copy-text" class="sr-only">Label</label>
25
- <input id="npm-install-copy-text" type="text" class="col-span-10 bg-gray-50 border border-gray-300 text-gray-500 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full px-2.5 py-4 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500" :value="totp.newSecret" disabled readonly>
26
- <button data-copy-to-clipboard-target="npm-install-copy-text" class="absolute end-2.5 top-1/2 -translate-y-1/2 text-gray-900 dark:text-gray-400 hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-600 dark:hover:bg-gray-700 rounded-lg py-2 px-2.5 inline-flex items-center justify-center bg-white border-gray-200 border">
27
- <span id="default-message" class="inline-flex items-center">
25
+ <input id="npm-install-copy-text" type="text" class="col-span-10 bg-gray-50 border border-gray-300 text-gray-500 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full px-2.5 py-4 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500 pr-20" :value="totp.newSecret" readonly>
26
+ <button @click="onCopyClick" data-copy-to-clipboard-target="npm-install-copy-text" class="absolute end-2.5 top-1/2 -translate-y-1/2 text-gray-900 dark:text-gray-400 hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-600 dark:hover:bg-gray-700 rounded-lg py-2 px-2.5 inline-flex items-center justify-center bg-white border-gray-200 border">
27
+ <span v-if="isCopied === false" id="default-message" class="inline-flex items-center">
28
28
  <svg class="w-3 h-3 me-1.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 18 20">
29
29
  <path d="M16 1h-3.278A1.992 1.992 0 0 0 11 0H7a1.993 1.993 0 0 0-1.722 1H2a2 2 0 0 0-2 2v15a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2Zm-3 14H5a1 1 0 0 1 0-2h8a1 1 0 0 1 0 2Zm0-4H5a1 1 0 0 1 0-2h8a1 1 0 1 1 0 2Zm0-5H5a1 1 0 0 1 0-2h2V2h4v2h2a1 1 0 1 1 0 2Z"/>
30
30
  </svg>
31
- <span @click="onCopyClick" class="text-xs font-semibold">Copy</span>
31
+ <span class="text-xs font-semibold">Copy</span>
32
32
  </span>
33
- <span id="success-message" class="hidden inline-flex items-center">
33
+ <span v-if="isCopied === true" id="success-message" class="inline-flex items-center">
34
34
  <svg class="w-3 h-3 text-lightPrimary dark:text-darkPrimary me-1.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 12">
35
35
  <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 5.917 5.724 10.5 15 1.5"/>
36
36
  </svg>
@@ -43,7 +43,7 @@
43
43
  <div class="my-4 flex justify-center items-center">
44
44
  <v-otp-input
45
45
  ref="code"
46
- input-classes="h-10 w-10 border border-[2px] rounded-md flex otp-input dark:bg-gray-700 dark:text-gray-400 font-bold"
46
+ input-classes="bg-gray-50 text-center flex justify-center otp-input border leading-none border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-10 h-10 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
47
47
  :conditionalClass="['one', 'two', 'three', 'four', 'five', 'six']"
48
48
  inputType="number"
49
49
  :num-inputs="6"
@@ -52,7 +52,6 @@
52
52
  @on-complete="handleOnComplete"
53
53
  />
54
54
  </div>
55
-
56
55
  <!-- <Vue2FACodeInput v-model="code" autofocus /> -->
57
56
  <Button @click="()=>{router.push('./login')}"
58
57
  class="w-full">Cancel
@@ -67,7 +66,7 @@
67
66
  </template>
68
67
 
69
68
 
70
- <script setup>
69
+ <script setup lang="ts">
71
70
 
72
71
  import { onMounted, onBeforeUnmount, ref, watchEffect,computed,watch } from 'vue';
73
72
  import { useCoreStore } from '@/stores/core';
@@ -81,14 +80,11 @@ import Vue2FACodeInput from '@loltech/vue3-2fa-code-input';
81
80
  import VOtpInput from "vue3-otp-input";
82
81
 
83
82
  const code = ref(null);
83
+ const isCopied = ref<boolean>(false);
84
84
  const handleOnComplete = (value) => {
85
85
  sendCode(value);
86
86
  };
87
87
 
88
- const fillInput = (value) => {
89
- code.value?.fillInput(value);
90
- };
91
-
92
88
  const router = useRouter();
93
89
  const inProgress = ref(false);
94
90
 
@@ -97,9 +93,6 @@ const user = useUserStore();
97
93
 
98
94
  // use this simple function to automatically focus on the next input
99
95
 
100
-
101
-
102
-
103
96
  const showPw = ref(false);
104
97
 
105
98
  const error = ref(null);
@@ -129,16 +122,11 @@ function parseJwt(token) {
129
122
  }
130
123
 
131
124
  function onCopyClick(){
125
+ isCopied.value = true;
126
+ navigator.clipboard.writeText(totp.value.newSecret);
132
127
  window.adminforth.alert({message: 'Copied to clipboard', variant: 'success'})
133
128
  }
134
129
 
135
- // watch(code, async (nv)=>{
136
- // if (nv){
137
- // console.log(code.value);
138
- // sendCode();
139
- // }
140
- // })
141
-
142
130
  onMounted(async () => {
143
131
  coreStore.getPublicConfig()
144
132
  const resp = await callAdminForthApi({
@@ -151,11 +139,12 @@ onMounted(async () => {
151
139
 
152
140
  totp.value=parseJwt(totpJWT.value);
153
141
 
154
- window.addEventListener('keydown', handleKeydown);
142
+
143
+ window.addEventListener('paste', handlePaste);
155
144
  });
156
145
 
157
146
  onBeforeUnmount(() => {
158
- window.removeEventListener('keydown', handleKeydown);
147
+ window.removeEventListener('paste', handlePaste);
159
148
  });
160
149
 
161
150
  async function sendCode (value) {
@@ -178,22 +167,19 @@ async function sendCode (value) {
178
167
  }
179
168
 
180
169
 
181
- function handleKeydown(event) {
182
- if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
183
- event.preventDefault();
184
- navigator.clipboard.readText().then((pastedData) => {
185
- if (pastedData) {
186
- fillInput(pastedData);
187
- }
188
- }).catch(err => {
189
- console.error('Failed to read clipboard contents: ', err);
190
- });
170
+ function handlePaste(event) {
171
+ event.preventDefault();
172
+ if (event.target.classList.contains('otp-input')) {
173
+ return;
174
+ }
175
+ const pastedText = event.clipboardData?.getData('text') || '';
176
+ if (pastedText.length === 6) {
177
+ code.value?.fillInput(pastedText);
191
178
  }
192
179
  }
193
180
  </script>
194
181
  <style>
195
182
  .otp-input {
196
183
  margin: 0 5px;
197
-
198
184
  }
199
185
  </style>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/two-factors-auth",
3
- "version": "1.0.22",
3
+ "version": "1.0.28",
4
4
  "description": "AdminForth plugin for two factors authentication",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
File without changes