- - {{messages.field_label_policy_contact_requiredForNetworkUnlock}} - | -- - {{messages.field_label_policy_contact_requiredForNodeOperations}} + + {{messages.field_label_policy_contact_requiredForNetworkOperations}} | @@ -101,10 +108,16 @@ | ||||||||||||||||
{{contact.nick}} | + +{{messages['field_label_policy_contact_type_'+contact.type]}} | + +{{contact.info}} | +{{messages.message_true}} @@ -137,6 +150,7 @@ | +{{messages.field_label_policy_contact_authFactor_name_required}} @@ -154,33 +168,27 @@ {{messages.field_label_policy_contact_value_not_applicable_name}} | -- - {{messages.message_true}} - | -- - {{messages.message_false}} - | - -- + + | + {{messages.message_true}} | - + {{messages.message_false}} | -- + + | + {{messages.message_true}} | - + {{messages.message_false}} | +{{messages.field_label_policy_contact_value_not_applicable_name}} @@ -194,6 +202,7 @@ {{messages.message_false}} | +{{messages.field_label_policy_contact_value_not_applicable_name}} @@ -207,6 +216,7 @@ {{messages.message_false}} | +{{messages.field_label_policy_contact_value_not_applicable_name}} @@ -220,6 +230,7 @@ {{messages.message_false}} | +{{messages.field_label_policy_contact_value_not_applicable_name}} @@ -233,6 +244,7 @@ {{messages.message_false}} | +{{messages.field_label_policy_contact_value_not_applicable_name}} @@ -246,6 +258,7 @@ {{messages.message_false}} | +
{{messages.button_label_remove_contact}}
@@ -275,19 +288,15 @@
-
-
-
-
- {{ errors.first('requiredForNetworkUnlock') }}
-
-
-
-
+
+
+
{{ errors.first('requiredForNetworkOperations') }}
+
@@ -339,8 +348,7 @@
function initNewContact () {
return {
uuid: '', type: '', info: '',
- requiredForNetworkUnlock: true,
- requiredForNodeOperations: true,
+ requiredForNetworkOperations: true,
requiredForAccountOperations: true,
receiveVerifyNotifications: true,
receiveLoginNotifications: true,
@@ -364,12 +372,15 @@
accountOperationTimeoutUnits: '',
nodeOperationTimeout: '',
nodeOperationTimeoutUnits: '',
+ authenticatorTimeout: '',
+ authenticatorTimeoutUnits: '',
contacts: [],
contactSubmitted: false,
newContactSmsCountry: '',
newContact: initNewContact(),
verifyingContact: null,
- inboundAction: null
+ inboundAction: null,
+ watchedPolicy: null
}
},
computed: {
@@ -413,19 +424,21 @@
methods: {
...mapActions('account', ['approveAction', 'denyAction', 'sendAuthenticatorCode', 'resendVerificationCode']),
...mapActions('users', [
- 'getPolicyByUserId', 'updatePolicyByUserId', 'addPolicyContactByUserId', 'removePolicyContactByUuid',
+ 'getPolicyByUserId', 'updatePolicyByUserId', 'addPolicyContactByUserId', 'removePolicyContactByUserId',
]),
...mapGetters('users', ['loading']),
isAuthenticator(val) { return window.isAuthenticator(val); },
isNotAuthenticator(val) { return window.isNotAuthenticator(val); },
updatePolicy(e) {
+ this.errors.clear();
this.submitted = true;
this.updatePolicyByUserId({
userId: this.currentUser.uuid,
policy: {
deletionPolicy: this.deletionPolicy,
accountOperationTimeout: this.messages.durationToMillis(this.accountOperationTimeout, this.accountOperationTimeoutUnits),
- nodeOperationTimeout: this.messages.durationToMillis(this.nodeOperationTimeout, this.nodeOperationTimeoutUnits)
+ nodeOperationTimeout: this.messages.durationToMillis(this.nodeOperationTimeout, this.nodeOperationTimeoutUnits),
+ authenticatorTimeout: this.messages.durationToMillis(this.authenticatorTimeout, this.authenticatorTimeoutUnits),
},
messages: this.messages,
errors: this.errors
@@ -438,7 +451,7 @@
}
this.contactSubmitted = true;
this.errors.clear();
- console.log('addContact: adding: '+JSON.stringify(contactToAdd));
+ // console.log('addContact: adding: '+JSON.stringify(contactToAdd));
this.addPolicyContactByUserId({
userId: this.currentUser.uuid,
contact: contactToAdd,
@@ -447,25 +460,45 @@
});
},
removeContact(uuid) {
- this.removePolicyContactByUuid({
+ this.errors.clear();
+ this.removePolicyContactByUserId({
userId: this.currentUser.uuid,
contactUuid: uuid,
messages: this.messages,
errors: this.errors
});
},
+ prepContact(contact) {
+ // remove 'info' property before sending to API
+ const c = Object.assign({}, contact);
+ if (c.hasOwnProperty('info')) delete c['info'];
+ return c;
+ },
contactFlag(contact, flag, val) {
+ this.errors.clear();
+ if (!contact.verified) {
+ this.errors.add({field: 'contact', msg: this.messages['err_contact_unverified']});
+ return;
+ }
contact[flag] = val;
- console.log('contactFlag: update: '+JSON.stringify(contact));
+ const c = this.prepContact(contact);
+ // console.log('contactFlag: update: '+JSON.stringify(c));
this.addPolicyContactByUserId({
userId: this.currentUser.uuid,
- contact: contact,
+ contact: c,
messages: this.messages,
errors: this.errors
});
},
toggleAuthFactor(contact) {
- if (isAuthenticator(contact)) return;
+ if (!contact.verified) {
+ this.errors.add({field: 'contact', msg: this.messages['err_contact_unverified']});
+ return;
+ }
+ if (isAuthenticator(contact)) {
+ this.errors.add({field: 'contact', msg: this.messages['err_contact_authenticatorAuthFactorCannotBeChanged']});
+ return;
+ }
switch (contact.authFactor) {
case 'required': this.setAuthFactor(contact, 'sufficient'); break;
case 'sufficient': this.setAuthFactor(contact, 'not_required'); break;
@@ -473,10 +506,12 @@
}
},
setAuthFactor(contact, factor) {
- contact.authFactor = factor;
+ this.errors.clear();
+ const c = this.prepContact(contact);
+ c.authFactor = factor;
this.addPolicyContactByUserId({
userId: this.currentUser.uuid,
- contact: contact,
+ contact: c,
messages: this.messages,
errors: this.errors
});
@@ -487,6 +522,7 @@
return false; // do not follow the click
},
resendVerification(contact) {
+ this.errors.clear();
this.resendVerificationCode({
userId: this.currentUser.uuid,
contact: contact,
@@ -500,6 +536,23 @@
this.errors.clear();
return false; // do not follow the click
},
+ updatePolicyTimeouts(p) {
+ if (typeof p.accountOperationTimeout !== 'undefined' && p.accountOperationTimeout !== null) {
+ const parts = this.messages.millisToDuration(p.accountOperationTimeout);
+ this.accountOperationTimeout = parts.count;
+ this.accountOperationTimeoutUnits = parts.units;
+ }
+ if (typeof p.nodeOperationTimeout !== 'undefined' && p.nodeOperationTimeout !== null) {
+ const parts = this.messages.millisToDuration(p.nodeOperationTimeout);
+ this.nodeOperationTimeout = parts.count;
+ this.nodeOperationTimeoutUnits = parts.units;
+ }
+ if (typeof p.authenticatorTimeout !== 'undefined' && p.authenticatorTimeout !== null) {
+ const parts = this.messages.millisToDuration(p.authenticatorTimeout);
+ this.authenticatorTimeout = parts.count;
+ this.authenticatorTimeoutUnits = parts.units;
+ }
+ },
submitVerification(contact) {
const uuid = contact.uuid;
const type = contact.type;
@@ -514,6 +567,7 @@
this.sendAuthenticatorCode({
userId: this.currentUser.uuid,
code: code,
+ authOnly: null,
verifyOnly: true,
messages: this.messages,
errors: this.errors
@@ -532,21 +586,18 @@
}
},
watch: {
+ messages (msgs) {
+ if (this.accountOperationTimeoutUnits === '' && this.watchedPolicy) {
+ this.updatePolicyTimeouts(this.watchedPolicy);
+ }
+ },
policy (p) {
// console.log('watch.policy: received: '+JSON.stringify(p));
+ if (p) this.watchedPolicy = p;
if (typeof p.deletionPolicy !== 'undefined' && p.deletionPolicy !== null) {
this.deletionPolicy = p.deletionPolicy;
}
- if (typeof p.accountOperationTimeout !== 'undefined' && p.accountOperationTimeout !== null) {
- const parts = this.messages.millisToDuration(p.accountOperationTimeout);
- this.accountOperationTimeout = parts.count;
- this.accountOperationTimeoutUnits = parts.units;
- }
- if (typeof p.nodeOperationTimeout !== 'undefined' && p.nodeOperationTimeout !== null) {
- const parts = this.messages.millisToDuration(p.nodeOperationTimeout);
- this.nodeOperationTimeout = parts.count;
- this.nodeOperationTimeoutUnits = parts.units;
- }
+ this.updatePolicyTimeouts(p);
if (typeof p.accountContacts !== 'undefined' && p.accountContacts !== null && p.accountContacts.length > 0) {
this.contacts = p.accountContacts;
} else {
diff --git a/src/app/App.vue b/src/app/App.vue
index a191c76..879dc50 100644
--- a/src/app/App.vue
+++ b/src/app/App.vue
@@ -1,5 +1,6 @@
+
diff --git a/src/auth/MultifactorAuthPage.vue b/src/auth/MultifactorAuthPage.vue
index 350446e..e91ce91 100644
--- a/src/auth/MultifactorAuthPage.vue
+++ b/src/auth/MultifactorAuthPage.vue
@@ -72,6 +72,7 @@
this.sendAuthenticatorCode({
userId: this.username,
code: code,
+ authOnly: null,
verifyOnly: false,
messages: this.messages,
errors: this.errors
diff --git a/src/index.html b/src/index.html
index 21e2eb2..80d05d1 100755
--- a/src/index.html
+++ b/src/index.html
@@ -33,6 +33,17 @@
width: 100%;
text-align: center;
}
+
+ .totp-modal {
+ position:fixed;
+ width:100%;
+ height:100%;
+ opacity:1;
+ background: #b9bbbe;
+ top:0;
+ left:0;
+ z-index:1000;
+ }
diff --git a/src/index.js b/src/index.js
index 6132e70..fe5c1b0 100755
--- a/src/index.js
+++ b/src/index.js
@@ -12,6 +12,7 @@ import { Datetime } from 'vue-datetime';
import { store } from './_store';
import { router } from './_helpers';
+import TotpModal from './_components/TotpModal';
import App from './app/App';
// why can't i import this?
@@ -21,6 +22,7 @@ Vue.use(VeeValidate);
Vue.use(VueSidebarMenu);
Vue.component('v-select', vSelect);
Vue.component('datetime', Datetime);
+Vue.component('totp-modal', TotpModal);
Vue.config.productionTip = false;
// not sure what the best way is to include these icons, we reference them programmatically via string resource/messages
diff --git a/webpack.config.js b/webpack.config.js
index b1737ed..67e40f9 100755
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -1,4 +1,3 @@
-var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
@@ -35,7 +34,6 @@ module.exports = {
externals: {
// global app config object
config: JSON.stringify({
- // apiUrl: 'http://localhost:4000'
apiUrl: '/api'
})
}
|