Completed
Push — master ( e88c19...17669b )
by Rain
03:00
created

dev/View/Popup/TwoFactorConfiguration.js   B

Complexity

Total Complexity 39
Complexity/F 2.05

Size

Lines of Code 239
Function Count 19

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 0
wmc 39
nc 9
mnd 2
bc 30
fnc 19
dl 0
loc 239
rs 8.2857
bpm 1.5789
cpm 2.0526
noi 0
c 1
b 0
f 0
1
2
import window from 'window';
3
import _ from '_';
4
import ko from 'ko';
5
import qr from 'qr';
6
7
import {Capa, StorageResultType} from 'Common/Enums';
8
import {pString} from 'Common/Utils';
9
import {i18n, trigger as translatorTrigger} from 'Common/Translator';
10
11
import * as Settings from 'Storage/Settings';
12
13
import Remote from 'Remote/User/Ajax';
14
15
import {getApp} from 'Helper/Apps/User';
16
17
import {view, ViewType, showScreenPopup} from 'Knoin/Knoin';
18
import {AbstractViewNext} from 'Knoin/AbstractViewNext';
19
20
@view({
21
	name: 'View/Popup/TwoFactorConfiguration',
22
	type: ViewType.Popup,
23
	templateID: 'PopupsTwoFactorConfiguration'
24
})
25
class TwoFactorConfigurationPopupView extends AbstractViewNext
26
{
27
	constructor() {
28
		super();
29
30
		this.lock = ko.observable(false);
31
32
		this.capaTwoFactor = Settings.capa(Capa.TwoFactor);
33
34
		this.processing = ko.observable(false);
35
		this.clearing = ko.observable(false);
36
		this.secreting = ko.observable(false);
37
38
		this.viewUser = ko.observable('');
39
		this.twoFactorStatus = ko.observable(false);
40
41
		this.twoFactorTested = ko.observable(false);
42
43
		this.viewSecret = ko.observable('');
44
		this.viewBackupCodes = ko.observable('');
45
		this.viewUrlTitle = ko.observable('');
46
		this.viewUrl = ko.observable('');
47
48
		this.viewEnable_ = ko.observable(false);
49
50
		this.viewEnable = ko.computed({
51
			read: this.viewEnable_,
52
			write: (value) => {
53
				value = !!value;
54
				if (value && this.twoFactorTested())
55
				{
56
					this.viewEnable_(value);
57
					Remote.enableTwoFactor((result, data) => {
58
						if (StorageResultType.Success !== result || !data || !data.Result)
59
						{
60
							this.viewEnable_(false);
61
						}
62
					}, true);
63
				}
64
				else
65
				{
66
					if (!value)
67
					{
68
						this.viewEnable_(value);
69
					}
70
71
					Remote.enableTwoFactor((result, data) => {
72
						if (StorageResultType.Success !== result || !data || !data.Result)
73
						{
74
							this.viewEnable_(false);
75
						}
76
					}, false);
77
				}
78
			}
79
		});
80
81
		this.viewTwoFactorEnableTooltip = ko.computed(() => {
82
			translatorTrigger();
83
			return this.twoFactorTested() || this.viewEnable_() ? '' :
84
				i18n('POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_TEST_BEFORE_DESC');
85
		});
86
87
		this.viewTwoFactorStatus = ko.computed(() => {
88
			translatorTrigger();
89
			return i18n(this.twoFactorStatus() ?
90
				'POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_CONFIGURED_DESC' :
91
				'POPUPS_TWO_FACTOR_CFG/TWO_FACTOR_SECRET_NOT_CONFIGURED_DESC'
92
			);
93
		});
94
95
		this.twoFactorAllowedEnable = ko.computed(() => this.viewEnable() || this.twoFactorTested());
96
97
		this.onResult = _.bind(this.onResult, this);
98
		this.onShowSecretResult = _.bind(this.onShowSecretResult, this);
99
	}
100
101
	showSecret() {
102
		this.secreting(true);
103
		Remote.showTwoFactorSecret(this.onShowSecretResult);
104
	}
105
106
	hideSecret() {
107
		this.viewSecret('');
108
		this.viewBackupCodes('');
109
		this.viewUrlTitle('');
110
		this.viewUrl('');
111
	}
112
113
	createTwoFactor() {
114
		this.processing(true);
115
		Remote.createTwoFactor(this.onResult);
116
	}
117
118
	logout() {
119
		getApp().logout();
120
	}
121
122
	testTwoFactor() {
123
		showScreenPopup(require('View/Popup/TwoFactorTest'), [this.twoFactorTested]);
124
	}
125
126
	clearTwoFactor() {
127
		this.viewSecret('');
128
		this.viewBackupCodes('');
129
		this.viewUrlTitle('');
130
		this.viewUrl('');
131
132
		this.twoFactorTested(false);
133
134
		this.clearing(true);
135
		Remote.clearTwoFactor(this.onResult);
136
	}
137
138
	onShow(bLock) {
139
		this.lock(!!bLock);
140
141
		this.viewSecret('');
142
		this.viewBackupCodes('');
143
		this.viewUrlTitle('');
144
		this.viewUrl('');
145
	}
146
147
	onHide() {
148
		if (this.lock())
149
		{
150
			window.location.reload();
151
		}
152
	}
153
154
	getQr() {
155
		return 'otpauth://totp/' + window.encodeURIComponent(this.viewUser()) +
156
			'?secret=' + window.encodeURIComponent(this.viewSecret()) +
157
			'&issuer=' + window.encodeURIComponent('');
158
	}
159
160
	onResult(sResult, oData) {
161
		this.processing(false);
162
		this.clearing(false);
163
164
		if (StorageResultType.Success === sResult && oData && oData.Result)
165
		{
166
			this.viewUser(pString(oData.Result.User));
167
			this.viewEnable_(!!oData.Result.Enable);
168
			this.twoFactorStatus(!!oData.Result.IsSet);
169
			this.twoFactorTested(!!oData.Result.Tested);
170
171
			this.viewSecret(pString(oData.Result.Secret));
172
			this.viewBackupCodes(pString(oData.Result.BackupCodes).replace(/[\s]+/g, '  '));
173
174
			this.viewUrlTitle(pString(oData.Result.UrlTitle));
175
			this.viewUrl(qr.toDataURL({level: 'M', size: 8, value: this.getQr()}));
176
		}
177
		else
178
		{
179
			this.viewUser('');
180
			this.viewEnable_(false);
181
			this.twoFactorStatus(false);
182
			this.twoFactorTested(false);
183
184
			this.viewSecret('');
185
			this.viewBackupCodes('');
186
			this.viewUrlTitle('');
187
			this.viewUrl('');
188
		}
189
	}
190
191
	onShowSecretResult(result, data) {
192
		this.secreting(false);
193
194
		if (StorageResultType.Success === result && data && data.Result)
195
		{
196
			this.viewSecret(pString(data.Result.Secret));
197
			this.viewUrlTitle(pString(data.Result.UrlTitle));
198
			this.viewUrl(qr.toDataURL({level: 'M', size: 6, value: this.getQr()}));
199
		}
200
		else
201
		{
202
			this.viewSecret('');
203
			this.viewUrlTitle('');
204
			this.viewUrl('');
205
		}
206
	}
207
208
	onBuild() {
209
		if (this.capaTwoFactor)
210
		{
211
			this.processing(true);
212
			Remote.getTwoFactor(this.onResult);
213
		}
214
	}
215
}
216
217
module.exports = TwoFactorConfigurationPopupView;
218