@atlasauth/angular 0.6.0 → 0.7.0
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 +6 -0
- package/dist/esm2022/lib/atlas.config.mjs +1 -1
- package/dist/esm2022/lib/atlas.service.mjs +4 -2
- package/dist/esm2022/lib/components/user-profile.component.mjs +103 -2
- package/dist/esm2022/lib/i18n.mjs +6 -1
- package/dist/esm2022/lib/version.mjs +2 -2
- package/dist/fesm2022/atlasauth-angular.mjs +110 -2
- package/dist/fesm2022/atlasauth-angular.mjs.map +1 -1
- package/dist/lib/atlas.config.d.ts +13 -1
- package/dist/lib/components/user-profile.component.d.ts +7 -0
- package/dist/lib/version.d.ts +1 -1
- package/package.json +2 -2
|
@@ -4,7 +4,7 @@ import { isPlatformBrowser, DOCUMENT } from '@angular/common';
|
|
|
4
4
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { BehaviorSubject, Subject, combineLatest, firstValueFrom } from 'rxjs';
|
|
6
6
|
import { map, distinctUntilChanged, filter, take } from 'rxjs/operators';
|
|
7
|
-
import { TokenCache, SignOutNotifier, resolveFrontendApi, catalogLocale, FapiClient, SignOutGuard, localizedErrorMessage, getTemplateToken, getProviderToken, signOutReasonFromClient, readRedirectResult, completeOAuthPopupLanding, mapOAuthPopupPayload, stripRedirectParams, closeOAuthPopupAfterSignIn, SDK_HEADER, sdkHeaderValue, reportSdkAdvisory, readExpiry, msUntilRefresh, nextStep, createCaptchaController, atlasCaptchaLabels, flowFromPending, initialFlow, fetchInstanceSettings, offeredFirstFactors, prepareFactor, signInCaptchaOptions, flowNeedsCaptcha, planFirstFactor, advanceWithCaptcha, createSignUp, shouldKeepPolling, pollAttempt } from '@atlasauth/js';
|
|
7
|
+
import { TokenCache, SignOutNotifier, resolveFrontendApi, catalogLocale, configureReferralCapture, FapiClient, SignOutGuard, localizedErrorMessage, getTemplateToken, getProviderToken, signOutReasonFromClient, readRedirectResult, completeOAuthPopupLanding, mapOAuthPopupPayload, stripRedirectParams, closeOAuthPopupAfterSignIn, SDK_HEADER, sdkHeaderValue, reportSdkAdvisory, readExpiry, msUntilRefresh, nextStep, createCaptchaController, atlasCaptchaLabels, flowFromPending, initialFlow, fetchInstanceSettings, offeredFirstFactors, prepareFactor, signInCaptchaOptions, flowNeedsCaptcha, planFirstFactor, advanceWithCaptcha, createSignUp, shouldKeepPolling, pollAttempt } from '@atlasauth/js';
|
|
8
8
|
export { FapiClient, SIGN_OUT_EVENT, SignOutError, advance, flowFromPending, getProviderToken, initialFlow, onAtlasSignOut, pollAttempt, prepareFactor, requestForStep, shouldKeepPolling } from '@atlasauth/js';
|
|
9
9
|
import { evaluate } from '@atlasauth/authz';
|
|
10
10
|
export { evaluate, hasFromClaims } from '@atlasauth/authz';
|
|
@@ -219,6 +219,11 @@ const EN_US = {
|
|
|
219
219
|
'userProfile.addEmail': 'Add an email address',
|
|
220
220
|
'userProfile.makePrimary': 'Make primary',
|
|
221
221
|
'userProfile.unverified': 'Unverified',
|
|
222
|
+
'userProfile.verify': 'Verify',
|
|
223
|
+
'userProfile.verifyConfirm': 'Confirm',
|
|
224
|
+
'userProfile.verifyCodePlaceholder': 'Code from the email',
|
|
225
|
+
'userProfile.verifySendFailed': 'We could not send a code right now. Try again in a minute.',
|
|
226
|
+
'userProfile.verifyCodeRejected': 'That code was not accepted.',
|
|
222
227
|
'userProfile.revokeDevice': 'Sign out',
|
|
223
228
|
'userProfile.deleteAccount': 'Delete account',
|
|
224
229
|
'organization.switcher': 'Switch organization',
|
|
@@ -286,7 +291,7 @@ function withFallback(locale) {
|
|
|
286
291
|
}
|
|
287
292
|
|
|
288
293
|
/** This package's version, sent as `X-Atlas-SDK` (kept in step with package.json by a test). */
|
|
289
|
-
const ATLAS_ANGULAR_VERSION = '0.
|
|
294
|
+
const ATLAS_ANGULAR_VERSION = '0.7.0';
|
|
290
295
|
const ATLAS_ANGULAR_SDK = { name: '@atlasauth/angular', version: ATLAS_ANGULAR_VERSION };
|
|
291
296
|
|
|
292
297
|
/**
|
|
@@ -397,6 +402,8 @@ class AtlasService {
|
|
|
397
402
|
this.catalog = options.localization ? withFallback(options.localization) : EN_US;
|
|
398
403
|
this.errorCatalog = options.localization ?? EN_US;
|
|
399
404
|
this.requestLocale = catalogLocale(options.localization);
|
|
405
|
+
// Referral attribution: app-wide options every FAPI client on the page falls back to.
|
|
406
|
+
configureReferralCapture({ referral: options.referral, referralConsent: options.referralConsent });
|
|
400
407
|
this.fapiClient = new FapiClient({
|
|
401
408
|
publishableKey: this.publishableKey,
|
|
402
409
|
baseUrl: this.baseUrl,
|
|
@@ -2303,6 +2310,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2303
2310
|
*/
|
|
2304
2311
|
class UserProfileComponent {
|
|
2305
2312
|
atlas = inject(AtlasService);
|
|
2313
|
+
// An unverified address (added and never confirmed, or the sign-up address on
|
|
2314
|
+
// an app that did not require verification) can be proven here: send a code,
|
|
2315
|
+
// then enter it.
|
|
2316
|
+
verifying = signal(null);
|
|
2317
|
+
code = signal('');
|
|
2318
|
+
busy = signal(false);
|
|
2319
|
+
verifyError = signal(null);
|
|
2320
|
+
client = this.atlas.createFapiClient();
|
|
2321
|
+
async sendCode(id) {
|
|
2322
|
+
this.verifyError.set(null);
|
|
2323
|
+
this.busy.set(true);
|
|
2324
|
+
const res = await this.client.post(`/v1/client/me/email_addresses/${id}/prepare_verification`);
|
|
2325
|
+
this.busy.set(false);
|
|
2326
|
+
if (!res.ok) {
|
|
2327
|
+
this.verifyError.set(this.t('userProfile.verifySendFailed'));
|
|
2328
|
+
return;
|
|
2329
|
+
}
|
|
2330
|
+
this.code.set('');
|
|
2331
|
+
this.verifying.set(id);
|
|
2332
|
+
}
|
|
2333
|
+
async confirmCode() {
|
|
2334
|
+
const id = this.verifying();
|
|
2335
|
+
if (!id)
|
|
2336
|
+
return;
|
|
2337
|
+
this.verifyError.set(null);
|
|
2338
|
+
this.busy.set(true);
|
|
2339
|
+
const res = await this.client.post(`/v1/client/me/email_addresses/${id}/attempt_verification`, {
|
|
2340
|
+
code: this.code(),
|
|
2341
|
+
});
|
|
2342
|
+
this.busy.set(false);
|
|
2343
|
+
if (!res.ok) {
|
|
2344
|
+
this.verifyError.set(this.t('userProfile.verifyCodeRejected'));
|
|
2345
|
+
return;
|
|
2346
|
+
}
|
|
2347
|
+
this.verifying.set(null);
|
|
2348
|
+
await this.atlas.reload();
|
|
2349
|
+
}
|
|
2306
2350
|
t(key) {
|
|
2307
2351
|
return translate(this.atlas.localization, key);
|
|
2308
2352
|
}
|
|
@@ -2323,10 +2367,42 @@ class UserProfileComponent {
|
|
|
2323
2367
|
{{ email.email_address }}
|
|
2324
2368
|
@if (!email.verified) {
|
|
2325
2369
|
<em> — {{ t('userProfile.unverified') }}</em>
|
|
2370
|
+
@if (verifying() === email.id) {
|
|
2371
|
+
<span data-atlas="email-verify">
|
|
2372
|
+
<input
|
|
2373
|
+
[class]="cls('formFieldInput', 'atlas-account-input')"
|
|
2374
|
+
inputmode="numeric"
|
|
2375
|
+
autocomplete="one-time-code"
|
|
2376
|
+
[placeholder]="t('userProfile.verifyCodePlaceholder')"
|
|
2377
|
+
[value]="code()"
|
|
2378
|
+
(input)="code.set($any($event.target).value)"
|
|
2379
|
+
/>
|
|
2380
|
+
<button
|
|
2381
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
2382
|
+
type="button"
|
|
2383
|
+
[disabled]="busy()"
|
|
2384
|
+
(click)="confirmCode()"
|
|
2385
|
+
>
|
|
2386
|
+
{{ t('userProfile.verifyConfirm') }}
|
|
2387
|
+
</button>
|
|
2388
|
+
</span>
|
|
2389
|
+
} @else {
|
|
2390
|
+
<button
|
|
2391
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
2392
|
+
type="button"
|
|
2393
|
+
[disabled]="busy()"
|
|
2394
|
+
(click)="sendCode(email.id)"
|
|
2395
|
+
>
|
|
2396
|
+
{{ t('userProfile.verify') }}
|
|
2397
|
+
</button>
|
|
2398
|
+
}
|
|
2326
2399
|
}
|
|
2327
2400
|
</li>
|
|
2328
2401
|
}
|
|
2329
2402
|
</ul>
|
|
2403
|
+
@if (verifyError(); as message) {
|
|
2404
|
+
<p role="alert">{{ message }}</p>
|
|
2405
|
+
}
|
|
2330
2406
|
</section>
|
|
2331
2407
|
|
|
2332
2408
|
<section>
|
|
@@ -2356,10 +2432,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2356
2432
|
{{ email.email_address }}
|
|
2357
2433
|
@if (!email.verified) {
|
|
2358
2434
|
<em> — {{ t('userProfile.unverified') }}</em>
|
|
2435
|
+
@if (verifying() === email.id) {
|
|
2436
|
+
<span data-atlas="email-verify">
|
|
2437
|
+
<input
|
|
2438
|
+
[class]="cls('formFieldInput', 'atlas-account-input')"
|
|
2439
|
+
inputmode="numeric"
|
|
2440
|
+
autocomplete="one-time-code"
|
|
2441
|
+
[placeholder]="t('userProfile.verifyCodePlaceholder')"
|
|
2442
|
+
[value]="code()"
|
|
2443
|
+
(input)="code.set($any($event.target).value)"
|
|
2444
|
+
/>
|
|
2445
|
+
<button
|
|
2446
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
2447
|
+
type="button"
|
|
2448
|
+
[disabled]="busy()"
|
|
2449
|
+
(click)="confirmCode()"
|
|
2450
|
+
>
|
|
2451
|
+
{{ t('userProfile.verifyConfirm') }}
|
|
2452
|
+
</button>
|
|
2453
|
+
</span>
|
|
2454
|
+
} @else {
|
|
2455
|
+
<button
|
|
2456
|
+
[class]="cls('formButtonSecondary', 'atlas-button-secondary')"
|
|
2457
|
+
type="button"
|
|
2458
|
+
[disabled]="busy()"
|
|
2459
|
+
(click)="sendCode(email.id)"
|
|
2460
|
+
>
|
|
2461
|
+
{{ t('userProfile.verify') }}
|
|
2462
|
+
</button>
|
|
2463
|
+
}
|
|
2359
2464
|
}
|
|
2360
2465
|
</li>
|
|
2361
2466
|
}
|
|
2362
2467
|
</ul>
|
|
2468
|
+
@if (verifyError(); as message) {
|
|
2469
|
+
<p role="alert">{{ message }}</p>
|
|
2470
|
+
}
|
|
2363
2471
|
</section>
|
|
2364
2472
|
|
|
2365
2473
|
<section>
|