@atlasauth/react 0.12.0 → 0.14.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 +29 -0
- package/dist/AtlasProvider.d.ts +10 -2
- package/dist/AtlasProvider.js +27 -3
- package/dist/AtlasProvider.js.map +1 -1
- package/dist/account.d.ts +7 -0
- package/dist/account.js +115 -7
- package/dist/account.js.map +1 -1
- package/dist/billing.d.ts +25 -0
- package/dist/billing.js +40 -5
- package/dist/billing.js.map +1 -1
- package/dist/components.d.ts +7 -3
- package/dist/components.js +11 -1
- package/dist/components.js.map +1 -1
- package/dist/flow.d.ts +41 -9
- package/dist/flow.js +194 -26
- package/dist/flow.js.map +1 -1
- package/dist/i18n.js +57 -0
- package/dist/i18n.js.map +1 -1
- package/dist/impersonation.d.ts +25 -0
- package/dist/impersonation.js +52 -0
- package/dist/impersonation.js.map +1 -0
- package/dist/mfa-steps.d.ts +53 -0
- package/dist/mfa-steps.js +148 -0
- package/dist/mfa-steps.js.map +1 -0
- package/dist/organization.d.ts +82 -1
- package/dist/organization.js +222 -4
- package/dist/organization.js.map +1 -1
- package/dist/reverification.d.ts +19 -0
- package/dist/reverification.js +49 -1
- package/dist/reverification.js.map +1 -1
- package/dist/sign-in-with-atlas.d.ts +8 -6
- package/dist/sign-in-with-atlas.js +2 -2
- package/dist/sign-in-with-atlas.js.map +1 -1
- package/dist/sign-in.js +2 -2
- package/dist/sign-in.js.map +1 -1
- package/dist/sign-up.d.ts +6 -0
- package/dist/sign-up.js +67 -14
- package/dist/sign-up.js.map +1 -1
- package/dist/styles.js +11 -0
- package/dist/styles.js.map +1 -1
- package/dist/types.d.ts +19 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type EndImpersonationResult, type ImpersonationActor } from '@atlasauth/js';
|
|
2
|
+
/** What {@link useImpersonation} returns. */
|
|
3
|
+
export interface UseImpersonationReturn {
|
|
4
|
+
/** The active session is an impersonation (its token carries `act`). */
|
|
5
|
+
isImpersonating: boolean;
|
|
6
|
+
/** Who is acting, or null. */
|
|
7
|
+
actor: ImpersonationActor | null;
|
|
8
|
+
/** The impersonator's own session is kept on this browser and can be resumed. */
|
|
9
|
+
canReturnToAdmin: boolean;
|
|
10
|
+
/** End the impersonation; resumes the impersonator's own session when there is one. */
|
|
11
|
+
endImpersonation(): Promise<EndImpersonationResult>;
|
|
12
|
+
}
|
|
13
|
+
/** The impersonation state of the active session, and "return to admin". */
|
|
14
|
+
export declare function useImpersonation(): UseImpersonationReturn;
|
|
15
|
+
export interface ImpersonationBannerProps {
|
|
16
|
+
/** Called after the impersonation ended, with the outcome. */
|
|
17
|
+
onEnded?: (result: EndImpersonationResult) => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A banner shown only while the active session is an impersonation: it names
|
|
21
|
+
* the user being acted as, and offers "Return to admin" (resume the
|
|
22
|
+
* impersonator's own session) or, with no session to return to, "End
|
|
23
|
+
* impersonation". Renders nothing on an ordinary session.
|
|
24
|
+
*/
|
|
25
|
+
export declare function ImpersonationBanner({ onEnded }: ImpersonationBannerProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useImpersonation = useImpersonation;
|
|
5
|
+
exports.ImpersonationBanner = ImpersonationBanner;
|
|
6
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const js_1 = require("@atlasauth/js");
|
|
9
|
+
const AtlasProvider_1 = require("./AtlasProvider");
|
|
10
|
+
const components_shared_1 = require("./components-shared");
|
|
11
|
+
/** The impersonation state of the active session, and "return to admin". */
|
|
12
|
+
function useImpersonation() {
|
|
13
|
+
const { claims, session, endImpersonation } = (0, AtlasProvider_1.useAtlas)();
|
|
14
|
+
const actor = (0, js_1.actorFromClaims)(claims) ?? session?.actor ?? null;
|
|
15
|
+
return {
|
|
16
|
+
isImpersonating: actor !== null,
|
|
17
|
+
actor,
|
|
18
|
+
canReturnToAdmin: actor !== null && Boolean(session?.actor_session_id),
|
|
19
|
+
endImpersonation,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A banner shown only while the active session is an impersonation: it names
|
|
24
|
+
* the user being acted as, and offers "Return to admin" (resume the
|
|
25
|
+
* impersonator's own session) or, with no session to return to, "End
|
|
26
|
+
* impersonation". Renders nothing on an ordinary session.
|
|
27
|
+
*/
|
|
28
|
+
function ImpersonationBanner({ onEnded }) {
|
|
29
|
+
const { user } = (0, AtlasProvider_1.useAtlas)();
|
|
30
|
+
const { isImpersonating, canReturnToAdmin, endImpersonation } = useImpersonation();
|
|
31
|
+
const t = (0, components_shared_1.useText)();
|
|
32
|
+
const cls = (0, components_shared_1.useClasses)();
|
|
33
|
+
const [busy, setBusy] = (0, react_1.useState)(false);
|
|
34
|
+
if (!isImpersonating)
|
|
35
|
+
return null;
|
|
36
|
+
const name = [user?.first_name, user?.last_name].filter(Boolean).join(' ') ||
|
|
37
|
+
user?.username ||
|
|
38
|
+
user?.email_addresses?.find((e) => e.primary)?.email_address ||
|
|
39
|
+
user?.id ||
|
|
40
|
+
'';
|
|
41
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: cls('alert', 'atlas-alert atlas-impersonation-banner'), role: "status", children: [(0, jsx_runtime_1.jsx)("span", { className: cls('text', 'atlas-text'), children: t('impersonation.banner', { name }) }), ' ', (0, jsx_runtime_1.jsx)("button", { type: "button", className: cls('formButtonPrimary', 'atlas-button'), disabled: busy, onClick: async () => {
|
|
42
|
+
setBusy(true);
|
|
43
|
+
try {
|
|
44
|
+
const result = await endImpersonation();
|
|
45
|
+
onEnded?.(result);
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
setBusy(false);
|
|
49
|
+
}
|
|
50
|
+
}, children: canReturnToAdmin ? t('impersonation.returnToAdmin') : t('impersonation.end') })] }));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=impersonation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impersonation.js","sourceRoot":"","sources":["../src/impersonation.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAoBb,4CASC;AAaD,kDAoCC;;AA5ED,iCAAiC;AACjC,sCAAsG;AACtG,mDAA2C;AAC3C,2DAA0D;AAc1D,4EAA4E;AAC5E,SAAgB,gBAAgB;IAC9B,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAA,wBAAQ,GAAE,CAAC;IACzD,MAAM,KAAK,GAAG,IAAA,oBAAe,EAAC,MAAM,CAAC,IAAI,OAAO,EAAE,KAAK,IAAI,IAAI,CAAC;IAChE,OAAO;QACL,eAAe,EAAE,KAAK,KAAK,IAAI;QAC/B,KAAK;QACL,gBAAgB,EAAE,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,OAAO,EAAE,gBAAgB,CAAC;QACtE,gBAAgB;KACjB,CAAC;AACJ,CAAC;AAOD;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,EAAE,OAAO,EAA4B;IACvE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAA,wBAAQ,GAAE,CAAC;IAC5B,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACnF,MAAM,CAAC,GAAG,IAAA,2BAAO,GAAE,CAAC;IACpB,MAAM,GAAG,GAAG,IAAA,8BAAU,GAAE,CAAC;IACzB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IACxC,IAAI,CAAC,eAAe;QAAE,OAAO,IAAI,CAAC;IAElC,MAAM,IAAI,GACR,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAC7D,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,aAAa;QAC5D,IAAI,EAAE,EAAE;QACR,EAAE,CAAC;IAEL,OAAO,CACL,iCAAK,SAAS,EAAE,GAAG,CAAC,OAAO,EAAE,wCAAwC,CAAC,EAAE,IAAI,EAAC,QAAQ,aACnF,iCAAM,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,YAAG,CAAC,CAAC,sBAAsB,EAAE,EAAE,IAAI,EAAE,CAAC,GAAQ,EAAC,GAAG,EAC5F,mCACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,GAAG,CAAC,mBAAmB,EAAE,cAAc,CAAC,EACnD,QAAQ,EAAE,IAAI,EACd,OAAO,EAAE,KAAK,IAAI,EAAE;oBAClB,OAAO,CAAC,IAAI,CAAC,CAAC;oBACd,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;wBACxC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;oBACpB,CAAC;4BAAS,CAAC;wBACT,OAAO,CAAC,KAAK,CAAC,CAAC;oBACjB,CAAC;gBACH,CAAC,YAEA,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,GACtE,IACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type MfaChoices, type MfaEnrollmentController, type MfaEnrollmentState } from '@atlasauth/js';
|
|
3
|
+
/**
|
|
4
|
+
* The sign-in's MFA steps for `<SignIn>`: setting up a second factor when the
|
|
5
|
+
* app requires one (`needs_mfa_enrollment`) and the texted / emailed code at the
|
|
6
|
+
* second-factor step. The requests and the step's state live in
|
|
7
|
+
* `@atlasauth/js` (`createMfaEnrollment`), shared with every framework SDK.
|
|
8
|
+
*/
|
|
9
|
+
/** What the instance lets the MFA steps offer (`account.mfa`, `account.emailSecondFactor`). */
|
|
10
|
+
export declare function useMfaChoices(): MfaChoices;
|
|
11
|
+
/**
|
|
12
|
+
* The enrolment step's controller and state, started for `attemptId` while
|
|
13
|
+
* `active` (the flow is at `needs_mfa_enrollment`) and reset when it leaves.
|
|
14
|
+
*/
|
|
15
|
+
export declare function useMfaEnrollment(attemptId: string | null, active: boolean): {
|
|
16
|
+
controller: MfaEnrollmentController;
|
|
17
|
+
state: MfaEnrollmentState;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The enrolment step's body: the method choice, the authenticator's QR code and
|
|
21
|
+
* setup key with its code field(s), or the phone number then the texted code.
|
|
22
|
+
* `field` draws an input the way the rest of the form does.
|
|
23
|
+
*/
|
|
24
|
+
export declare function MfaEnrollmentFields({ controller, state, busy, field, clearValues, }: {
|
|
25
|
+
controller: MfaEnrollmentController;
|
|
26
|
+
state: MfaEnrollmentState;
|
|
27
|
+
busy: boolean;
|
|
28
|
+
field: (name: string, labelKey: string, type?: string, extra?: {
|
|
29
|
+
autoComplete?: string;
|
|
30
|
+
inputMode?: 'numeric' | 'tel';
|
|
31
|
+
}) => ReactNode;
|
|
32
|
+
clearValues: () => void;
|
|
33
|
+
}): import("react").JSX.Element;
|
|
34
|
+
/**
|
|
35
|
+
* "Text me a code instead" / "Email me a code instead" at the second factor:
|
|
36
|
+
* sends the code for this attempt, then says where it went. The code is typed
|
|
37
|
+
* into the step's code field like any second-factor code.
|
|
38
|
+
*/
|
|
39
|
+
export declare function SecondFactorCodeOption({ attemptId, strategy }: {
|
|
40
|
+
attemptId: string;
|
|
41
|
+
strategy: 'sms' | 'email_code';
|
|
42
|
+
}): import("react").JSX.Element;
|
|
43
|
+
/**
|
|
44
|
+
* The recovery codes a mid-sign-in enrolment came with, shown once before the
|
|
45
|
+
* sign-in finishes: copy them, download them as a .txt file, then "I've saved
|
|
46
|
+
* my codes" (`onSaved`) exchanges the ticket. The codes live only in the flow's
|
|
47
|
+
* memory and are forgotten once saved.
|
|
48
|
+
*/
|
|
49
|
+
export declare function RecoveryCodes({ codes, busy, onSaved }: {
|
|
50
|
+
codes: string[];
|
|
51
|
+
busy: boolean;
|
|
52
|
+
onSaved(): void;
|
|
53
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
'use client';
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.useMfaChoices = useMfaChoices;
|
|
5
|
+
exports.useMfaEnrollment = useMfaEnrollment;
|
|
6
|
+
exports.MfaEnrollmentFields = MfaEnrollmentFields;
|
|
7
|
+
exports.SecondFactorCodeOption = SecondFactorCodeOption;
|
|
8
|
+
exports.RecoveryCodes = RecoveryCodes;
|
|
9
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
10
|
+
const react_1 = require("react");
|
|
11
|
+
const js_1 = require("@atlasauth/js");
|
|
12
|
+
const AtlasProvider_1 = require("./AtlasProvider");
|
|
13
|
+
const components_shared_1 = require("./components-shared");
|
|
14
|
+
/**
|
|
15
|
+
* The sign-in's MFA steps for `<SignIn>`: setting up a second factor when the
|
|
16
|
+
* app requires one (`needs_mfa_enrollment`) and the texted / emailed code at the
|
|
17
|
+
* second-factor step. The requests and the step's state live in
|
|
18
|
+
* `@atlasauth/js` (`createMfaEnrollment`), shared with every framework SDK.
|
|
19
|
+
*/
|
|
20
|
+
/** What the instance lets the MFA steps offer (`account.mfa`, `account.emailSecondFactor`). */
|
|
21
|
+
function useMfaChoices() {
|
|
22
|
+
const { instanceSettings } = (0, AtlasProvider_1.useAtlas)();
|
|
23
|
+
return (0, js_1.mfaChoicesFrom)(instanceSettings?.account);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The enrolment step's controller and state, started for `attemptId` while
|
|
27
|
+
* `active` (the flow is at `needs_mfa_enrollment`) and reset when it leaves.
|
|
28
|
+
*/
|
|
29
|
+
function useMfaEnrollment(attemptId, active) {
|
|
30
|
+
const client = (0, components_shared_1.useFapiClient)();
|
|
31
|
+
const choices = useMfaChoices();
|
|
32
|
+
const choicesRef = (0, react_1.useRef)(choices);
|
|
33
|
+
choicesRef.current = choices;
|
|
34
|
+
const controller = (0, react_1.useMemo)(() => (0, js_1.createMfaEnrollment)(client, () => choicesRef.current), [client]);
|
|
35
|
+
const [state, setState] = (0, react_1.useState)(controller.state);
|
|
36
|
+
(0, react_1.useEffect)(() => controller.subscribe(setState), [controller]);
|
|
37
|
+
(0, react_1.useEffect)(() => {
|
|
38
|
+
if (active && attemptId)
|
|
39
|
+
controller.start(attemptId);
|
|
40
|
+
else
|
|
41
|
+
controller.reset();
|
|
42
|
+
}, [controller, active, attemptId]);
|
|
43
|
+
return { controller, state };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The enrolment step's body: the method choice, the authenticator's QR code and
|
|
47
|
+
* setup key with its code field(s), or the phone number then the texted code.
|
|
48
|
+
* `field` draws an input the way the rest of the form does.
|
|
49
|
+
*/
|
|
50
|
+
function MfaEnrollmentFields({ controller, state, busy, field, clearValues, }) {
|
|
51
|
+
const t = (0, components_shared_1.useText)();
|
|
52
|
+
const cls = (0, components_shared_1.useClasses)();
|
|
53
|
+
const errorClass = (0, components_shared_1.useClass)('formFieldError', 'atlas-error');
|
|
54
|
+
const secondaryClass = (0, components_shared_1.useClass)('formButtonSecondary', 'atlas-button-secondary');
|
|
55
|
+
const { method, enrollment, options } = state;
|
|
56
|
+
const out = [];
|
|
57
|
+
if (method === null) {
|
|
58
|
+
out.push((0, jsx_runtime_1.jsx)("p", { className: cls('text', 'atlas-text'), children: t('mfa.enrollChoose') }, "choose"), ...options.map((m) => ((0, jsx_runtime_1.jsx)("button", { type: "button", className: secondaryClass, "data-atlas-mfa-method": m, disabled: busy || state.busy, onClick: () => {
|
|
59
|
+
clearValues();
|
|
60
|
+
void controller.choose(m);
|
|
61
|
+
}, children: t(m === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }, m))));
|
|
62
|
+
}
|
|
63
|
+
else if (method === 'totp') {
|
|
64
|
+
if (!enrollment) {
|
|
65
|
+
out.push((0, jsx_runtime_1.jsx)("p", { className: cls('text', 'atlas-text'), "aria-live": "polite", children: state.busy ? t('mfa.enrollPreparing') : null }, "preparing"));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
out.push((0, jsx_runtime_1.jsx)("p", { className: cls('text', 'atlas-text'), children: t('mfa.enrollScan') }, "scan"));
|
|
69
|
+
if (enrollment.qrCode) {
|
|
70
|
+
out.push((0, jsx_runtime_1.jsx)("img", { className: "atlas-mfa-qr", "data-atlas": "mfa-qr", src: enrollment.qrCode, alt: t('mfa.enrollQrAlt'), width: 180, height: 180 }, "qr"));
|
|
71
|
+
}
|
|
72
|
+
if (enrollment.secret) {
|
|
73
|
+
out.push((0, jsx_runtime_1.jsxs)("p", { className: cls('text', 'atlas-text'), "data-atlas": "mfa-setup-key", children: [t('mfa.enrollSetupKey'), ": ", (0, jsx_runtime_1.jsx)("code", { children: (0, js_1.groupSetupKey)(enrollment.secret) })] }, "secret"));
|
|
74
|
+
}
|
|
75
|
+
out.push(field('code', 'mfa.enrollFirstCodeLabel', 'text', { autoComplete: 'one-time-code', inputMode: 'numeric' }));
|
|
76
|
+
if (state.totpCodes >= 2) {
|
|
77
|
+
out.push(field('secondCode', 'mfa.enrollSecondCodeLabel', 'text', { autoComplete: 'one-time-code', inputMode: 'numeric' }));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (!enrollment) {
|
|
82
|
+
out.push(field('phone', 'mfa.phoneLabel', 'tel', { autoComplete: 'tel', inputMode: 'tel' }), (0, jsx_runtime_1.jsx)("p", { className: cls('text', 'atlas-text'), children: t('mfa.phoneHint') }, "phone-hint"));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
out.push((0, jsx_runtime_1.jsx)("p", { className: cls('text', 'atlas-text'), "data-atlas": "mfa-code-texted", "aria-live": "polite", children: t('mfa.codeTextedTo', { phone: enrollment.phone ?? '' }) }, "texted"), field('code', 'mfa.codeLabel', 'text', { autoComplete: 'one-time-code', inputMode: 'numeric' }), (0, jsx_runtime_1.jsx)("button", { type: "button", className: cls('link', 'atlas-link'), "data-atlas-resend": "", disabled: busy || state.busy, onClick: () => void controller.resend(), children: t('signIn.resendCode') }, "resend"));
|
|
86
|
+
}
|
|
87
|
+
for (const error of state.errors) {
|
|
88
|
+
out.push((0, jsx_runtime_1.jsx)("p", { className: errorClass, role: "alert", children: error.message }, `enrol-error-${error.code}-${error.param ?? ''}`));
|
|
89
|
+
}
|
|
90
|
+
if (method !== null && options.length > 1) {
|
|
91
|
+
const other = options.find((m) => m !== method);
|
|
92
|
+
out.push((0, jsx_runtime_1.jsx)("button", { type: "button", className: cls('link', 'atlas-link'), "data-atlas-mfa-method": other, disabled: busy || state.busy, onClick: () => {
|
|
93
|
+
clearValues();
|
|
94
|
+
void controller.choose(other);
|
|
95
|
+
}, children: t(other === 'totp' ? 'mfa.enrollTotpOption' : 'mfa.enrollSmsOption') }, "switch"));
|
|
96
|
+
}
|
|
97
|
+
return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: out });
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* "Text me a code instead" / "Email me a code instead" at the second factor:
|
|
101
|
+
* sends the code for this attempt, then says where it went. The code is typed
|
|
102
|
+
* into the step's code field like any second-factor code.
|
|
103
|
+
*/
|
|
104
|
+
function SecondFactorCodeOption({ attemptId, strategy }) {
|
|
105
|
+
const client = (0, components_shared_1.useFapiClient)();
|
|
106
|
+
const t = (0, components_shared_1.useText)();
|
|
107
|
+
const cls = (0, components_shared_1.useClasses)();
|
|
108
|
+
const [state, setState] = (0, react_1.useState)({});
|
|
109
|
+
const name = strategy === 'sms' ? 'sms-second-factor' : 'email-second-factor';
|
|
110
|
+
const send = () => {
|
|
111
|
+
setState({ busy: true });
|
|
112
|
+
(0, js_1.prepareSecondFactorCode)(client, attemptId, strategy)
|
|
113
|
+
.then(({ sentTo }) => setState({ sentTo }))
|
|
114
|
+
.catch((e) => setState({ error: e instanceof Error ? e.message : String(e) }));
|
|
115
|
+
};
|
|
116
|
+
if (state.sentTo !== undefined) {
|
|
117
|
+
return ((0, jsx_runtime_1.jsx)("p", { className: cls('text', 'atlas-text'), "data-atlas": `${name}-sent`, "aria-live": "polite", children: strategy === 'sms' ? t('mfa.codeTextedTo', { phone: state.sentTo }) : t('signIn.codeSentTo', { email: state.sentTo }) }));
|
|
118
|
+
}
|
|
119
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { type: "button", className: cls('link', 'atlas-link'), "data-atlas": name, disabled: state.busy, onClick: send, children: state.busy ? t('signIn.sending') : t(strategy === 'sms' ? 'mfa.smsCodeOption' : 'signIn.emailCodeOption') }), state.error ? ((0, jsx_runtime_1.jsx)("div", { className: cls('alert', 'atlas-alert'), role: "alert", children: state.error })) : null] }));
|
|
120
|
+
}
|
|
121
|
+
const RECOVERY_LIST_STYLE = {
|
|
122
|
+
listStyle: 'none',
|
|
123
|
+
padding: 0,
|
|
124
|
+
margin: '8px 0 12px',
|
|
125
|
+
display: 'grid',
|
|
126
|
+
gridTemplateColumns: 'repeat(2, minmax(0, 1fr))',
|
|
127
|
+
gap: 6,
|
|
128
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, monospace',
|
|
129
|
+
textAlign: 'center',
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* The recovery codes a mid-sign-in enrolment came with, shown once before the
|
|
133
|
+
* sign-in finishes: copy them, download them as a .txt file, then "I've saved
|
|
134
|
+
* my codes" (`onSaved`) exchanges the ticket. The codes live only in the flow's
|
|
135
|
+
* memory and are forgotten once saved.
|
|
136
|
+
*/
|
|
137
|
+
function RecoveryCodes({ codes, busy, onSaved }) {
|
|
138
|
+
const t = (0, components_shared_1.useText)();
|
|
139
|
+
const cls = (0, components_shared_1.useClasses)();
|
|
140
|
+
const cardClass = (0, components_shared_1.useClass)('card', 'atlas-card');
|
|
141
|
+
const titleClass = (0, components_shared_1.useClass)('headerTitle', 'atlas-title');
|
|
142
|
+
const buttonClass = (0, components_shared_1.useClass)('formButtonPrimary', 'atlas-button');
|
|
143
|
+
const secondaryClass = (0, components_shared_1.useClass)('formButtonSecondary', 'atlas-button-secondary');
|
|
144
|
+
const [copied, setCopied] = (0, react_1.useState)(false);
|
|
145
|
+
const canCopy = typeof navigator !== 'undefined' && !!navigator.clipboard?.writeText;
|
|
146
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: cardClass, "data-atlas": "recovery-codes", children: [(0, jsx_runtime_1.jsx)("h1", { className: titleClass, children: t('mfa.recoveryCodesTitle') }), (0, jsx_runtime_1.jsx)("p", { className: cls('text', 'atlas-text'), children: t('mfa.recoveryCodesHelp') }), (0, jsx_runtime_1.jsx)("ul", { "data-atlas": "recovery-codes-list", style: RECOVERY_LIST_STYLE, children: codes.map((code) => ((0, jsx_runtime_1.jsx)("li", { children: (0, jsx_runtime_1.jsx)("code", { children: code }) }, code))) }), (0, jsx_runtime_1.jsxs)("div", { className: "atlas-alternatives", children: [canCopy ? ((0, jsx_runtime_1.jsx)("button", { type: "button", className: secondaryClass, "data-atlas": "recovery-codes-copy", onClick: () => void (0, js_1.copyRecoveryCodes)(codes).then(setCopied), children: t('mfa.recoveryCodesCopy') })) : null, (0, js_1.canDownloadRecoveryCodes)() ? ((0, jsx_runtime_1.jsx)("button", { type: "button", className: secondaryClass, "data-atlas": "recovery-codes-download", onClick: () => (0, js_1.downloadRecoveryCodes)(codes), children: t('mfa.recoveryCodesDownload') })) : null] }), copied ? ((0, jsx_runtime_1.jsx)("p", { className: cls('text', 'atlas-text'), "aria-live": "polite", "data-atlas": "recovery-codes-copied", children: t('mfa.recoveryCodesCopied') })) : null, (0, jsx_runtime_1.jsx)("button", { type: "button", className: buttonClass, "data-atlas": "recovery-codes-saved", disabled: busy, onClick: onSaved, children: t('mfa.recoveryCodesSaved') })] }));
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=mfa-steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfa-steps.js","sourceRoot":"","sources":["../src/mfa-steps.tsx"],"names":[],"mappings":"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"}
|
package/dist/organization.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { OrganizationProfileController, type OrganizationProfileState } from '@atlasauth/js';
|
|
1
2
|
import { useOrganization } from './hooks';
|
|
3
|
+
import { useReverification } from './reverification';
|
|
2
4
|
export declare function OrganizationSwitcher(): import("react").JSX.Element;
|
|
3
5
|
/**
|
|
4
6
|
* Clerk-parity `useOrganizationList()`. The memberships the signed-in user
|
|
@@ -34,4 +36,83 @@ export declare function CreateOrganization({ onCreate, }?: {
|
|
|
34
36
|
* can make one without leaving the list.
|
|
35
37
|
*/
|
|
36
38
|
export declare function OrganizationList(): import("react").JSX.Element;
|
|
37
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Headless state for the active organization's profile: members, pending
|
|
41
|
+
* invitations and roles, with the admin actions (change role, remove, invite,
|
|
42
|
+
* revoke, resend) and the member actions (leave; delete for an admin, which
|
|
43
|
+
* parks for a password re-authentication on a stale session). The same
|
|
44
|
+
* `OrganizationProfileController` backs every SDK's `<OrganizationProfile>`.
|
|
45
|
+
*/
|
|
46
|
+
export declare function useOrganizationProfile(): {
|
|
47
|
+
organizationId: string | null;
|
|
48
|
+
state: OrganizationProfileState;
|
|
49
|
+
canManage: boolean;
|
|
50
|
+
isAdmin: boolean;
|
|
51
|
+
controller: OrganizationProfileController | null;
|
|
52
|
+
deleteOrganization(): Promise<boolean>;
|
|
53
|
+
reverification: ReturnType<typeof useReverification>;
|
|
54
|
+
};
|
|
55
|
+
export interface OrganizationProfileProps {
|
|
56
|
+
/** Called after the user leaves or deletes the organization (e.g. to navigate away). */
|
|
57
|
+
onExit?(reason: 'left' | 'deleted'): void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Clerk-parity `<OrganizationProfile>`: the active organization's members
|
|
61
|
+
* (admins change roles and remove), invitations (admins invite, revoke and
|
|
62
|
+
* resend) and settings (leave; an admin deletes, after re-authenticating).
|
|
63
|
+
* Every control is gated on the ACTIVE org role, matching the server's rule.
|
|
64
|
+
*/
|
|
65
|
+
export declare function OrganizationProfile({ onExit }?: OrganizationProfileProps): import("react").JSX.Element | null;
|
|
66
|
+
/** One entry of an organization's audit trail, as the Frontend API returns it. */
|
|
67
|
+
export interface OrganizationAuditLogEntry {
|
|
68
|
+
object: 'audit_log';
|
|
69
|
+
id: string;
|
|
70
|
+
action: string;
|
|
71
|
+
actor: {
|
|
72
|
+
type: string;
|
|
73
|
+
id: string | null;
|
|
74
|
+
};
|
|
75
|
+
target: {
|
|
76
|
+
type: string | null;
|
|
77
|
+
id: string | null;
|
|
78
|
+
};
|
|
79
|
+
organization_id: string;
|
|
80
|
+
ip: string | null;
|
|
81
|
+
user_agent: string | null;
|
|
82
|
+
metadata: Record<string, unknown>;
|
|
83
|
+
created_at: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The active organization's audit trail, for org admins: one page at a time,
|
|
87
|
+
* newest first, with a "load more" cursor. `action` narrows it (exact, or a
|
|
88
|
+
* prefix ending in `.`). Returns `forbidden: true` when the signed-in member is
|
|
89
|
+
* not allowed to read it, so the caller can hide the surface.
|
|
90
|
+
*/
|
|
91
|
+
export declare function useOrganizationAuditLog(options?: {
|
|
92
|
+
pageSize?: number;
|
|
93
|
+
action?: string;
|
|
94
|
+
}): {
|
|
95
|
+
entries: OrganizationAuditLogEntry[];
|
|
96
|
+
loading: boolean;
|
|
97
|
+
forbidden: boolean;
|
|
98
|
+
hasMore: boolean;
|
|
99
|
+
loadMore(): Promise<void>;
|
|
100
|
+
reload(): Promise<void>;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* `<OrganizationAuditLog/>` — the active organization's audit trail for its
|
|
104
|
+
* admins, next to `<OrganizationProfile/>`. Renders nothing for a member who may
|
|
105
|
+
* not read it (the server is the authority; the component just follows it).
|
|
106
|
+
* Labels are props so an app can localise them.
|
|
107
|
+
*/
|
|
108
|
+
export declare function OrganizationAuditLog({ pageSize, action, labels, formatDate, }?: {
|
|
109
|
+
pageSize?: number;
|
|
110
|
+
action?: string;
|
|
111
|
+
labels?: {
|
|
112
|
+
title?: string;
|
|
113
|
+
empty?: string;
|
|
114
|
+
loadMore?: string;
|
|
115
|
+
actor?: string;
|
|
116
|
+
};
|
|
117
|
+
formatDate?(ms: number): string;
|
|
118
|
+
}): import("react").JSX.Element | null;
|