@atlasauth/svelte 0.5.0 → 0.5.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/CHANGELOG.md +9 -0
- package/dist/components/AttemptFlow.svelte +52 -3
- package/dist/i18n.js +6 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @atlasauth/svelte changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.1
|
|
4
|
+
- **Fixed: email-code sign-in on instances without password sign-in.** After the email step the sign-in form now
|
|
5
|
+
sends the code itself (`prepare_first_factor`), shows "We sent a code to …" with the code field and a
|
|
6
|
+
"Resend code" action, and completes with `attempt_first_factor { strategy: "email_code", code }`. A password field
|
|
7
|
+
is drawn only when the server offers `password`; when it is offered, password stays the default and the emailed
|
|
8
|
+
code is one click away. If the automatic send is refused (a 429, or the app can't send email), the step shows the
|
|
9
|
+
server's error and a button to try again.
|
|
10
|
+
- The email-link step also has "Resend link". New catalog keys: `signIn.codeSentTo`, `signIn.linkSentTo`, `signIn.sending`, `signIn.resendCode`, `signIn.resendLink`, `signIn.passwordOption`.
|
|
11
|
+
|
|
3
12
|
## 0.5.0
|
|
4
13
|
Requires `@atlasauth/js` 0.9.0.
|
|
5
14
|
- **Server errors render in the app's language.** `<SignIn>` / `<SignUp>` show the catalog string
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script>import {
|
|
2
2
|
localizedErrorMessage,
|
|
3
3
|
nextStep,
|
|
4
|
-
offeredFirstFactors
|
|
4
|
+
offeredFirstFactors,
|
|
5
|
+
planFirstFactor
|
|
5
6
|
} from "@atlasauth/js";
|
|
6
7
|
import { useAtlas } from "../context";
|
|
7
8
|
import { classFor } from "../appearance";
|
|
@@ -24,6 +25,7 @@ $: step = attempt ? nextStep(attempt) : { kind: "collect_identifier" };
|
|
|
24
25
|
const strategyName = (s) => typeof s === "string" ? s : String(s?.strategy ?? "");
|
|
25
26
|
$: offered = step.kind === "collect_first_factor" ? offeredFirstFactors(step.strategies.map(strategyName), emailDelivery) : [];
|
|
26
27
|
$: emailOptions = onPrepare ? offered.filter((s) => s === "email_code" || s === "email_link") : [];
|
|
28
|
+
$: plan = planFirstFactor(offered);
|
|
27
29
|
$: showPassword = offered.includes("password") || emailOptions.length === 0;
|
|
28
30
|
let prepared = null;
|
|
29
31
|
$: sent = prepared && prepared.attemptId === (attempt?.id ?? null) ? prepared.strategy : null;
|
|
@@ -32,6 +34,17 @@ async function prepare(strategy) {
|
|
|
32
34
|
const attemptId = attempt?.id ?? null;
|
|
33
35
|
if (await onPrepare(strategy)) prepared = { strategy, attemptId };
|
|
34
36
|
}
|
|
37
|
+
let autoSentFor = null;
|
|
38
|
+
$: if (step.kind === "collect_first_factor" && onPrepare && plan.autoSend && attempt?.id && autoSentFor !== attempt.id && sent === null) {
|
|
39
|
+
autoSentFor = attempt.id;
|
|
40
|
+
void prepare(plan.autoSend);
|
|
41
|
+
}
|
|
42
|
+
$: sending = step.kind === "collect_first_factor" && sent === null && !!onPrepare && !plan.password && emailOptions.length > 0;
|
|
43
|
+
$: identifier = attempt?.identifier ?? "";
|
|
44
|
+
function usePassword() {
|
|
45
|
+
prepared = null;
|
|
46
|
+
values = {};
|
|
47
|
+
}
|
|
35
48
|
$: fields = (() => {
|
|
36
49
|
switch (step.kind) {
|
|
37
50
|
case "collect_identifier":
|
|
@@ -40,6 +53,7 @@ $: fields = (() => {
|
|
|
40
53
|
if (sent === "email_code") {
|
|
41
54
|
return [{ name: "code", labelKey: "signIn.emailCodeLabel", type: "text" }];
|
|
42
55
|
}
|
|
56
|
+
if (sending || sent === "email_link") return [];
|
|
43
57
|
return showPassword ? [{ name: "password", labelKey: "signIn.passwordLabel", type: "password" }] : [];
|
|
44
58
|
case "collect_second_factor":
|
|
45
59
|
return [{ name: "code", labelKey: "mfa.codeLabel", type: "text" }];
|
|
@@ -65,7 +79,7 @@ $: message = (() => {
|
|
|
65
79
|
case "restart":
|
|
66
80
|
return t("error.generic");
|
|
67
81
|
case "collect_first_factor":
|
|
68
|
-
return
|
|
82
|
+
return null;
|
|
69
83
|
case "collect_captcha":
|
|
70
84
|
case "collect_identifier":
|
|
71
85
|
case "collect_second_factor":
|
|
@@ -79,10 +93,14 @@ $: message = (() => {
|
|
|
79
93
|
})();
|
|
80
94
|
$: showSubmit = step.kind !== "done" && step.kind !== "await_oauth" && message === null && // Only emailed factors on offer: the option buttons are the way forward.
|
|
81
95
|
(step.kind !== "collect_first_factor" || fields.length > 0);
|
|
82
|
-
$: showEmailOptions = step.kind === "collect_first_factor" && message === null && sent === null && emailOptions.length > 0;
|
|
96
|
+
$: showEmailOptions = step.kind === "collect_first_factor" && message === null && sent === null && emailOptions.length > 0 && !(sending && busy);
|
|
83
97
|
$: showCaptcha = !!captcha && (step.kind === "collect_identifier" || step.kind === "collect_captcha");
|
|
84
98
|
function handleSubmit(event) {
|
|
85
99
|
event.preventDefault();
|
|
100
|
+
if (step.kind === "collect_first_factor") {
|
|
101
|
+
onSubmit(sent === "email_code" ? { code: values.code ?? "" } : { password: values.password ?? "" });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
86
104
|
onSubmit(values);
|
|
87
105
|
}
|
|
88
106
|
</script>
|
|
@@ -103,6 +121,15 @@ function handleSubmit(event) {
|
|
|
103
121
|
the widget resubmits the identifier on its own; the button retries. -->
|
|
104
122
|
<p class="atlas-text">{t('captcha.prompt')}</p>
|
|
105
123
|
{/if}
|
|
124
|
+
{#if step.kind === 'collect_first_factor' && sent === 'email_code'}
|
|
125
|
+
<p class="atlas-text" data-atlas-code-sent>{t('signIn.codeSentTo', { email: identifier })}</p>
|
|
126
|
+
{/if}
|
|
127
|
+
{#if step.kind === 'collect_first_factor' && sent === 'email_link'}
|
|
128
|
+
<p class="atlas-text" data-atlas-link-sent>{t('signIn.linkSentTo', { email: identifier })}</p>
|
|
129
|
+
{/if}
|
|
130
|
+
{#if sending}
|
|
131
|
+
<p class="atlas-text" aria-live="polite">{t('signIn.sending')}</p>
|
|
132
|
+
{/if}
|
|
106
133
|
{#each fields as f (f.name)}
|
|
107
134
|
<label class="atlas-field">
|
|
108
135
|
<span>{t(f.labelKey)}</span>
|
|
@@ -118,6 +145,28 @@ function handleSubmit(event) {
|
|
|
118
145
|
{/each}
|
|
119
146
|
</label>
|
|
120
147
|
{/each}
|
|
148
|
+
{#if step.kind === 'collect_first_factor' && sent !== null}
|
|
149
|
+
<button
|
|
150
|
+
class={cls('formButtonSecondary', 'atlas-button-secondary')}
|
|
151
|
+
type="button"
|
|
152
|
+
data-atlas-resend
|
|
153
|
+
disabled={busy}
|
|
154
|
+
on:click={() => void prepare(sent)}
|
|
155
|
+
>
|
|
156
|
+
{t(sent === 'email_code' ? 'signIn.resendCode' : 'signIn.resendLink')}
|
|
157
|
+
</button>
|
|
158
|
+
{#if plan.password}
|
|
159
|
+
<button
|
|
160
|
+
class={cls('formButtonSecondary', 'atlas-button-secondary')}
|
|
161
|
+
type="button"
|
|
162
|
+
data-strategy="password"
|
|
163
|
+
disabled={busy}
|
|
164
|
+
on:click={usePassword}
|
|
165
|
+
>
|
|
166
|
+
{t('signIn.passwordOption')}
|
|
167
|
+
</button>
|
|
168
|
+
{/if}
|
|
169
|
+
{/if}
|
|
121
170
|
{#if showEmailOptions}
|
|
122
171
|
{#each emailOptions as strategy (strategy)}
|
|
123
172
|
<button
|
package/dist/i18n.js
CHANGED
|
@@ -25,6 +25,12 @@ export const EN_US = {
|
|
|
25
25
|
'signIn.emailCodeOption': 'Email me a code',
|
|
26
26
|
'signIn.emailLinkOption': 'Email me a sign-in link',
|
|
27
27
|
'signIn.magicLinkSent': 'Check your email for a sign-in link.',
|
|
28
|
+
'signIn.codeSentTo': 'We sent a code to {email}. Enter it below.',
|
|
29
|
+
'signIn.linkSentTo': 'We sent a sign-in link to {email}. Open it on any device to continue.',
|
|
30
|
+
'signIn.sending': 'Sending…',
|
|
31
|
+
'signIn.resendCode': 'Resend code',
|
|
32
|
+
'signIn.resendLink': 'Resend link',
|
|
33
|
+
'signIn.passwordOption': 'Use your password instead',
|
|
28
34
|
'signIn.checkOtherTab': 'You can close this tab — you are signed in where you started.',
|
|
29
35
|
'signUp.title': 'Create your account',
|
|
30
36
|
'signUp.submit': 'Continue',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlasauth/svelte",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"svelte": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@atlasauth/design": "0.2.0",
|
|
26
|
-
"@atlasauth/js": "0.9.0",
|
|
27
26
|
"@atlasauth/authz": "0.1.1",
|
|
28
|
-
"@atlasauth/backend": "0.7.
|
|
27
|
+
"@atlasauth/backend": "0.7.3",
|
|
28
|
+
"@atlasauth/js": "0.10.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"svelte": ">=4",
|