@everymatrix/general-input 1.87.0 → 1.87.2
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/dist/cjs/checkbox-group-input_14.cjs.entry.js +310 -86
- package/dist/cjs/general-input.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/components/date-input/date-input.js +60 -3
- package/dist/collection/components/general-input/general-input.js +41 -5
- package/dist/collection/components/password-input/password-input.css +52 -0
- package/dist/collection/components/password-input/password-input.js +31 -3
- package/dist/collection/components/text-input/text-input.js +133 -33
- package/dist/collection/components/twofa-input/twofa-input.js +105 -40
- package/dist/collection/utils/locale.utils.js +77 -5
- package/dist/esm/checkbox-group-input_14.entry.js +310 -86
- package/dist/esm/general-input.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/general-input/checkbox-group-input_14.entry.js +239 -239
- package/dist/general-input/general-input.esm.js +1 -1
- package/dist/types/components/date-input/date-input.d.ts +7 -0
- package/dist/types/components/general-input/general-input.d.ts +8 -0
- package/dist/types/components/password-input/password-input.d.ts +5 -0
- package/dist/types/components/text-input/text-input.d.ts +12 -1
- package/dist/types/components/twofa-input/twofa-input.d.ts +12 -1
- package/dist/types/components.d.ts +56 -0
- package/dist/types/utils/locale.utils.d.ts +28 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { h } from "@stencil/core";
|
|
2
|
-
import { translate } from "../../utils/locale.utils";
|
|
2
|
+
import { translate, validateID, CONSTANTS, ERROR_KEYS } from "../../utils/locale.utils";
|
|
3
3
|
import tooltipIcon from "../../utils/tooltipIcon.svg";
|
|
4
4
|
export class TextInput {
|
|
5
5
|
constructor() {
|
|
@@ -9,24 +9,28 @@ export class TextInput {
|
|
|
9
9
|
this.postalcodelength = 5;
|
|
10
10
|
this.touched = false;
|
|
11
11
|
this.handleInput = (event) => {
|
|
12
|
-
|
|
12
|
+
const input = event.target;
|
|
13
|
+
const normalizedValue = this.enableSouthAfricanMode &&
|
|
14
|
+
(this.name === CONSTANTS.FIRSTNAME_ON_DOCUMENT ||
|
|
15
|
+
this.name === CONSTANTS.LASTNAME_ON_DOCUMENT)
|
|
16
|
+
? input.value.replace(CONSTANTS.NON_LETTERS_REGEX, '')
|
|
17
|
+
: input.value;
|
|
18
|
+
if (normalizedValue !== input.value) {
|
|
19
|
+
input.value = normalizedValue;
|
|
20
|
+
}
|
|
21
|
+
this.value = normalizedValue;
|
|
13
22
|
this.touched = true;
|
|
14
|
-
if (this.debounceTime)
|
|
23
|
+
if (this.debounceTime)
|
|
15
24
|
clearTimeout(this.debounceTime);
|
|
16
|
-
}
|
|
17
25
|
this.debounceTime = setTimeout(() => {
|
|
18
|
-
this.
|
|
19
|
-
this.errorMessage = this.setErrorMessage();
|
|
20
|
-
this.validityStateHandler({ valid: this.isValid, name: this.name });
|
|
26
|
+
this.updateValidationState();
|
|
21
27
|
this.emitValueHandler(true);
|
|
22
28
|
}, 500);
|
|
23
29
|
};
|
|
24
30
|
this.handleBlur = (event) => {
|
|
25
31
|
this.value = event.target.value;
|
|
26
32
|
this.touched = true;
|
|
27
|
-
this.
|
|
28
|
-
this.errorMessage = this.setErrorMessage();
|
|
29
|
-
this.validityStateHandler({ valid: this.isValid, name: this.name });
|
|
33
|
+
this.updateValidationState();
|
|
30
34
|
};
|
|
31
35
|
this.setClientStyling = () => {
|
|
32
36
|
let sheet = document.createElement('style');
|
|
@@ -46,6 +50,7 @@ export class TextInput {
|
|
|
46
50
|
this.isDuplicateInput = undefined;
|
|
47
51
|
this.clientStyling = '';
|
|
48
52
|
this.haspostalcodelookup = undefined;
|
|
53
|
+
this.enableSouthAfricanMode = undefined;
|
|
49
54
|
this.isValid = undefined;
|
|
50
55
|
this.errorMessage = '';
|
|
51
56
|
this.limitStylingAppends = false;
|
|
@@ -83,15 +88,13 @@ export class TextInput {
|
|
|
83
88
|
if (this.isDuplicateInput && this.name === event.detail.name + 'Duplicate') {
|
|
84
89
|
this.duplicateInputValue = event.detail.value;
|
|
85
90
|
if (this.touched) {
|
|
86
|
-
this.
|
|
87
|
-
this.errorMessage = this.setErrorMessage();
|
|
91
|
+
this.updateValidationState();
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
|
-
if (this.name === event.detail.name + 'Duplicate'
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
this.
|
|
94
|
-
this.errorMessage = this.setErrorMessage();
|
|
94
|
+
if (this.name === event.detail.name + 'Duplicate' &&
|
|
95
|
+
this.name.replace('Duplicate', '') === event.detail.name &&
|
|
96
|
+
this.touched) {
|
|
97
|
+
this.updateValidationState();
|
|
95
98
|
}
|
|
96
99
|
}
|
|
97
100
|
handleValidationChange(event) {
|
|
@@ -101,7 +104,7 @@ export class TextInput {
|
|
|
101
104
|
this.validation = event.detail.validation;
|
|
102
105
|
this.validationPattern = this.setPattern();
|
|
103
106
|
if (this.touched) {
|
|
104
|
-
this.isValid = this.
|
|
107
|
+
this.isValid = this.isValidValue();
|
|
105
108
|
this.errorMessage = this.setErrorMessage();
|
|
106
109
|
}
|
|
107
110
|
}
|
|
@@ -137,13 +140,37 @@ export class TextInput {
|
|
|
137
140
|
}
|
|
138
141
|
this.value = newValue;
|
|
139
142
|
this.touched = true;
|
|
140
|
-
this.
|
|
141
|
-
this.valueHandler({ name: this.name, value: newValue });
|
|
142
|
-
this.validityStateHandler({ valid: true, name: this.name });
|
|
143
|
+
this.updateValidationState();
|
|
143
144
|
}
|
|
144
145
|
connectedCallback() {
|
|
145
146
|
this.validationPattern = this.setPattern();
|
|
146
147
|
}
|
|
148
|
+
handleExternalDocUpdate(event) {
|
|
149
|
+
if (this.name !== CONSTANTS.DOCUMENT_NUMBER)
|
|
150
|
+
return;
|
|
151
|
+
this.value = event.detail || "";
|
|
152
|
+
this.touched = true;
|
|
153
|
+
if (this.inputReference) {
|
|
154
|
+
this.inputReference.value = this.value;
|
|
155
|
+
}
|
|
156
|
+
this.sendInputValue.emit({
|
|
157
|
+
name: this.name,
|
|
158
|
+
value: this.value
|
|
159
|
+
});
|
|
160
|
+
this.updateValidationState();
|
|
161
|
+
}
|
|
162
|
+
handleDocReset() {
|
|
163
|
+
if (this.name !== CONSTANTS.DOCUMENT_NUMBER)
|
|
164
|
+
return;
|
|
165
|
+
this.value = "";
|
|
166
|
+
this.touched = false;
|
|
167
|
+
this.isValid = false;
|
|
168
|
+
this.errorMessage = "";
|
|
169
|
+
if (this.inputReference) {
|
|
170
|
+
this.inputReference.value = "";
|
|
171
|
+
}
|
|
172
|
+
this.validityStateHandler({ valid: false, name: this.name });
|
|
173
|
+
}
|
|
147
174
|
componentDidRender() {
|
|
148
175
|
// start custom styling area
|
|
149
176
|
if (!this.limitStylingAppends && this.stylingContainer) {
|
|
@@ -160,6 +187,7 @@ export class TextInput {
|
|
|
160
187
|
}
|
|
161
188
|
componentDidLoad() {
|
|
162
189
|
if (this.defaultValue) {
|
|
190
|
+
this.value = this.defaultValue;
|
|
163
191
|
this.valueHandler({ name: this.name, value: this.value });
|
|
164
192
|
if (this.isDuplicateInput) {
|
|
165
193
|
this.touched = true;
|
|
@@ -171,18 +199,49 @@ export class TextInput {
|
|
|
171
199
|
window.targetInputRefs[this.name] = this.inputReference;
|
|
172
200
|
}
|
|
173
201
|
}
|
|
174
|
-
this.isValid = this.
|
|
202
|
+
this.isValid = this.isValidValue();
|
|
203
|
+
}
|
|
204
|
+
validateDocument(valueRaw, docType) {
|
|
205
|
+
const value = valueRaw.trim();
|
|
206
|
+
if (docType === CONSTANTS.PASSPORT) {
|
|
207
|
+
const valid = CONSTANTS.PASSPORT_NUMERIC_REGEX.test(value);
|
|
208
|
+
return valid
|
|
209
|
+
? { valid: true }
|
|
210
|
+
: { valid: false, errorKey: ERROR_KEYS.PASSPORT_INVALID };
|
|
211
|
+
}
|
|
212
|
+
if (docType === CONSTANTS.SOUTH_AFRICAN_ID) {
|
|
213
|
+
if (value.length !== CONSTANTS.SOUTH_AFRICAN_ID_LENGTH) {
|
|
214
|
+
return { valid: false, errorKey: ERROR_KEYS.SA_ID_LENGTH };
|
|
215
|
+
}
|
|
216
|
+
const valid = validateID(value);
|
|
217
|
+
return valid
|
|
218
|
+
? { valid: true }
|
|
219
|
+
: { valid: false, errorKey: ERROR_KEYS.SA_ID_INVALID };
|
|
220
|
+
}
|
|
221
|
+
return { valid: true };
|
|
175
222
|
}
|
|
176
|
-
|
|
223
|
+
updateValidationState() {
|
|
224
|
+
const nextValid = this.isValidValue();
|
|
225
|
+
this.isValid = nextValid;
|
|
226
|
+
if (!this.touched) {
|
|
227
|
+
this.errorMessage = '';
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
this.errorMessage = nextValid ? '' : this.setErrorMessage();
|
|
231
|
+
}
|
|
232
|
+
isValidValue() {
|
|
177
233
|
if (!this.inputReference) {
|
|
178
234
|
return false;
|
|
179
235
|
}
|
|
180
|
-
if (this.
|
|
181
|
-
|
|
236
|
+
if (this.enableSouthAfricanMode && this.name === CONSTANTS.DOCUMENT_NUMBER) {
|
|
237
|
+
const docType = window.documentTypeValue;
|
|
238
|
+
return this.validateDocument(this.value, docType).valid;
|
|
182
239
|
}
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
240
|
+
const fallbackResult = (this.value.trim() === "" && !this.validation.mandatory) ||
|
|
241
|
+
(this.inputReference.validity.valid &&
|
|
242
|
+
(!this.inputReference.value ||
|
|
243
|
+
this.inputReference.value.match(this.validationPattern) !== null));
|
|
244
|
+
return fallbackResult;
|
|
186
245
|
}
|
|
187
246
|
setPattern() {
|
|
188
247
|
var _a, _b;
|
|
@@ -192,14 +251,25 @@ export class TextInput {
|
|
|
192
251
|
}
|
|
193
252
|
setErrorMessage() {
|
|
194
253
|
var _a, _b, _c, _d;
|
|
195
|
-
|
|
254
|
+
const value = this.value.trim();
|
|
255
|
+
if (this.enableSouthAfricanMode && this.name === CONSTANTS.DOCUMENT_NUMBER) {
|
|
256
|
+
const docType = window.documentTypeValue;
|
|
257
|
+
const res = this.validateDocument(this.value, docType);
|
|
258
|
+
return res.valid ? '' : translate(res.errorKey, this.language);
|
|
259
|
+
}
|
|
260
|
+
if (value === "" && !this.validation.mandatory) {
|
|
196
261
|
return "";
|
|
197
262
|
}
|
|
198
263
|
if (this.inputReference.validity.valueMissing) {
|
|
199
|
-
return translate(
|
|
264
|
+
return translate(ERROR_KEYS.REQUIRED, this.language);
|
|
200
265
|
}
|
|
201
266
|
if (this.inputReference.validity.tooShort || this.inputReference.validity.tooLong) {
|
|
202
|
-
return translate(
|
|
267
|
+
return translate(ERROR_KEYS.LENGTH, this.language, {
|
|
268
|
+
values: {
|
|
269
|
+
minLength: this.validation.minLength,
|
|
270
|
+
maxLength: this.validation.maxLength
|
|
271
|
+
}
|
|
272
|
+
});
|
|
203
273
|
}
|
|
204
274
|
if (this.inputReference.value.match(this.validationPattern) == null) {
|
|
205
275
|
const errorCode = (_a = this.validation.custom.find(customValidation => customValidation.rule === 'regex')) === null || _a === void 0 ? void 0 : _a.errorKey;
|
|
@@ -211,6 +281,7 @@ export class TextInput {
|
|
|
211
281
|
const errorMessage = (_d = this.validation.custom.find(customRule => customRule.rule === 'duplicate-input')) === null || _d === void 0 ? void 0 : _d.errorMessage;
|
|
212
282
|
return translate(`${errorCode}`, this.language) ? translate(`${errorCode}`, this.language) : errorMessage;
|
|
213
283
|
}
|
|
284
|
+
return "";
|
|
214
285
|
}
|
|
215
286
|
renderTooltip() {
|
|
216
287
|
if (this.showTooltip) {
|
|
@@ -223,8 +294,8 @@ export class TextInput {
|
|
|
223
294
|
if (this.touched) {
|
|
224
295
|
invalidClass = this.isValid == true || this.isValid == undefined ? '' : 'text__input--invalid';
|
|
225
296
|
}
|
|
226
|
-
return h("div", { key: '
|
|
227
|
-
h("img", { key: '
|
|
297
|
+
return h("div", { key: '5b0bf10acadab5c3362d185cef10c5ed4f3a6a47', class: `text__wrapper ${this.name}__input ${this.autofilled ? 'text__wrapper--autofilled' : ''}`, ref: el => this.stylingContainer = el }, h("div", { key: '6d79cc845aac8d9b11737d35571680d7701c4b94', class: 'text__wrapper--flex' }, h("label", { key: 'de687661fa037d691fe1da1231b651f564bca010', class: `text__label ${this.validation.mandatory ? 'text__label--required' : ''}`, htmlFor: `${this.name}__input` }, this.displayName), h("div", { key: '4d9b12a587267eaf6fab4c4f3c38befb8d5c2b99', class: 'text__wrapper--relative' }, this.tooltip &&
|
|
298
|
+
h("img", { key: '7f27a118124cd0407b6c2644137a79eaa0496164', class: 'text__tooltip-icon', src: tooltipIcon, alt: "", ref: (el) => this.tooltipIconReference = el, onClick: () => this.showTooltip = !this.showTooltip }), this.renderTooltip())), h("input", { key: '94a614815155465dbfef2a7cc1cb788bb14d1498', name: this.name, id: `${this.name}__input`, value: this.value, type: 'text', class: `text__input ${invalidClass}`, placeholder: `${this.placeholder}`, ref: (el) => this.inputReference = el, readOnly: this.autofilled, required: this.validation.mandatory, minlength: this.enableSouthAfricanMode ? '' : this.validation.minLength, maxlength: this.enableSouthAfricanMode ? '' : this.validation.maxLength, onInput: this.handleInput, onBlur: this.handleBlur }), h("small", { key: 'b9b3bdcd9cb81b56dc25a208b0c1d7784d06b5e0', class: 'text__error-message' }, this.errorMessage));
|
|
228
299
|
}
|
|
229
300
|
static get is() { return "text-input"; }
|
|
230
301
|
static get encapsulation() { return "shadow"; }
|
|
@@ -466,6 +537,23 @@ export class TextInput {
|
|
|
466
537
|
},
|
|
467
538
|
"attribute": "haspostalcodelookup",
|
|
468
539
|
"reflect": true
|
|
540
|
+
},
|
|
541
|
+
"enableSouthAfricanMode": {
|
|
542
|
+
"type": "boolean",
|
|
543
|
+
"mutable": false,
|
|
544
|
+
"complexType": {
|
|
545
|
+
"original": "boolean",
|
|
546
|
+
"resolved": "boolean",
|
|
547
|
+
"references": {}
|
|
548
|
+
},
|
|
549
|
+
"required": false,
|
|
550
|
+
"optional": false,
|
|
551
|
+
"docs": {
|
|
552
|
+
"tags": [],
|
|
553
|
+
"text": "Enable South African registration mode"
|
|
554
|
+
},
|
|
555
|
+
"attribute": "enable-south-african-mode",
|
|
556
|
+
"reflect": true
|
|
469
557
|
}
|
|
470
558
|
};
|
|
471
559
|
}
|
|
@@ -566,6 +654,18 @@ export class TextInput {
|
|
|
566
654
|
"target": "body",
|
|
567
655
|
"capture": false,
|
|
568
656
|
"passive": false
|
|
657
|
+
}, {
|
|
658
|
+
"name": "documentNumberUpdatedExternally",
|
|
659
|
+
"method": "handleExternalDocUpdate",
|
|
660
|
+
"target": "window",
|
|
661
|
+
"capture": false,
|
|
662
|
+
"passive": false
|
|
663
|
+
}, {
|
|
664
|
+
"name": "documentNumberResetValidation",
|
|
665
|
+
"method": "handleDocReset",
|
|
666
|
+
"target": "window",
|
|
667
|
+
"capture": false,
|
|
668
|
+
"passive": false
|
|
569
669
|
}];
|
|
570
670
|
}
|
|
571
671
|
}
|
|
@@ -58,20 +58,24 @@ export class TwofaInput {
|
|
|
58
58
|
this.handleInput = (e, idx) => {
|
|
59
59
|
const input = e.target;
|
|
60
60
|
const value = input.value;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
else {
|
|
65
|
-
input.value = value.charAt(0);
|
|
66
|
-
}
|
|
67
|
-
if (!value) {
|
|
61
|
+
const char = value.slice(-1);
|
|
62
|
+
input.value = char;
|
|
63
|
+
if (!char)
|
|
68
64
|
return;
|
|
65
|
+
this.code[idx] = char;
|
|
66
|
+
// --- Hide pin code --- //
|
|
67
|
+
if (this.enableSouthAfricanMode) {
|
|
68
|
+
// show character for 500ms
|
|
69
|
+
this.revealedIndexes = [idx];
|
|
70
|
+
if (this.revealTimeout)
|
|
71
|
+
clearTimeout(this.revealTimeout);
|
|
72
|
+
this.revealTimeout = setTimeout(() => {
|
|
73
|
+
this.revealedIndexes = [];
|
|
74
|
+
}, 500);
|
|
69
75
|
}
|
|
70
|
-
this.code[idx] = input.value;
|
|
71
76
|
const nextInput = this.inputRefs[idx + 1];
|
|
72
|
-
if (nextInput)
|
|
77
|
+
if (nextInput)
|
|
73
78
|
nextInput.focus();
|
|
74
|
-
}
|
|
75
79
|
this.setValidity();
|
|
76
80
|
this.setErrorMessage();
|
|
77
81
|
};
|
|
@@ -100,6 +104,8 @@ export class TwofaInput {
|
|
|
100
104
|
this.destination = '';
|
|
101
105
|
this.resendIntervalSeconds = 60;
|
|
102
106
|
this.clientStyling = '';
|
|
107
|
+
this.enableSouthAfricanMode = undefined;
|
|
108
|
+
this.pinAttemptsExceeded = undefined;
|
|
103
109
|
this.clientStylingUrl = '';
|
|
104
110
|
this.mbSource = undefined;
|
|
105
111
|
this.limitStylingAppends = false;
|
|
@@ -109,10 +115,7 @@ export class TwofaInput {
|
|
|
109
115
|
this.errorMessage = '';
|
|
110
116
|
this.code = [];
|
|
111
117
|
this.resendIntervalSecondsLeft = this.resendIntervalSeconds;
|
|
112
|
-
|
|
113
|
-
handleStylingChange(newValue, oldValue) {
|
|
114
|
-
if (newValue !== oldValue)
|
|
115
|
-
this.setClientStyling();
|
|
118
|
+
this.revealedIndexes = [];
|
|
116
119
|
}
|
|
117
120
|
validityChanged() {
|
|
118
121
|
this.validityStateHandler({ valid: this.isValid, name: this.name });
|
|
@@ -141,6 +144,10 @@ export class TwofaInput {
|
|
|
141
144
|
this.showTooltip = false;
|
|
142
145
|
}
|
|
143
146
|
}
|
|
147
|
+
handleStylingChange(newValue, oldValue) {
|
|
148
|
+
if (newValue !== oldValue)
|
|
149
|
+
this.setClientStyling();
|
|
150
|
+
}
|
|
144
151
|
connectedCallback() {
|
|
145
152
|
this.validationPattern = this.setPattern();
|
|
146
153
|
this.code = new Array(this.validation.maxLength).fill('');
|
|
@@ -175,37 +182,51 @@ export class TwofaInput {
|
|
|
175
182
|
}
|
|
176
183
|
handleKeyDown(e, idx) {
|
|
177
184
|
if (e.key === 'Backspace') {
|
|
178
|
-
this.code
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (prevInput) {
|
|
184
|
-
prevInput === null || prevInput === void 0 ? void 0 : prevInput.focus();
|
|
185
|
+
const newCode = [...this.code];
|
|
186
|
+
newCode[idx] = '';
|
|
187
|
+
this.code = newCode;
|
|
188
|
+
if (this.enableSouthAfricanMode) {
|
|
189
|
+
this.revealedIndexes = this.revealedIndexes.filter(i => i !== idx);
|
|
185
190
|
}
|
|
191
|
+
const prevInput = this.inputRefs[idx - 1];
|
|
192
|
+
prevInput === null || prevInput === void 0 ? void 0 : prevInput.focus();
|
|
186
193
|
}
|
|
187
194
|
this.setValidity();
|
|
188
195
|
this.setErrorMessage();
|
|
189
196
|
}
|
|
190
197
|
handlePaste(e) {
|
|
191
|
-
var _a;
|
|
198
|
+
var _a, _b;
|
|
192
199
|
e.preventDefault();
|
|
193
|
-
const data = (_a = e.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text').trim();
|
|
194
|
-
if (!data)
|
|
200
|
+
const data = (_b = (_a = e.clipboardData) === null || _a === void 0 ? void 0 : _a.getData('text')) === null || _b === void 0 ? void 0 : _b.trim();
|
|
201
|
+
if (!data)
|
|
195
202
|
return;
|
|
203
|
+
const value = data.slice(0, this.validation.maxLength).split('');
|
|
204
|
+
this.code = [
|
|
205
|
+
...value,
|
|
206
|
+
...new Array(this.validation.maxLength - value.length).fill('')
|
|
207
|
+
];
|
|
208
|
+
if (this.enableSouthAfricanMode) {
|
|
209
|
+
this.revealedIndexes = value.map((_, i) => i);
|
|
210
|
+
if (this.revealTimeout)
|
|
211
|
+
clearTimeout(this.revealTimeout);
|
|
212
|
+
this.revealTimeout = setTimeout(() => {
|
|
213
|
+
this.revealedIndexes = [];
|
|
214
|
+
}, 500);
|
|
196
215
|
}
|
|
197
|
-
const value = data.slice(0, this.validation.maxLength).split(''); // Limit to OTP length
|
|
198
|
-
this.code = [...value, ...new Array(this.validation.maxLength - value.length).fill('')];
|
|
199
|
-
value.forEach((char, index) => {
|
|
200
|
-
this.inputRefs[index].value = char;
|
|
201
|
-
});
|
|
202
|
-
// Move focus to the last input or trigger submit
|
|
203
216
|
const lastInput = this.inputRefs[Math.min(value.length, this.inputRefs.length - 1)];
|
|
204
|
-
|
|
205
|
-
lastInput.focus();
|
|
206
|
-
}
|
|
217
|
+
lastInput === null || lastInput === void 0 ? void 0 : lastInput.focus();
|
|
207
218
|
this.setValidity();
|
|
208
219
|
this.setErrorMessage();
|
|
220
|
+
if (this.enableSouthAfricanMode) {
|
|
221
|
+
this.valueHandler({
|
|
222
|
+
name: this.name,
|
|
223
|
+
value: this.code.join('')
|
|
224
|
+
});
|
|
225
|
+
this.validityStateHandler({
|
|
226
|
+
valid: this.isValid,
|
|
227
|
+
name: this.name
|
|
228
|
+
});
|
|
229
|
+
}
|
|
209
230
|
}
|
|
210
231
|
setValidity() {
|
|
211
232
|
const code = this.code.join('');
|
|
@@ -238,10 +259,19 @@ export class TwofaInput {
|
|
|
238
259
|
}
|
|
239
260
|
return null;
|
|
240
261
|
}
|
|
262
|
+
getInputDisplayValue(idx) {
|
|
263
|
+
const current = this.code[idx];
|
|
264
|
+
if (!current)
|
|
265
|
+
return "";
|
|
266
|
+
if (this.enableSouthAfricanMode) {
|
|
267
|
+
return this.revealedIndexes.includes(idx) ? current : "*";
|
|
268
|
+
}
|
|
269
|
+
return current;
|
|
270
|
+
}
|
|
241
271
|
render() {
|
|
242
|
-
return (h("div", { key: '
|
|
243
|
-
return (h("input", { key: idx, ref: el => this.setInputRef(el, idx), id: `otp-input-${idx}`, type: "text", maxLength: 2, value:
|
|
244
|
-
})), h("div", { key: '
|
|
272
|
+
return (h("div", { key: '56a639eb6e240482078fc7aaf688c75ae3de04c8', class: "twofa", ref: el => this.stylingContainer = el }, h("div", { key: 'a64039a3ed66556a0dc1bbac7b6fd6d60de23fa3', class: 'twofa__error-message' }, h("p", { key: '21adf57c840d51714ab097e9df3cc77e22be611f' }, this.errorMessage)), h("div", { key: '6653201178b40bc1eb5d6e7d881f2bbe150901f3', class: "twofa__description", innerHTML: translate('twofaDescription', this.language, { values: { destination: this.destination } }) }), h("div", { key: 'ca7600034af473838b741d5be4fe72ded9937647', class: "twofa__input-wrapper", ref: this.setContainerRef }, this.code.map((_, idx) => {
|
|
273
|
+
return (h("input", { key: idx, ref: el => this.setInputRef(el, idx), id: `otp-input-${idx}`, type: "text", maxLength: 2, value: this.getInputDisplayValue(idx), onInput: (event) => this.handleInput(event, idx), onKeyDown: (event) => this.handleKeyDown(event, idx), onPaste: (event) => this.handlePaste(event) }));
|
|
274
|
+
})), h("div", { key: '0ecd60dd5e6b3f6c3a86176e1937e7aeeffc0e92', class: "twofa__button-wrapper" }, h("p", { key: 'fa9608598580bb8628d0e7a208cc69e3ebe83264', class: "twofa__resend-message" }, translate('twofaResendMessage', this.language)), h("button", { key: 'c70ea6e780eefc8fef0002fdcc10286ae0e66619', class: `twofa__resend-button ${this.pinAttemptsExceeded ? 'twofa__resend-button--disabled' : ''}`, onClick: this.resendCodeHandler, disabled: !this.isResendButtonAvailable || this.pinAttemptsExceeded }, this.isResendButtonAvailable
|
|
245
275
|
? translate('twofaResendButton', this.language)
|
|
246
276
|
: this.formatTime()))));
|
|
247
277
|
}
|
|
@@ -442,6 +472,40 @@ export class TwofaInput {
|
|
|
442
472
|
"reflect": true,
|
|
443
473
|
"defaultValue": "''"
|
|
444
474
|
},
|
|
475
|
+
"enableSouthAfricanMode": {
|
|
476
|
+
"type": "boolean",
|
|
477
|
+
"mutable": false,
|
|
478
|
+
"complexType": {
|
|
479
|
+
"original": "boolean",
|
|
480
|
+
"resolved": "boolean",
|
|
481
|
+
"references": {}
|
|
482
|
+
},
|
|
483
|
+
"required": false,
|
|
484
|
+
"optional": false,
|
|
485
|
+
"docs": {
|
|
486
|
+
"tags": [],
|
|
487
|
+
"text": "Enable South African registration mode"
|
|
488
|
+
},
|
|
489
|
+
"attribute": "enable-south-african-mode",
|
|
490
|
+
"reflect": true
|
|
491
|
+
},
|
|
492
|
+
"pinAttemptsExceeded": {
|
|
493
|
+
"type": "boolean",
|
|
494
|
+
"mutable": false,
|
|
495
|
+
"complexType": {
|
|
496
|
+
"original": "boolean",
|
|
497
|
+
"resolved": "boolean",
|
|
498
|
+
"references": {}
|
|
499
|
+
},
|
|
500
|
+
"required": false,
|
|
501
|
+
"optional": false,
|
|
502
|
+
"docs": {
|
|
503
|
+
"tags": [],
|
|
504
|
+
"text": "Check if user has exceeded the failing pin code inputs"
|
|
505
|
+
},
|
|
506
|
+
"attribute": "pin-attempts-exceeded",
|
|
507
|
+
"reflect": true
|
|
508
|
+
},
|
|
445
509
|
"clientStylingUrl": {
|
|
446
510
|
"type": "string",
|
|
447
511
|
"mutable": false,
|
|
@@ -487,7 +551,8 @@ export class TwofaInput {
|
|
|
487
551
|
"showTooltip": {},
|
|
488
552
|
"errorMessage": {},
|
|
489
553
|
"code": {},
|
|
490
|
-
"resendIntervalSecondsLeft": {}
|
|
554
|
+
"resendIntervalSecondsLeft": {},
|
|
555
|
+
"revealedIndexes": {}
|
|
491
556
|
};
|
|
492
557
|
}
|
|
493
558
|
static get events() {
|
|
@@ -568,9 +633,6 @@ export class TwofaInput {
|
|
|
568
633
|
static get elementRef() { return "host"; }
|
|
569
634
|
static get watchers() {
|
|
570
635
|
return [{
|
|
571
|
-
"propName": "clientStyling",
|
|
572
|
-
"methodName": "handleStylingChange"
|
|
573
|
-
}, {
|
|
574
636
|
"propName": "isValid",
|
|
575
637
|
"methodName": "validityChanged"
|
|
576
638
|
}, {
|
|
@@ -579,6 +641,9 @@ export class TwofaInput {
|
|
|
579
641
|
}, {
|
|
580
642
|
"propName": "clientStylingUrl",
|
|
581
643
|
"methodName": "handleStylingUrlChange"
|
|
644
|
+
}, {
|
|
645
|
+
"propName": "clientStyling",
|
|
646
|
+
"methodName": "handleStylingChange"
|
|
582
647
|
}];
|
|
583
648
|
}
|
|
584
649
|
static get listeners() {
|
|
@@ -29,6 +29,10 @@ export const TRANSLATIONS = {
|
|
|
29
29
|
"enterIEAddressManually": "For IRE, enter the address manually",
|
|
30
30
|
"postalLookUpNoAddressFound": "No addresses found for this postal code",
|
|
31
31
|
"searchingForAddresses": "Searching for addresses...",
|
|
32
|
+
"SAIdLengthError": "SA ID must be 13 digits",
|
|
33
|
+
"SAIdInvalidError": "Invalid SA ID",
|
|
34
|
+
"PassportLengthError": "Passport number must be 8 or 9 digits.",
|
|
35
|
+
"PasswordMustContain": "Password must contain:"
|
|
32
36
|
},
|
|
33
37
|
"hu": {
|
|
34
38
|
"dateError": "A választott dátumnak {min} és {max} között kell lennie",
|
|
@@ -55,7 +59,11 @@ export const TRANSLATIONS = {
|
|
|
55
59
|
"InvalidDocumentNumber": "Csak számjegyek engedélyezettek.",
|
|
56
60
|
"twofaDescription": "<p> A megerősítő kódot elküldtük a következő címre: <p> {destination}. </p> </p> <p> Kérjük, írja be az alábbi PIN-kódot. </p>",
|
|
57
61
|
"twofaResendMessage": "Nem kapta meg a megerősítő kódot?",
|
|
58
|
-
"twofaResendButton": "Újraküldés"
|
|
62
|
+
"twofaResendButton": "Újraküldés",
|
|
63
|
+
"PassportLengthError": "Az útlevélszámnak 9 számjegyűnek kell lennie",
|
|
64
|
+
"SAIdLengthError": "A dél-afrikai személyi számnak 13 számjegyűnek kell lennie",
|
|
65
|
+
"SAIdInvalidError": "Érvénytelen dél-afrikai személyi szám",
|
|
66
|
+
"PasswordMustContain": "A jelszónak tartalmaznia kell:"
|
|
59
67
|
},
|
|
60
68
|
"hr": {
|
|
61
69
|
"dateError": "Odabrani datum treba biti između {min} i {max}",
|
|
@@ -82,7 +90,11 @@ export const TRANSLATIONS = {
|
|
|
82
90
|
"InvalidDocumentNumber": "Dopušteni su samo numerički znakovi.",
|
|
83
91
|
"twofaDescription": "<p> Poslali smo verifikacijski kod na: <p> {destination}. </p> </p> <p> Molimo unesite PIN ispod. </p>",
|
|
84
92
|
"twofaResendMessage": "Niste primili verifikacijski kod?",
|
|
85
|
-
"twofaResendButton": "Ponovno pošalji"
|
|
93
|
+
"twofaResendButton": "Ponovno pošalji",
|
|
94
|
+
"PassportLengthError": "Broj putovnice mora imati 9 znamenki",
|
|
95
|
+
"SAIdLengthError": "Južnoafrički osobni broj mora imati 13 znamenki",
|
|
96
|
+
"SAIdInvalidError": "Nevažeći južnoafrički osobni broj",
|
|
97
|
+
"PasswordMustContain": "Lozinka mora sadržavati:"
|
|
86
98
|
},
|
|
87
99
|
"tr": {
|
|
88
100
|
"dateError": "Seçilen tarih {min} ve {max} arasında olmalıdır",
|
|
@@ -109,7 +121,11 @@ export const TRANSLATIONS = {
|
|
|
109
121
|
"InvalidDocumentNumber": "Sadece sayısal karakterlere izin verilir.",
|
|
110
122
|
"twofaDescription": "<p> Doğrulama kodunu şu adrese gönderdik: <p> {destination}. </p> </p> <p> Lütfen aşağıya PIN kodunu girin. </p>",
|
|
111
123
|
"twofaResendMessage": "Doğrulama kodunu almadınız mı?",
|
|
112
|
-
"twofaResendButton": "Yeniden gönder"
|
|
124
|
+
"twofaResendButton": "Yeniden gönder",
|
|
125
|
+
"PassportLengthError": "Pasaport numarası 9 haneli olmalıdır",
|
|
126
|
+
"SAIdLengthError": "Güney Afrika kimlik numarası 13 haneli olmalıdır",
|
|
127
|
+
"SAIdInvalidError": "Geçersiz Güney Afrika kimlik numarası",
|
|
128
|
+
"PasswordMustContain": "Şifre şunları içermelidir:"
|
|
113
129
|
},
|
|
114
130
|
"pt-br": {
|
|
115
131
|
"dateError": "A data selecionada deve estar entre {min} e {max}",
|
|
@@ -136,7 +152,11 @@ export const TRANSLATIONS = {
|
|
|
136
152
|
"InvalidDocumentNumber": "Apenas caracteres numéricos são permitidos.",
|
|
137
153
|
"twofaDescription": "<p> Enviamos o código de verificação para: <p> {destination}. </p> </p> <p> Por favor, insira o PIN abaixo. </p>",
|
|
138
154
|
"twofaResendMessage": "Não recebeu o código de verificação?",
|
|
139
|
-
"twofaResendButton": "Reenviar"
|
|
155
|
+
"twofaResendButton": "Reenviar",
|
|
156
|
+
"PassportLengthError": "O número do passaporte deve ter 9 dígitos",
|
|
157
|
+
"SAIdLengthError": "O número de identificação da África do Sul deve ter 13 dígitos",
|
|
158
|
+
"SAIdInvalidError": "Número de identificação da África do Sul inválido",
|
|
159
|
+
"PasswordMustContain": "A senha deve conter:"
|
|
140
160
|
},
|
|
141
161
|
"es-mx": {
|
|
142
162
|
"dateError": "La fecha seleccionada debe ser entre {min} y {max}",
|
|
@@ -163,9 +183,40 @@ export const TRANSLATIONS = {
|
|
|
163
183
|
"InvalidDocumentNumber": "Solo se permiten caracteres numéricos.",
|
|
164
184
|
"twofaDescription": "<p> Hemos enviado el código de verificación a: <p> {destination}. </p> </p> <p> Por favor, ingrese el PIN a continuación. </p>",
|
|
165
185
|
"twofaResendMessage": "¿No recibiste el código de verificación?",
|
|
166
|
-
"twofaResendButton": "Reenviar"
|
|
186
|
+
"twofaResendButton": "Reenviar",
|
|
187
|
+
"PassportLengthError": "El número de pasaporte debe tener 9 dígitos",
|
|
188
|
+
"SAIdLengthError": "El número de identificación de Sudáfrica debe tener 13 dígitos",
|
|
189
|
+
"SAIdInvalidError": "Número de identificación de Sudáfrica inválido",
|
|
190
|
+
"PasswordMustContain": "La contraseña debe contener:"
|
|
167
191
|
}
|
|
168
192
|
};
|
|
193
|
+
export const CONSTANTS = {
|
|
194
|
+
DOCUMENT_NUMBER: "DocumentNumber",
|
|
195
|
+
FIRSTNAME_ON_DOCUMENT: "FirstnameOnDocument",
|
|
196
|
+
LASTNAME_ON_DOCUMENT: "LastnameOnDocument",
|
|
197
|
+
PASSPORT: "Passport",
|
|
198
|
+
SOUTH_AFRICAN_ID: "SouthAfricanID",
|
|
199
|
+
BIRTHDATE: "BirthDate",
|
|
200
|
+
PASSPORT_NUMERIC_REGEX: /^\d{8,9}$/,
|
|
201
|
+
SA_ID_BASIC_REGEX: /^\d{13}$/,
|
|
202
|
+
SOUTH_AFRICAN_ID_LENGTH: 13,
|
|
203
|
+
NON_LETTERS_REGEX: /[^A-Za-z]/g,
|
|
204
|
+
DATE_FORMAT: "yyyy-MM-dd",
|
|
205
|
+
PASSWORD_COMPLEXITY_PASSED: "passed",
|
|
206
|
+
PASSWORD_COMPLEXITY_FAILED: "failed"
|
|
207
|
+
};
|
|
208
|
+
export const ERROR_KEYS = {
|
|
209
|
+
PASSPORT_INVALID: 'PassportLengthError',
|
|
210
|
+
SA_ID_LENGTH: 'SAIdLengthError',
|
|
211
|
+
SA_ID_INVALID: 'SAIdInvalidError',
|
|
212
|
+
REQUIRED: 'requiredError',
|
|
213
|
+
LENGTH: 'lengthError',
|
|
214
|
+
DUPLICATE: 'duplicateInputError',
|
|
215
|
+
};
|
|
216
|
+
export const STATUS_ICONS = {
|
|
217
|
+
PASSED: '✓',
|
|
218
|
+
FAILED: '✕',
|
|
219
|
+
};
|
|
169
220
|
export const translate = (key, customLang, values) => {
|
|
170
221
|
const lang = customLang;
|
|
171
222
|
let translation = TRANSLATIONS[lang !== undefined ? lang : DEFAULT_LANGUAGE][key];
|
|
@@ -192,3 +243,24 @@ export const getTranslations = (url) => {
|
|
|
192
243
|
});
|
|
193
244
|
});
|
|
194
245
|
};
|
|
246
|
+
export const validateID = (id) => {
|
|
247
|
+
if (!CONSTANTS.SA_ID_BASIC_REGEX.test(id))
|
|
248
|
+
return false;
|
|
249
|
+
const digits = id.split("").map(n => parseInt(n, 10));
|
|
250
|
+
let oddSum = 0;
|
|
251
|
+
for (let i = 0; i < 12; i += 2) {
|
|
252
|
+
oddSum += digits[i];
|
|
253
|
+
}
|
|
254
|
+
let evenConcat = "";
|
|
255
|
+
for (let i = 1; i < 12; i += 2) {
|
|
256
|
+
evenConcat += digits[i];
|
|
257
|
+
}
|
|
258
|
+
const evenNumber = parseInt(evenConcat, 10) * 2;
|
|
259
|
+
const evenSum = evenNumber
|
|
260
|
+
.toString()
|
|
261
|
+
.split("")
|
|
262
|
+
.reduce((s, n) => s + parseInt(n, 10), 0);
|
|
263
|
+
const total = oddSum + evenSum;
|
|
264
|
+
let checkDigit = (10 - (total % 10)) % 10;
|
|
265
|
+
return checkDigit === digits[12];
|
|
266
|
+
};
|