@adminforth/two-factors-auth 1.7.0 → 1.8.1

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/build.log CHANGED
@@ -11,5 +11,5 @@ custom/package-lock.json
11
11
  custom/package.json
12
12
  custom/tsconfig.json
13
13
 
14
- sent 31,283 bytes received 134 bytes 62,834.00 bytes/sec
15
- total size is 30,790 speedup is 0.98
14
+ sent 31,322 bytes received 134 bytes 62,912.00 bytes/sec
15
+ total size is 30,836 speedup is 0.98
@@ -34,7 +34,7 @@
34
34
 
35
35
  <script setup lang="ts">
36
36
  import VOtpInput from 'vue3-otp-input';
37
- import { ref, nextTick, onMounted, onBeforeUnmount } from 'vue';
37
+ import { ref, nextTick, watch } from 'vue';
38
38
  import { useUserStore } from '@/stores/user';
39
39
  import { useI18n } from 'vue-i18n';
40
40
  declare global {
@@ -131,15 +131,19 @@
131
131
  emit('rejected', new Error('cancelled'));
132
132
  emit('closed');
133
133
  }
134
-
135
- onMounted(async () => {
134
+
135
+ watch(modelShow, async (open) => {
136
+ if (open) {
136
137
  await nextTick();
137
138
  tagOtpInputs();
138
- window.addEventListener('paste', handlePaste as any);
139
- });
140
- onBeforeUnmount(() => {
141
- window.removeEventListener('paste', handlePaste as any);
142
- });
139
+ console.log('adding paste listener');
140
+ window.addEventListener('paste', handlePaste);
141
+ } else {
142
+ console.log('re paste listener');
143
+ window.removeEventListener('paste', handlePaste);
144
+ }
145
+ });
146
+
143
147
  </script>
144
148
 
145
149
  <style scoped>
@@ -35,7 +35,7 @@
35
35
  <v-otp-input
36
36
  ref="code"
37
37
  container-class="grid grid-cols-6 gap-3 w-full"
38
- input-classes="otp-input bg-gray-50 text-center border leading-none border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block h-[46px] w-full 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"
38
+ input-classes="otp-input bg-gray-50 text-center border leading-none border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block h-11 w-full 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"
39
39
  :num-inputs="6"
40
40
  inputType="number"
41
41
  inputmode="numeric"
@@ -34,7 +34,7 @@
34
34
 
35
35
  <script setup lang="ts">
36
36
  import VOtpInput from 'vue3-otp-input';
37
- import { ref, nextTick, onMounted, onBeforeUnmount } from 'vue';
37
+ import { ref, nextTick, watch } from 'vue';
38
38
  import { useUserStore } from '@/stores/user';
39
39
  import { useI18n } from 'vue-i18n';
40
40
  declare global {
@@ -131,15 +131,19 @@
131
131
  emit('rejected', new Error('cancelled'));
132
132
  emit('closed');
133
133
  }
134
-
135
- onMounted(async () => {
134
+
135
+ watch(modelShow, async (open) => {
136
+ if (open) {
136
137
  await nextTick();
137
138
  tagOtpInputs();
138
- window.addEventListener('paste', handlePaste as any);
139
- });
140
- onBeforeUnmount(() => {
141
- window.removeEventListener('paste', handlePaste as any);
142
- });
139
+ console.log('adding paste listener');
140
+ window.addEventListener('paste', handlePaste);
141
+ } else {
142
+ console.log('re paste listener');
143
+ window.removeEventListener('paste', handlePaste);
144
+ }
145
+ });
146
+
143
147
  </script>
144
148
 
145
149
  <style scoped>
@@ -35,7 +35,7 @@
35
35
  <v-otp-input
36
36
  ref="code"
37
37
  container-class="grid grid-cols-6 gap-3 w-full"
38
- input-classes="otp-input bg-gray-50 text-center border leading-none border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block h-[46px] w-full 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"
38
+ input-classes="otp-input bg-gray-50 text-center border leading-none border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block h-11 w-full 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"
39
39
  :num-inputs="6"
40
40
  inputType="number"
41
41
  inputmode="numeric"
package/dist/index.js CHANGED
@@ -83,6 +83,9 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
83
83
  const userName = adminUser.dbUser[adminforth.config.auth.usernameField];
84
84
  const brandName = adminforth.config.customization.brandName;
85
85
  const brandNameSlug = adminforth.config.customization.brandNameSlug;
86
+ const issuerName = (this.options.customBrendPrefix && this.options.customBrendPrefix.trim())
87
+ ? this.options.customBrendPrefix.trim()
88
+ : brandName;
86
89
  const authResource = adminforth.config.resources.find((res) => res.resourceId === adminforth.config.auth.usersResourceId);
87
90
  const authPk = authResource.columns.find((col) => col.primaryKey).name;
88
91
  const userPk = adminUser.dbUser[authPk];
@@ -95,11 +98,11 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
95
98
  }
96
99
  const userCanSkipSetup = this.options.usersFilterToAllowSkipSetup ? this.options.usersFilterToAllowSkipSetup(adminUser) : false;
97
100
  if (!secret) {
98
- const tempSecret = twofactor.generateSecret({ name: brandName, account: userName });
101
+ const tempSecret = twofactor.generateSecret({ name: issuerName, account: userName });
99
102
  newSecret = tempSecret.secret;
100
103
  }
101
104
  else {
102
- const value = this.adminforth.auth.issueJWT({ userName, issuer: brandName, pk: userPk, userCanSkipSetup, rememberMeDays }, 'tempTotp', '2h');
105
+ const value = this.adminforth.auth.issueJWT({ userName, issuer: issuerName, pk: userPk, userCanSkipSetup, rememberMeDays }, 'tempTotp', '2h');
103
106
  response.setHeader('Set-Cookie', `adminforth_${brandNameSlug}_totpTemporaryJWT=${value}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; max-age=3600; `);
104
107
  return {
105
108
  body: {
@@ -109,7 +112,7 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
109
112
  ok: true
110
113
  };
111
114
  }
112
- const totpTemporaryJWT = this.adminforth.auth.issueJWT({ userName, newSecret, issuer: brandName, pk: userPk, userCanSkipSetup, rememberMeDays }, 'tempTotp', '2h');
115
+ const totpTemporaryJWT = this.adminforth.auth.issueJWT({ userName, newSecret, issuer: issuerName, pk: userPk, userCanSkipSetup, rememberMeDays }, 'tempTotp', '2h');
113
116
  response.setHeader('Set-Cookie', `adminforth_${brandNameSlug}_totpTemporaryJWT=${totpTemporaryJWT}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=${new Date(Date.now() + '1h').toUTCString()} `);
114
117
  return {
115
118
  body: {
package/index.ts CHANGED
@@ -93,6 +93,9 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
93
93
  const userName = adminUser.dbUser[adminforth.config.auth.usernameField]
94
94
  const brandName = adminforth.config.customization.brandName;
95
95
  const brandNameSlug = adminforth.config.customization.brandNameSlug;
96
+ const issuerName = (this.options.customBrendPrefix && this.options.customBrendPrefix.trim())
97
+ ? this.options.customBrendPrefix.trim()
98
+ : brandName;
96
99
  const authResource = adminforth.config.resources.find((res)=>res.resourceId === adminforth.config.auth.usersResourceId )
97
100
  const authPk = authResource.columns.find((col)=>col.primaryKey).name
98
101
  const userPk = adminUser.dbUser[authPk]
@@ -108,10 +111,10 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
108
111
  const userCanSkipSetup = this.options.usersFilterToAllowSkipSetup ? this.options.usersFilterToAllowSkipSetup(adminUser) : false;
109
112
 
110
113
  if (!secret){
111
- const tempSecret = twofactor.generateSecret({name: brandName,account: userName})
114
+ const tempSecret = twofactor.generateSecret({name: issuerName,account: userName})
112
115
  newSecret = tempSecret.secret
113
116
  } else {
114
- const value = this.adminforth.auth.issueJWT({userName, issuer:brandName, pk:userPk, userCanSkipSetup, rememberMeDays }, 'tempTotp', '2h');
117
+ const value = this.adminforth.auth.issueJWT({userName, issuer:issuerName, pk:userPk, userCanSkipSetup, rememberMeDays }, 'tempTotp', '2h');
115
118
  response.setHeader('Set-Cookie', `adminforth_${brandNameSlug}_totpTemporaryJWT=${value}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; max-age=3600; `);
116
119
 
117
120
  return {
@@ -122,7 +125,7 @@ export default class TwoFactorsAuthPlugin extends AdminForthPlugin {
122
125
  ok: true
123
126
  }
124
127
  }
125
- const totpTemporaryJWT = this.adminforth.auth.issueJWT({userName, newSecret, issuer:brandName, pk:userPk, userCanSkipSetup, rememberMeDays }, 'tempTotp', '2h');
128
+ const totpTemporaryJWT = this.adminforth.auth.issueJWT({userName, newSecret, issuer:issuerName, pk:userPk, userCanSkipSetup, rememberMeDays }, 'tempTotp', '2h');
126
129
  response.setHeader('Set-Cookie', `adminforth_${brandNameSlug}_totpTemporaryJWT=${totpTemporaryJWT}; Path=${this.adminforth.config.baseUrl || '/'}; HttpOnly; SameSite=Strict; Expires=${new Date(Date.now() + '1h').toUTCString() } `);
127
130
 
128
131
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adminforth/two-factors-auth",
3
- "version": "1.7.0",
3
+ "version": "1.8.1",
4
4
  "description": "AdminForth plugin for two factors authentication",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/types.ts CHANGED
@@ -16,6 +16,8 @@ export type PluginOptions = {
16
16
  */
17
17
  timeStepWindow?: number;
18
18
 
19
+ customBrendPrefix?: string;
20
+
19
21
  /**
20
22
  * Optional function to filter users to apply 2FA.
21
23
  * Should return true if 2FA should be applied to the user and false if AdminForth should not challenge the user with 2FA.