@sparkvault/sdk 1.1.5 → 1.1.6
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/identity/views/icons.d.ts +0 -4
- package/dist/identity/views/totp-verify.d.ts +1 -1
- package/dist/sparkvault.cjs.js +24 -106
- package/dist/sparkvault.cjs.js.map +1 -1
- package/dist/sparkvault.esm.js +24 -106
- package/dist/sparkvault.esm.js.map +1 -1
- package/dist/sparkvault.js +1 -1
- package/dist/sparkvault.js.map +1 -1
- package/package.json +1 -1
|
@@ -12,10 +12,6 @@ export declare function createCheckmarkIcon(): SVGSVGElement;
|
|
|
12
12
|
* Back arrow (chevron left)
|
|
13
13
|
*/
|
|
14
14
|
export declare function createBackArrowIcon(): SVGSVGElement;
|
|
15
|
-
/**
|
|
16
|
-
* Resend/refresh icon - circular arrow
|
|
17
|
-
*/
|
|
18
|
-
export declare function createResendIcon(): SVGSVGElement;
|
|
19
15
|
/**
|
|
20
16
|
* Close (X) icon
|
|
21
17
|
*/
|
|
@@ -19,7 +19,6 @@ export declare class TotpVerifyView implements View {
|
|
|
19
19
|
private inputElements;
|
|
20
20
|
private submitButton;
|
|
21
21
|
private resendButton;
|
|
22
|
-
private timerDisplay;
|
|
23
22
|
private backLink;
|
|
24
23
|
private errorContainer;
|
|
25
24
|
private resendTimer;
|
|
@@ -34,6 +33,7 @@ export declare class TotpVerifyView implements View {
|
|
|
34
33
|
private readonly inputHandlers;
|
|
35
34
|
constructor(props: TotpVerifyViewProps);
|
|
36
35
|
render(): HTMLElement;
|
|
36
|
+
private createBackLink;
|
|
37
37
|
private createInputGroup;
|
|
38
38
|
private handleInput;
|
|
39
39
|
private handleKeyDown;
|
package/dist/sparkvault.cjs.js
CHANGED
|
@@ -2305,71 +2305,6 @@ function getStyles(options) {
|
|
|
2305
2305
|
TOTP VIEW
|
|
2306
2306
|
======================================== */
|
|
2307
2307
|
|
|
2308
|
-
.sv-resend-row {
|
|
2309
|
-
display: flex;
|
|
2310
|
-
align-items: center;
|
|
2311
|
-
justify-content: space-between;
|
|
2312
|
-
margin-top: 16px;
|
|
2313
|
-
}
|
|
2314
|
-
|
|
2315
|
-
.sv-resend-btn {
|
|
2316
|
-
display: inline-flex;
|
|
2317
|
-
align-items: center;
|
|
2318
|
-
gap: 6px;
|
|
2319
|
-
color: ${tokens.textSecondary};
|
|
2320
|
-
font-size: 13px;
|
|
2321
|
-
font-weight: 500;
|
|
2322
|
-
text-decoration: none;
|
|
2323
|
-
cursor: pointer;
|
|
2324
|
-
background: none;
|
|
2325
|
-
border: none;
|
|
2326
|
-
padding: 0;
|
|
2327
|
-
transition: color 0.15s ease;
|
|
2328
|
-
}
|
|
2329
|
-
|
|
2330
|
-
.sv-resend-btn:hover:not(:disabled) {
|
|
2331
|
-
color: ${tokens.primary};
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2334
|
-
.sv-resend-btn:disabled {
|
|
2335
|
-
opacity: 0.5;
|
|
2336
|
-
cursor: not-allowed;
|
|
2337
|
-
}
|
|
2338
|
-
|
|
2339
|
-
.sv-resend-btn svg {
|
|
2340
|
-
width: 14px;
|
|
2341
|
-
height: 14px;
|
|
2342
|
-
}
|
|
2343
|
-
|
|
2344
|
-
.sv-resend-timer {
|
|
2345
|
-
font-size: 13px;
|
|
2346
|
-
font-weight: 500;
|
|
2347
|
-
color: ${tokens.textMuted};
|
|
2348
|
-
min-width: 24px;
|
|
2349
|
-
text-align: right;
|
|
2350
|
-
}
|
|
2351
|
-
|
|
2352
|
-
.sv-alt-method-link {
|
|
2353
|
-
display: block;
|
|
2354
|
-
width: 100%;
|
|
2355
|
-
text-align: center;
|
|
2356
|
-
color: ${tokens.textSecondary};
|
|
2357
|
-
font-size: 13px;
|
|
2358
|
-
font-weight: 400;
|
|
2359
|
-
text-decoration: none;
|
|
2360
|
-
cursor: pointer;
|
|
2361
|
-
background: none;
|
|
2362
|
-
border: none;
|
|
2363
|
-
padding: 16px 0 0 0;
|
|
2364
|
-
margin-top: 8px;
|
|
2365
|
-
transition: color 0.15s ease;
|
|
2366
|
-
}
|
|
2367
|
-
|
|
2368
|
-
.sv-alt-method-link:hover {
|
|
2369
|
-
color: ${tokens.primary};
|
|
2370
|
-
text-decoration: underline;
|
|
2371
|
-
}
|
|
2372
|
-
|
|
2373
2308
|
.sv-resend-container {
|
|
2374
2309
|
text-align: center;
|
|
2375
2310
|
margin-top: 16px;
|
|
@@ -2761,27 +2696,6 @@ function createBackArrowIcon() {
|
|
|
2761
2696
|
}));
|
|
2762
2697
|
return svg;
|
|
2763
2698
|
}
|
|
2764
|
-
/**
|
|
2765
|
-
* Resend/refresh icon - circular arrow
|
|
2766
|
-
*/
|
|
2767
|
-
function createResendIcon() {
|
|
2768
|
-
const svg = createSvgElement('0 0 16 16');
|
|
2769
|
-
svg.appendChild(createPath('M13.5 8a5.5 5.5 0 11-1.21-3.45', {
|
|
2770
|
-
stroke: 'currentColor',
|
|
2771
|
-
'stroke-width': '1.5',
|
|
2772
|
-
'stroke-linecap': 'round',
|
|
2773
|
-
'stroke-linejoin': 'round',
|
|
2774
|
-
fill: 'none',
|
|
2775
|
-
}));
|
|
2776
|
-
svg.appendChild(createPath('M13.5 2.5v2.5H11', {
|
|
2777
|
-
stroke: 'currentColor',
|
|
2778
|
-
'stroke-width': '1.5',
|
|
2779
|
-
'stroke-linecap': 'round',
|
|
2780
|
-
'stroke-linejoin': 'round',
|
|
2781
|
-
fill: 'none',
|
|
2782
|
-
}));
|
|
2783
|
-
return svg;
|
|
2784
|
-
}
|
|
2785
2699
|
/**
|
|
2786
2700
|
* Close (X) icon
|
|
2787
2701
|
*/
|
|
@@ -3704,7 +3618,6 @@ class TotpVerifyView {
|
|
|
3704
3618
|
this.inputElements = [];
|
|
3705
3619
|
this.submitButton = null;
|
|
3706
3620
|
this.resendButton = null;
|
|
3707
|
-
this.timerDisplay = null;
|
|
3708
3621
|
this.backLink = null;
|
|
3709
3622
|
this.errorContainer = null;
|
|
3710
3623
|
this.resendTimer = null;
|
|
@@ -3722,12 +3635,14 @@ class TotpVerifyView {
|
|
|
3722
3635
|
}
|
|
3723
3636
|
render() {
|
|
3724
3637
|
const container = div();
|
|
3638
|
+
this.backLink = this.createBackLink();
|
|
3725
3639
|
const title = document.createElement('h3');
|
|
3726
3640
|
title.className = 'sv-title';
|
|
3727
3641
|
title.textContent = 'Enter verification code';
|
|
3642
|
+
const methodText = this.props.method === 'email' ? 'email' : 'phone';
|
|
3728
3643
|
const subtitle = document.createElement('p');
|
|
3729
3644
|
subtitle.className = 'sv-subtitle';
|
|
3730
|
-
subtitle.innerHTML = `
|
|
3645
|
+
subtitle.innerHTML = `We sent a 6-digit code to your ${methodText}<br><strong>${escapeHtml(this.props.email)}</strong>`;
|
|
3731
3646
|
this.errorContainer = div();
|
|
3732
3647
|
if (this.props.error) {
|
|
3733
3648
|
this.errorContainer.appendChild(errorMessage(this.props.error));
|
|
@@ -3745,32 +3660,35 @@ class TotpVerifyView {
|
|
|
3745
3660
|
this.startBackoff(this.props.backoffExpires);
|
|
3746
3661
|
}
|
|
3747
3662
|
}
|
|
3748
|
-
|
|
3749
|
-
const resendContainer = div('sv-resend-row');
|
|
3663
|
+
const resendContainer = div('sv-resend-container');
|
|
3750
3664
|
this.resendButton = document.createElement('button');
|
|
3751
|
-
this.resendButton.className = 'sv-
|
|
3752
|
-
this.resendButton.
|
|
3753
|
-
this.resendButton.appendChild(document.createTextNode('Resend code'));
|
|
3665
|
+
this.resendButton.className = 'sv-back-link';
|
|
3666
|
+
this.resendButton.textContent = 'Resend code';
|
|
3754
3667
|
this.resendButton.addEventListener('click', this.boundHandleResend);
|
|
3755
|
-
this.timerDisplay = document.createElement('span');
|
|
3756
|
-
this.timerDisplay.className = 'sv-resend-timer';
|
|
3757
3668
|
resendContainer.appendChild(this.resendButton);
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
this.backLink.textContent = 'Log in another way';
|
|
3763
|
-
this.backLink.addEventListener('click', this.boundHandleBack);
|
|
3669
|
+
// Use flex column layout so we can use CSS order for tab order control
|
|
3670
|
+
container.style.display = 'flex';
|
|
3671
|
+
container.style.flexDirection = 'column';
|
|
3672
|
+
// Append in TAB ORDER (not visual order) - back link last for tab navigation
|
|
3764
3673
|
container.appendChild(title);
|
|
3765
3674
|
container.appendChild(subtitle);
|
|
3766
3675
|
container.appendChild(this.errorContainer);
|
|
3767
3676
|
container.appendChild(inputGroup);
|
|
3768
3677
|
container.appendChild(this.submitButton);
|
|
3769
3678
|
container.appendChild(resendContainer);
|
|
3770
|
-
container.appendChild(this.backLink);
|
|
3679
|
+
container.appendChild(this.backLink); // Last in DOM = last in tab order
|
|
3771
3680
|
this.focusTimeoutId = setTimeout(() => this.inputElements[0]?.focus(), 50);
|
|
3772
3681
|
return container;
|
|
3773
3682
|
}
|
|
3683
|
+
createBackLink() {
|
|
3684
|
+
const link = document.createElement('button');
|
|
3685
|
+
link.className = 'sv-back-link';
|
|
3686
|
+
link.style.order = '-1'; // Visually keep at top with flexbox (DOM order controls tab order)
|
|
3687
|
+
link.appendChild(createBackArrowIcon());
|
|
3688
|
+
link.appendChild(document.createTextNode(' Choose another method'));
|
|
3689
|
+
link.addEventListener('click', this.boundHandleBack);
|
|
3690
|
+
return link;
|
|
3691
|
+
}
|
|
3774
3692
|
createInputGroup() {
|
|
3775
3693
|
const group = div('sv-totp-input-group');
|
|
3776
3694
|
for (let i = 0; i < CODE_LENGTH; i++) {
|
|
@@ -3945,15 +3863,15 @@ class TotpVerifyView {
|
|
|
3945
3863
|
this.resendTimer = new CooldownTimer({
|
|
3946
3864
|
duration: 30,
|
|
3947
3865
|
onTick: (secondsRemaining) => {
|
|
3948
|
-
if (!this.resendButton
|
|
3866
|
+
if (!this.resendButton)
|
|
3949
3867
|
return;
|
|
3950
|
-
this.
|
|
3868
|
+
this.resendButton.textContent = `Resend code (${secondsRemaining}s)`;
|
|
3951
3869
|
this.resendButton.disabled = true;
|
|
3952
3870
|
},
|
|
3953
3871
|
onComplete: () => {
|
|
3954
|
-
if (!this.resendButton
|
|
3872
|
+
if (!this.resendButton)
|
|
3955
3873
|
return;
|
|
3956
|
-
this.
|
|
3874
|
+
this.resendButton.textContent = 'Resend code';
|
|
3957
3875
|
this.resendButton.disabled = false;
|
|
3958
3876
|
},
|
|
3959
3877
|
});
|