@arbidocs/blocks 0.5.22 → 0.5.23
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/auth/index.cjs +47 -47
- package/dist/auth/index.js +2 -2
- package/dist/{chunk-K237IYOD.cjs → chunk-BYJUI4AT.cjs} +54 -2
- package/dist/chunk-BYJUI4AT.cjs.map +1 -0
- package/dist/{chunk-MSPNYW6Z.cjs → chunk-DTLVC6MN.cjs} +2 -53
- package/dist/chunk-DTLVC6MN.cjs.map +1 -0
- package/dist/{chunk-KL6XOSEN.js → chunk-PLAGIVFF.js} +4 -52
- package/dist/chunk-PLAGIVFF.js.map +1 -0
- package/dist/{chunk-IXBJEQH5.js → chunk-VN4FSGBR.js} +53 -4
- package/dist/chunk-VN4FSGBR.js.map +1 -0
- package/dist/connect/index.cjs +164 -59
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/index.js +122 -18
- package/dist/connect/index.js.map +1 -1
- package/dist/connection/auth/support.d.ts +17 -0
- package/dist/connection/auth/useLoginActions.d.ts +5 -0
- package/dist/connection/billing/ConnectedQuotaDialog.d.ts +5 -13
- package/dist/connection/billing/index.d.ts +1 -1
- package/dist/connection/connectors/ConnectedSharePointAdminConsentPage.d.ts +26 -0
- package/dist/connection/connectors/index.d.ts +1 -0
- package/dist/connection/settings-page/ConnectedAccountSettings.d.ts +2 -1
- package/dist/connection/settings-page/ConnectedBoxPortalSection.d.ts +6 -0
- package/dist/index.cjs +47 -47
- package/dist/index.js +2 -2
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/dist/chunk-IXBJEQH5.js.map +0 -1
- package/dist/chunk-K237IYOD.cjs.map +0 -1
- package/dist/chunk-KL6XOSEN.js.map +0 -1
- package/dist/chunk-MSPNYW6Z.cjs.map +0 -1
|
@@ -35,6 +35,23 @@ export interface AuthPagesSupport {
|
|
|
35
35
|
passwordRules?: PasswordRules;
|
|
36
36
|
/** Only SSO: the page hands straight over to the provider. */
|
|
37
37
|
ssoOnly?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Visitors can create an account here. Default: on. Off (a staff-only site whose accounts are
|
|
40
|
+
* made for people): the page signs in only, with no Register tab.
|
|
41
|
+
*/
|
|
42
|
+
allowRegistration?: boolean;
|
|
43
|
+
/** The sign-in heading and the line under it. Default: "Welcome back". */
|
|
44
|
+
heading?: {
|
|
45
|
+
title: string;
|
|
46
|
+
description?: ReactNode;
|
|
47
|
+
};
|
|
48
|
+
/** The email field's label on sign-in. Default: "Email". */
|
|
49
|
+
emailLabel?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Sign in from `#email=…&password=…[&next=…]` (mock and demo deployments only; see
|
|
52
|
+
* `useFragmentCredentials`). A `next` path goes to `onReturnPath`. Default: off.
|
|
53
|
+
*/
|
|
54
|
+
fragmentSignIn?: boolean;
|
|
38
55
|
/** The visitor started to sign in: warm what the signed-in app needs. */
|
|
39
56
|
onIntent?: () => void;
|
|
40
57
|
/** An invitation link carries where to go once signed in. */
|
|
@@ -14,6 +14,11 @@ export declare function useLoginActions({ formState, formActions, }: {
|
|
|
14
14
|
handleSsoLogin: (connection?: string) => void;
|
|
15
15
|
handleLocalLogin: (opts?: {
|
|
16
16
|
isFreshRegistration?: boolean;
|
|
17
|
+
/** Sign in with these, not the form's (a sign-in link's). */
|
|
18
|
+
credentials?: {
|
|
19
|
+
email: string;
|
|
20
|
+
password: string;
|
|
21
|
+
};
|
|
17
22
|
}) => Promise<void>;
|
|
18
23
|
handleRegister: (saveRecoveryKey?: boolean) => Promise<void>;
|
|
19
24
|
handleRequestVerificationCode: () => Promise<void>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The dialog shown when a project's AI usage for the month is used up (a 402 `QUOTA_EXCEEDED`: an
|
|
3
3
|
* API call, a chat send, a document's processing). The host decides when (`info`), and what a Box
|
|
4
|
-
* deployment's admin opens (`
|
|
4
|
+
* deployment's admin opens the portal (`runtimeConfig.licenceUrl`); billing opens through
|
|
5
|
+
* `environment.openProject`.
|
|
5
6
|
*
|
|
6
7
|
* One sentence and the actions that get the user going again, by project (the add-on state is only
|
|
7
8
|
* visible to the owner of a Pro project). The usage cap limits automatic top-ups only, so adding AI
|
|
@@ -11,8 +12,8 @@
|
|
|
11
12
|
* - Pro, cap reached → "Usage cap reached: no more automatic top-ups this month." / Add and "Raise cap".
|
|
12
13
|
* - Pro otherwise (the automatic top-up failed) → the billing error / Add.
|
|
13
14
|
* - Free (or not the owner) → "Upgrade", which opens the plan picker of the project.
|
|
14
|
-
* - Box deployment
|
|
15
|
-
* "Open the ARBI portal"
|
|
15
|
+
* - Box deployment → members: "Ask your Box admin to add more." (no purchase); Box admins:
|
|
16
|
+
* "Open the ARBI portal", where the Box is administered. No Box billing here.
|
|
16
17
|
*/
|
|
17
18
|
/** What used up: the project's spend against its budget (£), and the server's message. */
|
|
18
19
|
export interface QuotaExceededInfo {
|
|
@@ -21,18 +22,9 @@ export interface QuotaExceededInfo {
|
|
|
21
22
|
projectExtId: string | null;
|
|
22
23
|
message?: string;
|
|
23
24
|
}
|
|
24
|
-
/** A Box deployment: its AI usage is the firm's, administered in the ARBI portal. */
|
|
25
|
-
export interface QuotaDialogBox {
|
|
26
|
-
/** The viewer administers the Box (else they ask their admin). */
|
|
27
|
-
isAdmin: boolean;
|
|
28
|
-
/** The Box's licence page in the portal. */
|
|
29
|
-
portalUrl: string;
|
|
30
|
-
}
|
|
31
25
|
export interface ConnectedQuotaDialogProps {
|
|
32
26
|
/** Open with what was used up; `null`: closed. */
|
|
33
27
|
info: QuotaExceededInfo | null;
|
|
34
28
|
onClose: () => void;
|
|
35
|
-
/** On a Box deployment. Absent: a project's own billing. */
|
|
36
|
-
box?: QuotaDialogBox;
|
|
37
29
|
}
|
|
38
|
-
export declare function ConnectedQuotaDialog({ info, onClose: close
|
|
30
|
+
export declare function ConnectedQuotaDialog({ info, onClose: close }: ConnectedQuotaDialogProps): import("react").JSX.Element;
|
|
@@ -20,6 +20,6 @@ export { REFERRAL_OFFER, useReferralReward } from './referral-reward';
|
|
|
20
20
|
export { isProProject, planBadgeView, planName } from './plan-badge';
|
|
21
21
|
export { aiUsageResetTimestamp, formatResetDate, getQuotaItems } from './quota-items';
|
|
22
22
|
export { CAP_REACHED_MESSAGE, ZERO_BUDGET_MESSAGE, isAddonBudgetZero } from './addon-pricing';
|
|
23
|
-
export { ConnectedQuotaDialog, type ConnectedQuotaDialogProps, type
|
|
23
|
+
export { ConnectedQuotaDialog, type ConnectedQuotaDialogProps, type QuotaExceededInfo, } from './ConnectedQuotaDialog';
|
|
24
24
|
export { ConnectedWelcomeDialog, type ConnectedWelcomeDialogProps } from './ConnectedWelcomeDialog';
|
|
25
25
|
export { ProjectUsageContent, type ProjectUsageContentProps, type UsageBreakdownKey, } from './ProjectUsageContent';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SharePoint org admin-consent page — PUBLIC (no sign-in). Requests go to the environment's API
|
|
3
|
+
* base URL (`runtimeConfig.apiBaseUrl`).
|
|
4
|
+
*
|
|
5
|
+
* The enterprise story: a user wants SharePoint sync, but their Microsoft
|
|
6
|
+
* tenant requires an IT admin to approve the app's Sites.Read.All scope. The
|
|
7
|
+
* admin almost never has (or wants) an ARBI account, so this page gives them a
|
|
8
|
+
* standalone place to grant the org-wide consent:
|
|
9
|
+
*
|
|
10
|
+
* 1. A user copies this page's link from the SharePoint connector row and
|
|
11
|
+
* sends it to their admin.
|
|
12
|
+
* 2. The admin opens it, reviews what will be granted, and clicks Approve —
|
|
13
|
+
* which redirects to Microsoft's admin-consent screen
|
|
14
|
+
* (GET /v1/connectors/microsoft_sharepoint/admin-consent, public endpoint).
|
|
15
|
+
* 3. Microsoft sends them back here with ?result=granted|declined and this
|
|
16
|
+
* page shows the outcome.
|
|
17
|
+
*
|
|
18
|
+
* After the grant, users in that tenant connect SharePoint themselves — this
|
|
19
|
+
* page only unlocks the org-level permission wall; it grants no data access by
|
|
20
|
+
* itself (per-user OAuth + sealed tokens still gate every mailbox/site).
|
|
21
|
+
*/
|
|
22
|
+
export interface ConnectedSharePointAdminConsentPageProps {
|
|
23
|
+
/** The outcome Microsoft sends back (`?result=granted|declined`). Default: the page's query. */
|
|
24
|
+
result?: string | null;
|
|
25
|
+
}
|
|
26
|
+
export declare function ConnectedSharePointAdminConsentPage({ result: givenResult, }?: ConnectedSharePointAdminConsentPageProps): import("react").JSX.Element;
|
|
@@ -2,3 +2,4 @@ export { ConnectedAppsSettings, type ConnectedAppsSettingsProps } from './Connec
|
|
|
2
2
|
export { ConnectedMailboxSyncDialog, type ConnectedMailboxSyncDialogProps, } from './ConnectedMailboxSyncDialog';
|
|
3
3
|
export { ConnectedDriveSyncDialog, type ConnectedDriveSyncDialogProps, } from './ConnectedDriveSyncDialog';
|
|
4
4
|
export { BACKFILL_OPTIONS, windowLabel } from './sync-labels';
|
|
5
|
+
export { ConnectedSharePointAdminConsentPage, type ConnectedSharePointAdminConsentPageProps, } from './ConnectedSharePointAdminConsentPage';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The Account section of a settings page, bound to the signed-in account: profile and ID check,
|
|
3
|
-
* security, the session card (server connection, active sessions, sign
|
|
3
|
+
* a Box admin's portal link, security, the session card (server connection, active sessions, sign
|
|
4
|
+
* out) and the danger zone.
|
|
4
5
|
* What only the host knows is a prop: the recovery-key download, its admin links, its socket and
|
|
5
6
|
* its billing page.
|
|
6
7
|
*/
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Account settings, Box admins only: one row linking to the Box's page in the ARBI portal
|
|
3
|
+
* (`runtimeConfig.licenceUrl`), where the Box is administered (users, storage, AI usage, budget,
|
|
4
|
+
* billing). Nothing for anyone else, or where the host gives no portal.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ConnectedBoxPortalSection(): import("react").JSX.Element | null;
|
package/dist/index.cjs
CHANGED
|
@@ -42,8 +42,8 @@ require('./chunk-AHDJXIUB.cjs');
|
|
|
42
42
|
var chunk2EI7NCUA_cjs = require('./chunk-2EI7NCUA.cjs');
|
|
43
43
|
var chunkQW3SVHGM_cjs = require('./chunk-QW3SVHGM.cjs');
|
|
44
44
|
require('./chunk-LKK52DEY.cjs');
|
|
45
|
-
var
|
|
46
|
-
var
|
|
45
|
+
var chunkDTLVC6MN_cjs = require('./chunk-DTLVC6MN.cjs');
|
|
46
|
+
var chunkBYJUI4AT_cjs = require('./chunk-BYJUI4AT.cjs');
|
|
47
47
|
var chunkCG757WKY_cjs = require('./chunk-CG757WKY.cjs');
|
|
48
48
|
require('./chunk-VZOOGA47.cjs');
|
|
49
49
|
var chunkMOIZ2R5X_cjs = require('./chunk-MOIZ2R5X.cjs');
|
|
@@ -3086,147 +3086,147 @@ Object.defineProperty(exports, "ActionLink", {
|
|
|
3086
3086
|
});
|
|
3087
3087
|
Object.defineProperty(exports, "DEFAULT_SSO_LOGIN_BUTTON_LABELS", {
|
|
3088
3088
|
enumerable: true,
|
|
3089
|
-
get: function () { return
|
|
3089
|
+
get: function () { return chunkDTLVC6MN_cjs.DEFAULT_SSO_LOGIN_BUTTON_LABELS; }
|
|
3090
3090
|
});
|
|
3091
3091
|
Object.defineProperty(exports, "SsoLoginButton", {
|
|
3092
3092
|
enumerable: true,
|
|
3093
|
-
get: function () { return
|
|
3094
|
-
});
|
|
3095
|
-
Object.defineProperty(exports, "consumeFragmentCredentials", {
|
|
3096
|
-
enumerable: true,
|
|
3097
|
-
get: function () { return chunkMSPNYW6Z_cjs.consumeFragmentCredentials; }
|
|
3093
|
+
get: function () { return chunkDTLVC6MN_cjs.SsoLoginButton; }
|
|
3098
3094
|
});
|
|
3099
3095
|
Object.defineProperty(exports, "isAuthRoutePath", {
|
|
3100
3096
|
enumerable: true,
|
|
3101
|
-
get: function () { return
|
|
3097
|
+
get: function () { return chunkDTLVC6MN_cjs.isAuthRoutePath; }
|
|
3102
3098
|
});
|
|
3103
3099
|
Object.defineProperty(exports, "normalizeAuthPath", {
|
|
3104
3100
|
enumerable: true,
|
|
3105
|
-
get: function () { return
|
|
3106
|
-
});
|
|
3107
|
-
Object.defineProperty(exports, "parseFragmentCredentials", {
|
|
3108
|
-
enumerable: true,
|
|
3109
|
-
get: function () { return chunkMSPNYW6Z_cjs.parseFragmentCredentials; }
|
|
3101
|
+
get: function () { return chunkDTLVC6MN_cjs.normalizeAuthPath; }
|
|
3110
3102
|
});
|
|
3111
3103
|
Object.defineProperty(exports, "preserveAuthReturnUrl", {
|
|
3112
3104
|
enumerable: true,
|
|
3113
|
-
get: function () { return
|
|
3114
|
-
});
|
|
3115
|
-
Object.defineProperty(exports, "useFragmentCredentials", {
|
|
3116
|
-
enumerable: true,
|
|
3117
|
-
get: function () { return chunkMSPNYW6Z_cjs.useFragmentCredentials; }
|
|
3105
|
+
get: function () { return chunkDTLVC6MN_cjs.preserveAuthReturnUrl; }
|
|
3118
3106
|
});
|
|
3119
3107
|
Object.defineProperty(exports, "AccountRecoveryDialog", {
|
|
3120
3108
|
enumerable: true,
|
|
3121
|
-
get: function () { return
|
|
3109
|
+
get: function () { return chunkBYJUI4AT_cjs.AccountRecoveryDialog; }
|
|
3122
3110
|
});
|
|
3123
3111
|
Object.defineProperty(exports, "AuthAlert", {
|
|
3124
3112
|
enumerable: true,
|
|
3125
|
-
get: function () { return
|
|
3113
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthAlert; }
|
|
3126
3114
|
});
|
|
3127
3115
|
Object.defineProperty(exports, "AuthConsent", {
|
|
3128
3116
|
enumerable: true,
|
|
3129
|
-
get: function () { return
|
|
3117
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthConsent; }
|
|
3130
3118
|
});
|
|
3131
3119
|
Object.defineProperty(exports, "AuthDivider", {
|
|
3132
3120
|
enumerable: true,
|
|
3133
|
-
get: function () { return
|
|
3121
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthDivider; }
|
|
3134
3122
|
});
|
|
3135
3123
|
Object.defineProperty(exports, "AuthField", {
|
|
3136
3124
|
enumerable: true,
|
|
3137
|
-
get: function () { return
|
|
3125
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthField; }
|
|
3138
3126
|
});
|
|
3139
3127
|
Object.defineProperty(exports, "AuthFieldBadge", {
|
|
3140
3128
|
enumerable: true,
|
|
3141
|
-
get: function () { return
|
|
3129
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthFieldBadge; }
|
|
3142
3130
|
});
|
|
3143
3131
|
Object.defineProperty(exports, "AuthFooterLinks", {
|
|
3144
3132
|
enumerable: true,
|
|
3145
|
-
get: function () { return
|
|
3133
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthFooterLinks; }
|
|
3146
3134
|
});
|
|
3147
3135
|
Object.defineProperty(exports, "AuthHeading", {
|
|
3148
3136
|
enumerable: true,
|
|
3149
|
-
get: function () { return
|
|
3137
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthHeading; }
|
|
3150
3138
|
});
|
|
3151
3139
|
Object.defineProperty(exports, "AuthHero", {
|
|
3152
3140
|
enumerable: true,
|
|
3153
|
-
get: function () { return
|
|
3141
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthHero; }
|
|
3154
3142
|
});
|
|
3155
3143
|
Object.defineProperty(exports, "AuthInput", {
|
|
3156
3144
|
enumerable: true,
|
|
3157
|
-
get: function () { return
|
|
3145
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthInput; }
|
|
3158
3146
|
});
|
|
3159
3147
|
Object.defineProperty(exports, "AuthLayout", {
|
|
3160
3148
|
enumerable: true,
|
|
3161
|
-
get: function () { return
|
|
3149
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthLayout; }
|
|
3162
3150
|
});
|
|
3163
3151
|
Object.defineProperty(exports, "AuthLink", {
|
|
3164
3152
|
enumerable: true,
|
|
3165
|
-
get: function () { return
|
|
3153
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthLink; }
|
|
3166
3154
|
});
|
|
3167
3155
|
Object.defineProperty(exports, "AuthNote", {
|
|
3168
3156
|
enumerable: true,
|
|
3169
|
-
get: function () { return
|
|
3157
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthNote; }
|
|
3170
3158
|
});
|
|
3171
3159
|
Object.defineProperty(exports, "AuthOfflineBadge", {
|
|
3172
3160
|
enumerable: true,
|
|
3173
|
-
get: function () { return
|
|
3161
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthOfflineBadge; }
|
|
3174
3162
|
});
|
|
3175
3163
|
Object.defineProperty(exports, "AuthSubmitButton", {
|
|
3176
3164
|
enumerable: true,
|
|
3177
|
-
get: function () { return
|
|
3165
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthSubmitButton; }
|
|
3178
3166
|
});
|
|
3179
3167
|
Object.defineProperty(exports, "AuthTabs", {
|
|
3180
3168
|
enumerable: true,
|
|
3181
|
-
get: function () { return
|
|
3169
|
+
get: function () { return chunkBYJUI4AT_cjs.AuthTabs; }
|
|
3182
3170
|
});
|
|
3183
3171
|
Object.defineProperty(exports, "DEFAULT_ACCOUNT_RECOVERY_DIALOG_LABELS", {
|
|
3184
3172
|
enumerable: true,
|
|
3185
|
-
get: function () { return
|
|
3173
|
+
get: function () { return chunkBYJUI4AT_cjs.DEFAULT_ACCOUNT_RECOVERY_DIALOG_LABELS; }
|
|
3186
3174
|
});
|
|
3187
3175
|
Object.defineProperty(exports, "DEFAULT_AUTH_CONSENT_LABELS", {
|
|
3188
3176
|
enumerable: true,
|
|
3189
|
-
get: function () { return
|
|
3177
|
+
get: function () { return chunkBYJUI4AT_cjs.DEFAULT_AUTH_CONSENT_LABELS; }
|
|
3190
3178
|
});
|
|
3191
3179
|
Object.defineProperty(exports, "DEFAULT_AUTH_FOOTER_LINKS_LABELS", {
|
|
3192
3180
|
enumerable: true,
|
|
3193
|
-
get: function () { return
|
|
3181
|
+
get: function () { return chunkBYJUI4AT_cjs.DEFAULT_AUTH_FOOTER_LINKS_LABELS; }
|
|
3194
3182
|
});
|
|
3195
3183
|
Object.defineProperty(exports, "DEFAULT_AUTH_OFFLINE_BADGE_LABELS", {
|
|
3196
3184
|
enumerable: true,
|
|
3197
|
-
get: function () { return
|
|
3185
|
+
get: function () { return chunkBYJUI4AT_cjs.DEFAULT_AUTH_OFFLINE_BADGE_LABELS; }
|
|
3198
3186
|
});
|
|
3199
3187
|
Object.defineProperty(exports, "DEFAULT_PASSWORD_RULES", {
|
|
3200
3188
|
enumerable: true,
|
|
3201
|
-
get: function () { return
|
|
3189
|
+
get: function () { return chunkBYJUI4AT_cjs.DEFAULT_PASSWORD_RULES; }
|
|
3202
3190
|
});
|
|
3203
3191
|
Object.defineProperty(exports, "DEFAULT_RECOVERY_KEY_DIALOG_LABELS", {
|
|
3204
3192
|
enumerable: true,
|
|
3205
|
-
get: function () { return
|
|
3193
|
+
get: function () { return chunkBYJUI4AT_cjs.DEFAULT_RECOVERY_KEY_DIALOG_LABELS; }
|
|
3206
3194
|
});
|
|
3207
3195
|
Object.defineProperty(exports, "DEFAULT_REVEALABLE_PASSWORD_INPUT_LABELS", {
|
|
3208
3196
|
enumerable: true,
|
|
3209
|
-
get: function () { return
|
|
3197
|
+
get: function () { return chunkBYJUI4AT_cjs.DEFAULT_REVEALABLE_PASSWORD_INPUT_LABELS; }
|
|
3210
3198
|
});
|
|
3211
3199
|
Object.defineProperty(exports, "RecoveryKeyDialog", {
|
|
3212
3200
|
enumerable: true,
|
|
3213
|
-
get: function () { return
|
|
3201
|
+
get: function () { return chunkBYJUI4AT_cjs.RecoveryKeyDialog; }
|
|
3214
3202
|
});
|
|
3215
3203
|
Object.defineProperty(exports, "RevealablePasswordInput", {
|
|
3216
3204
|
enumerable: true,
|
|
3217
|
-
get: function () { return
|
|
3205
|
+
get: function () { return chunkBYJUI4AT_cjs.RevealablePasswordInput; }
|
|
3206
|
+
});
|
|
3207
|
+
Object.defineProperty(exports, "consumeFragmentCredentials", {
|
|
3208
|
+
enumerable: true,
|
|
3209
|
+
get: function () { return chunkBYJUI4AT_cjs.consumeFragmentCredentials; }
|
|
3218
3210
|
});
|
|
3219
3211
|
Object.defineProperty(exports, "createPasswordRules", {
|
|
3220
3212
|
enumerable: true,
|
|
3221
|
-
get: function () { return
|
|
3213
|
+
get: function () { return chunkBYJUI4AT_cjs.createPasswordRules; }
|
|
3222
3214
|
});
|
|
3223
3215
|
Object.defineProperty(exports, "parseAuthError", {
|
|
3224
3216
|
enumerable: true,
|
|
3225
|
-
get: function () { return
|
|
3217
|
+
get: function () { return chunkBYJUI4AT_cjs.parseAuthError; }
|
|
3218
|
+
});
|
|
3219
|
+
Object.defineProperty(exports, "parseFragmentCredentials", {
|
|
3220
|
+
enumerable: true,
|
|
3221
|
+
get: function () { return chunkBYJUI4AT_cjs.parseFragmentCredentials; }
|
|
3226
3222
|
});
|
|
3227
3223
|
Object.defineProperty(exports, "promptSaveCredential", {
|
|
3228
3224
|
enumerable: true,
|
|
3229
|
-
get: function () { return
|
|
3225
|
+
get: function () { return chunkBYJUI4AT_cjs.promptSaveCredential; }
|
|
3226
|
+
});
|
|
3227
|
+
Object.defineProperty(exports, "useFragmentCredentials", {
|
|
3228
|
+
enumerable: true,
|
|
3229
|
+
get: function () { return chunkBYJUI4AT_cjs.useFragmentCredentials; }
|
|
3230
3230
|
});
|
|
3231
3231
|
Object.defineProperty(exports, "DEFAULT_PASSWORD_STRENGTH_INPUT_LABELS", {
|
|
3232
3232
|
enumerable: true,
|
package/dist/index.js
CHANGED
|
@@ -41,8 +41,8 @@ export { DEFAULT_FILTER_FIELDS, DEFAULT_FILTER_INPUT_LABELS, FilterInput } from
|
|
|
41
41
|
import { ActionLink } from './chunk-SUDPZ5IQ.js';
|
|
42
42
|
export { ActionLink } from './chunk-SUDPZ5IQ.js';
|
|
43
43
|
import './chunk-7F5Z4K5W.js';
|
|
44
|
-
export { DEFAULT_SSO_LOGIN_BUTTON_LABELS, SsoLoginButton,
|
|
45
|
-
export { AccountRecoveryDialog, AuthAlert, AuthConsent, AuthDivider, AuthField, AuthFieldBadge, AuthFooterLinks, AuthHeading, AuthHero, AuthInput, AuthLayout, AuthLink, AuthNote, AuthOfflineBadge, AuthSubmitButton, AuthTabs, DEFAULT_ACCOUNT_RECOVERY_DIALOG_LABELS, DEFAULT_AUTH_CONSENT_LABELS, DEFAULT_AUTH_FOOTER_LINKS_LABELS, DEFAULT_AUTH_OFFLINE_BADGE_LABELS, DEFAULT_PASSWORD_RULES, DEFAULT_RECOVERY_KEY_DIALOG_LABELS, DEFAULT_REVEALABLE_PASSWORD_INPUT_LABELS, RecoveryKeyDialog, RevealablePasswordInput, createPasswordRules, parseAuthError, promptSaveCredential } from './chunk-
|
|
44
|
+
export { DEFAULT_SSO_LOGIN_BUTTON_LABELS, SsoLoginButton, isAuthRoutePath, normalizeAuthPath, preserveAuthReturnUrl } from './chunk-PLAGIVFF.js';
|
|
45
|
+
export { AccountRecoveryDialog, AuthAlert, AuthConsent, AuthDivider, AuthField, AuthFieldBadge, AuthFooterLinks, AuthHeading, AuthHero, AuthInput, AuthLayout, AuthLink, AuthNote, AuthOfflineBadge, AuthSubmitButton, AuthTabs, DEFAULT_ACCOUNT_RECOVERY_DIALOG_LABELS, DEFAULT_AUTH_CONSENT_LABELS, DEFAULT_AUTH_FOOTER_LINKS_LABELS, DEFAULT_AUTH_OFFLINE_BADGE_LABELS, DEFAULT_PASSWORD_RULES, DEFAULT_RECOVERY_KEY_DIALOG_LABELS, DEFAULT_REVEALABLE_PASSWORD_INPUT_LABELS, RecoveryKeyDialog, RevealablePasswordInput, consumeFragmentCredentials, createPasswordRules, parseAuthError, parseFragmentCredentials, promptSaveCredential, useFragmentCredentials } from './chunk-VN4FSGBR.js';
|
|
46
46
|
export { DEFAULT_PASSWORD_STRENGTH_INPUT_LABELS, PasswordStrengthInput } from './chunk-P6OLZGQA.js';
|
|
47
47
|
import './chunk-WNDIVNPT.js';
|
|
48
48
|
export { DEFAULT_DM_INVITE_CHIP_LABELS, DmInviteChip, DmThreadHeader } from './chunk-2S3LT5KE.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arbidocs/coedit",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.23",
|
|
4
4
|
"description": "Real-time collaboration for the ARBI native DOCX editor: a Yjs mirror of the canonical OOXML package, session, and server runtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arbidocs/blocks",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.23",
|
|
4
4
|
"description": "Composable, domain-neutral UI blocks for ARBI apps, organised by capability (retrieval, facts, agents, workspaces, citations, collaboration) plus shell, theme and site primitives, on top of @arbidocs/react.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -296,9 +296,9 @@
|
|
|
296
296
|
"example:test:e2e": "playwright test -c examples/custom-ui/playwright.config.ts"
|
|
297
297
|
},
|
|
298
298
|
"dependencies": {
|
|
299
|
-
"@arbidocs/client": "0.5.
|
|
300
|
-
"@arbidocs/coedit": "0.5.
|
|
301
|
-
"@arbidocs/sdk": "0.5.
|
|
299
|
+
"@arbidocs/client": "0.5.23",
|
|
300
|
+
"@arbidocs/coedit": "0.5.23",
|
|
301
|
+
"@arbidocs/sdk": "0.5.23",
|
|
302
302
|
"@auth0/auth0-react": "^2.19.0",
|
|
303
303
|
"@dnd-kit/core": "^6.3.1",
|
|
304
304
|
"@dnd-kit/sortable": "^10.0.0",
|
|
@@ -345,7 +345,7 @@
|
|
|
345
345
|
"y-protocols": "^1.0.6"
|
|
346
346
|
},
|
|
347
347
|
"peerDependencies": {
|
|
348
|
-
"@arbidocs/react": "0.5.
|
|
348
|
+
"@arbidocs/react": "0.5.23",
|
|
349
349
|
"@lexical/html": "0.35.0",
|
|
350
350
|
"@lexical/link": "0.35.0",
|
|
351
351
|
"@lexical/list": "0.35.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/auth/AuthLayout.tsx","../src/auth/AuthForm.tsx","../src/auth/AuthFooter.tsx","../src/auth/auth-error.ts","../src/auth/password-rules.ts","../src/auth/credential-storage.ts","../src/auth/RecoveryDialogs.tsx","../src/connection/auth/auth-hash.ts"],"names":["jsxs","jsx","cn","useMemo","AlertCircle","useId","Button","Input","Fragment","Loader2","useState"],"mappings":"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","file":"chunk-IXBJEQH5.js","sourcesContent":["import type { LucideIcon } from 'lucide-react'\nimport { ArrowRight } from 'lucide-react'\nimport type { ReactNode } from 'react'\nimport { cn } from '@arbidocs/react/ui'\n\nexport interface AuthLayoutProps {\n /** The form column content. */\n children: ReactNode\n /** Sits above the form: the Login / Register tabs, or an offline badge. */\n headerRight?: ReactNode\n /** Hero panel: the right half on desktop, hidden on mobile. Omit for a single centred column. */\n aside?: ReactNode\n /** Brand mark shown top-left of the form column (logo + name). */\n brand?: ReactNode\n /** Pinned bottom-right over the hero on desktop (e.g. a deployment indicator). */\n corner?: ReactNode\n className?: string\n testId?: string\n}\n\n/**\n * Full-bleed split: a calm form column on the left, the hero (`aside`) on the right. On mobile the\n * hero is hidden and the form fills the screen. With no `aside` it is a single centred column.\n */\nexport function AuthLayout({\n children,\n headerRight,\n aside,\n brand,\n corner,\n className,\n testId = 'auth-layout',\n}: AuthLayoutProps) {\n return (\n <div\n data-slot=\"auth-layout\"\n className={cn(\n 'min-h-screen bg-background text-foreground',\n // The hero needs height: a phone held sideways (under 32rem tall) gets the form alone.\n aside && 'md:grid [@media(min-height:32rem)]:md:grid-cols-2',\n className\n )}\n data-testid={testId}\n >\n {corner}\n <section className=\"flex min-h-screen flex-col px-4 py-5 sm:px-8 md:px-12 md:py-6\">\n {brand && (\n <div className=\"flex items-center gap-3 font-semibold text-foreground\">{brand}</div>\n )}\n {/* Top-aligned at a fixed offset (not vertically centred) so switching tabs never moves the tabs. */}\n <div className=\"mx-auto mt-10 flex w-full max-w-sm flex-col gap-5 py-8 md:mt-[14vh]\">\n {headerRight && <div className=\"flex items-center\">{headerRight}</div>}\n {children}\n </div>\n </section>\n {/* Exactly one screen tall and pinned, so the hero is centred in the window rather than in\n the row: a form that overflows the screen (Login, with its SSO buttons, on a laptop)\n would otherwise stretch the row and move the hero text when switching tabs. */}\n {aside && (\n <div className=\"hidden [@media(min-height:32rem)]:md:sticky [@media(min-height:32rem)]:md:top-0 [@media(min-height:32rem)]:md:flex [@media(min-height:32rem)]:md:h-screen\">\n {aside}\n </div>\n )}\n </div>\n )\n}\n\nexport interface AuthHeroPillar {\n icon: LucideIcon\n title: string\n body: string\n}\n\nexport interface AuthHeroProps {\n /** First line of the headline. */\n headline?: ReactNode\n /** Second headline line, set in italic accent. */\n emphasis?: string\n lead?: ReactNode\n pillars?: AuthHeroPillar[]\n link?: { href: string; label: string }\n /** Cover image behind the content (any CSS `url(...)` source). A tint keeps text legible. */\n backgroundImage?: string\n /** Extra content under the pillars (a quote, a logo row, a screenshot). */\n children?: ReactNode\n className?: string\n testId?: string\n}\n\n/** The value-proposition panel for {@link AuthLayout}'s `aside`: headline, lead, pillars, link. */\nexport function AuthHero({\n headline,\n emphasis,\n lead,\n pillars = [],\n link,\n backgroundImage,\n children,\n className,\n testId = 'product-pillars',\n}: AuthHeroProps) {\n return (\n <div\n data-slot=\"auth-hero\"\n className={cn(\n 'relative flex w-full flex-col justify-center gap-6 overflow-hidden bg-hero px-12 py-16 text-white',\n className\n )}\n data-testid={testId}\n >\n {backgroundImage && (\n <>\n <div\n aria-hidden=\"true\"\n data-slot=\"auth-hero-image\"\n className=\"absolute inset-0 bg-cover bg-center\"\n style={{ backgroundImage: `url(${backgroundImage})` }}\n />\n <div aria-hidden=\"true\" className=\"absolute inset-0 bg-hero/70\" />\n </>\n )}\n {headline && (\n <h2 className=\"relative max-w-[18ch] text-3xl font-semibold leading-tight text-white\">\n {headline}\n {emphasis && (\n <>\n <br />\n <span className=\"italic text-theme-cyan-bright\">{emphasis}</span>\n </>\n )}\n </h2>\n )}\n {lead && <p className=\"relative max-w-[44ch] text-base text-white/70\">{lead}</p>}\n\n <ul className=\"relative flex max-w-[46ch] flex-col gap-5\">\n {pillars.map(({ icon: Icon, title, body }) => (\n <li key={title} className=\"flex gap-3\">\n <Icon className=\"mt-0.5 h-5 w-5 shrink-0 text-theme-cyan-bright\" aria-hidden=\"true\" />\n <div>\n <h3 className=\"text-base font-semibold leading-snug text-white\">{title}</h3>\n <p className=\"text-sm leading-relaxed text-white/70\">{body}</p>\n </div>\n </li>\n ))}\n </ul>\n\n {children && <div className=\"relative\">{children}</div>}\n\n {link && (\n <a\n href={link.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"relative inline-flex items-center gap-1 text-sm font-medium text-theme-cyan-bright transition-colors hover:text-white\"\n >\n {link.label}\n <ArrowRight className=\"h-4 w-4\" />\n </a>\n )}\n </div>\n )\n}\n","import { AlertCircle, Eye, EyeOff, Loader2, WifiOff } from 'lucide-react'\nimport {\n createContext,\n useContext,\n useId,\n useMemo,\n useState,\n type ComponentProps,\n type ReactNode,\n} from 'react'\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\nimport { Button, cn, Input } from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\n\n/** Title + one-line description above an auth form. */\nexport function AuthHeading({ title, description }: { title: ReactNode; description?: ReactNode }) {\n return (\n <div data-slot=\"auth-heading\">\n <h1 className=\"text-2xl font-semibold tracking-tight text-foreground\">{title}</h1>\n {description && <p className=\"mt-2 text-sm text-muted-foreground\">{description}</p>}\n </div>\n )\n}\n\n/** A text-style action under or beside a field (\"Forgot your password?\", \"Clear form\"). */\nexport function AuthLink({ className, type = 'button', ...props }: ComponentProps<'button'>) {\n return (\n <button\n type={type}\n data-slot=\"auth-link\"\n className={cn(\n 'text-sm text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11',\n className\n )}\n {...props}\n />\n )\n}\n\ninterface AuthFieldContextValue {\n id: string\n errorId?: string\n}\n\n/** What an `AuthField` hands to the control inside: its id and the id of its error message. */\nconst AuthFieldContext = createContext<AuthFieldContextValue | null>(null)\n\n/** Merge space-separated id lists for `aria-describedby`. */\nfunction joinIds(...ids: Array<string | undefined>): string | undefined {\n const joined = ids.filter(Boolean).join(' ')\n return joined || undefined\n}\n\nexport interface AuthFieldProps {\n /** Id of the control inside, for the label. Omit it to use a generated (`useId`) id that the\n * `AuthInput` / `RevealablePasswordInput` inside picks up automatically. */\n htmlFor?: string\n /** Field-level error: shown under the control, linked with `aria-describedby`, and marks the\n * control `aria-invalid`. */\n error?: ReactNode\n errorTestId?: string\n label: ReactNode\n required?: boolean\n /** Right-aligned action in the label row (e.g. \"Clear form\"). */\n labelAction?: ReactNode\n /** Overlaid at the right edge of the control (e.g. a \"Verified\" badge). */\n trailing?: ReactNode\n className?: string\n children: ReactNode\n}\n\n/** Label (with required marker) above a control. */\nexport function AuthField({\n htmlFor,\n error,\n errorTestId,\n label,\n required,\n labelAction,\n trailing,\n className,\n children,\n}: AuthFieldProps) {\n const generatedId = useId()\n const id = htmlFor ?? generatedId\n const errorId = error ? `${id}-error` : undefined\n const context = useMemo(() => ({ id, errorId }), [id, errorId])\n return (\n <AuthFieldContext.Provider value={context}>\n <div data-slot=\"auth-field\" className={className}>\n <div className=\"mb-1 flex items-center justify-between\">\n <label htmlFor={id} className=\"block text-sm font-medium text-foreground\">\n {label} {required && <span className=\"text-red-text\">*</span>}\n </label>\n {labelAction}\n </div>\n {trailing ? (\n <div className=\"relative\">\n {children}\n {trailing}\n </div>\n ) : (\n children\n )}\n {error && (\n <p\n id={errorId}\n role=\"alert\"\n className=\"mt-1 text-sm text-red-text\"\n data-testid={errorTestId}\n >\n {error}\n </p>\n )}\n </div>\n </AuthFieldContext.Provider>\n )\n}\n\n/** Input styled for auth forms (faint placeholder). */\nexport function AuthInput({\n className,\n id,\n 'aria-describedby': describedBy,\n 'aria-invalid': invalid,\n ...props\n}: ComponentProps<typeof Input>) {\n const field = useContext(AuthFieldContext)\n return (\n <Input\n id={id ?? field?.id}\n aria-describedby={joinIds(describedBy, field?.errorId)}\n aria-invalid={invalid ?? (field?.errorId ? true : undefined)}\n className={cn('placeholder:text-muted-foreground', className)}\n {...props}\n />\n )\n}\n\n/** Every fixed string of the revealable password input. */\nexport interface RevealablePasswordInputLabels {\n hidePassword: string\n showPassword: string\n}\n\nexport const DEFAULT_REVEALABLE_PASSWORD_INPUT_LABELS: RevealablePasswordInputLabels = {\n hidePassword: 'Hide password',\n showPassword: 'Show password',\n}\n\n/** Every fixed string of the offline badge. */\nexport interface AuthOfflineBadgeLabels {\n offline: string\n}\n\nexport const DEFAULT_AUTH_OFFLINE_BADGE_LABELS: AuthOfflineBadgeLabels = {\n offline: 'Offline',\n}\n\nexport interface RevealablePasswordInputProps extends Omit<ComponentProps<typeof Input>, 'type'> {\n /** Controlled reveal state. Omit it and the input manages its own (see `defaultRevealed`). */\n isRevealed?: boolean\n /** Initial state when uncontrolled. */\n defaultRevealed?: boolean\n /** Called on every toggle press, controlled or not. */\n onToggleReveal?: () => void\n labels?: Partial<RevealablePasswordInputLabels>\n /** Show/hide button id (default `toggle-password-visibility`); `data-testid` goes to the input. */\n toggleTestId?: string\n}\n\n/** Password input with a show/hide button inside the field. */\nexport function RevealablePasswordInput({\n isRevealed: controlledRevealed,\n defaultRevealed = false,\n onToggleReveal,\n className,\n labels,\n toggleTestId,\n ...props\n}: RevealablePasswordInputProps) {\n const [innerRevealed, setInnerRevealed] = useState(defaultRevealed)\n const isControlled = controlledRevealed !== undefined\n const isRevealed = isControlled ? controlledRevealed : innerRevealed\n const l = useMemo(() => ({ ...DEFAULT_REVEALABLE_PASSWORD_INPUT_LABELS, ...labels }), [labels])\n return (\n <div className=\"relative\">\n <AuthInput\n type={isRevealed ? 'text' : 'password'}\n className={cn('pr-10', className)}\n {...props}\n />\n <button\n type=\"button\"\n onClick={() => {\n if (!isControlled) setInnerRevealed((prev) => !prev)\n onToggleReveal?.()\n }}\n aria-label={isRevealed ? l.hidePassword : l.showPassword}\n aria-pressed={isRevealed}\n className=\"absolute inset-y-0 right-0 flex w-10 items-center justify-center rounded-r-md text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring pointer-coarse:w-11\"\n data-testid={testIdOr(toggleTestId, { testId: 'toggle-password-visibility' })}\n >\n {isRevealed ? (\n <EyeOff className=\"h-4 w-4\" aria-hidden=\"true\" />\n ) : (\n <Eye className=\"h-4 w-4\" aria-hidden=\"true\" />\n )}\n </button>\n </div>\n )\n}\n\n/** Small pill on a locked field, e.g. \"Verified\". */\nexport function AuthFieldBadge({\n icon,\n children,\n testId,\n}: {\n icon?: ReactNode\n children: ReactNode\n testId?: string\n}) {\n return (\n <span\n className=\"pointer-events-none absolute inset-y-0 right-3 flex items-center gap-1 text-xs font-medium text-green-text\"\n data-testid={testId}\n >\n {icon}\n {children}\n </span>\n )\n}\n\n/** Centred muted sentence under a step's primary action. */\nexport function AuthNote({ className, ...props }: ComponentProps<'p'>) {\n return <p className={cn('text-center text-sm text-muted-foreground', className)} {...props} />\n}\n\n/** Error / status message box for a form. */\nexport function AuthAlert({\n children,\n withIcon = false,\n testId,\n id,\n}: {\n children: ReactNode\n withIcon?: boolean\n testId?: string\n /** Lets a field point at this message with `aria-describedby`. */\n id?: string\n}) {\n return (\n <div\n id={id}\n role=\"alert\"\n data-testid={testId}\n className=\"flex gap-2 rounded-md bg-red-bg p-3 text-sm text-red-text\"\n >\n {withIcon && <AlertCircle className=\"h-5 w-5 flex-shrink-0\" aria-hidden=\"true\" />}\n <div>{children}</div>\n </div>\n )\n}\n\nexport interface AuthSubmitButtonProps extends ComponentProps<typeof Button> {\n /** Shows a spinner and sets `aria-busy`. */\n isBusy?: boolean\n /** Shorthand for `data-testid`. */\n testId?: string\n}\n\n/** Full-width primary submit with a spinner while busy. */\nexport function AuthSubmitButton({\n isBusy,\n testId,\n children,\n className,\n ...props\n}: AuthSubmitButtonProps) {\n return (\n <Button\n type=\"submit\"\n className={cn('w-full', className)}\n aria-busy={isBusy || undefined}\n data-testid={testId}\n {...props}\n >\n {isBusy && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />}\n {children}\n </Button>\n )\n}\n\n/** \"or continue with\" separator between the form and the SSO button. */\nexport function AuthDivider({ label, testId }: { label: string; testId?: string }) {\n return (\n <div\n data-slot=\"auth-divider\"\n data-testid={testIdOr(testId, { testId: 'login-divider' })}\n className=\"relative\"\n >\n <div className=\"absolute inset-0 flex items-center\">\n <div className=\"w-full border-t border-border\" />\n </div>\n <div className=\"relative flex justify-center text-xs\">\n <span className=\"bg-background px-2 text-muted-foreground\">{label}</span>\n </div>\n </div>\n )\n}\n\nexport interface AuthTabOption<T extends string> {\n value: T\n label: string\n testId?: string\n}\n\n/**\n * Underline tab pair (Login / Register) above the form. Radix Tabs: one tab stop, arrow keys,\n * Home and End move between tabs and select them (the form below swaps with the selection).\n */\nexport function AuthTabs<T extends string>({\n value,\n onChange,\n tabs,\n ariaLabel,\n}: {\n value: T\n onChange: (value: T) => void\n tabs: AuthTabOption<T>[]\n ariaLabel: string\n}) {\n return (\n <TabsPrimitive.Root value={value} onValueChange={(next) => onChange(next as T)}>\n <TabsPrimitive.List aria-label={ariaLabel} className=\"inline-flex items-center gap-6\">\n {tabs.map((tab) => (\n <TabsPrimitive.Trigger\n key={tab.value}\n value={tab.value}\n data-testid={tab.testId}\n className={cn(\n '-mb-px border-b-2 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-w-11 pointer-coarse:py-3',\n tab.value === value\n ? 'border-primary text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n )}\n >\n {tab.label}\n </TabsPrimitive.Trigger>\n ))}\n </TabsPrimitive.List>\n {/* The form the tabs switch lives outside this component; these empty, hidden panels only\n give each tab's `aria-controls` a valid target. */}\n {tabs.map((tab) => (\n <TabsPrimitive.Content\n key={tab.value}\n value={tab.value}\n tabIndex={-1}\n aria-hidden=\"true\"\n className=\"hidden\"\n />\n ))}\n </TabsPrimitive.Root>\n )\n}\n\n/** Pill shown instead of the tabs when the device is offline. */\nexport function AuthOfflineBadge({\n label,\n title,\n testId,\n labels,\n}: {\n label?: string\n title?: string\n testId?: string\n labels?: Partial<AuthOfflineBadgeLabels>\n}) {\n const text = label ?? labels?.offline ?? DEFAULT_AUTH_OFFLINE_BADGE_LABELS.offline\n return (\n <span\n data-testid={testIdOr(testId, { testId: 'login-offline-indicator' })}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-yellow-bg px-2.5 py-1.5 text-sm font-medium text-yellow-text\"\n title={title}\n >\n <WifiOff className=\"h-4 w-4 shrink-0\" />\n {text}\n </span>\n )\n}\n","import { useMemo, type ReactNode } from 'react'\nimport { MoreVertical } from 'lucide-react'\nimport {\n Checkbox,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\n\nexport interface AuthLegalLink {\n href: string\n label: string\n}\n\nexport interface AuthConsentProps {\n termsAccepted: boolean\n onTermsAcceptedChange: (accepted: boolean) => void\n /** Whether to download a recovery key on signup (opt-out; unchecking shows the warning). */\n saveRecoveryKey: boolean\n onSaveRecoveryKeyChange: (save: boolean) => void\n termsLink: AuthLegalLink\n privacyLink: AuthLegalLink\n /** Shown (role=\"alert\") only when the recovery-key box is unchecked. */\n noRecoveryKeyWarning: string\n labels?: Partial<AuthConsentLabels>\n /** Part ids; defaults are the current ids. */\n testIds?: Partial<\n Record<'termsCheckbox' | 'recoveryKeyCheckbox' | 'noRecoveryKeyWarning', string>\n >\n}\n\n/** Every fixed string of the sign-up consent block. */\nexport interface AuthConsentLabels {\n /** Text before the terms link. */\n acknowledge: string\n /** Text between the terms and privacy links. */\n and: string\n downloadRecoveryKey: string\n}\n\nexport const DEFAULT_AUTH_CONSENT_LABELS: AuthConsentLabels = {\n acknowledge: 'I acknowledge the',\n and: 'and',\n downloadRecoveryKey: 'Download my recovery key',\n}\n\n/** Every fixed string of the sign-in footer. */\nexport interface AuthFooterLinksLabels {\n installOptions: string\n install: string\n}\n\nexport const DEFAULT_AUTH_FOOTER_LINKS_LABELS: AuthFooterLinksLabels = {\n installOptions: 'Install options',\n install: 'Install',\n}\n\nconst LEGAL_LINK_CLASS = 'underline transition-colors hover:text-primary'\n\n/** Sign-up consent: required terms checkbox and the opt-out \"download recovery key\" checkbox. */\nexport function AuthConsent({\n termsAccepted,\n onTermsAcceptedChange,\n saveRecoveryKey,\n onSaveRecoveryKeyChange,\n termsLink,\n privacyLink,\n noRecoveryKeyWarning,\n labels,\n testIds,\n}: AuthConsentProps) {\n const l = useMemo(() => ({ ...DEFAULT_AUTH_CONSENT_LABELS, ...labels }), [labels])\n return (\n <div data-slot=\"auth-consent\" className=\"space-y-2\">\n <div className=\"flex items-start gap-2\">\n <Checkbox\n id=\"accept-terms\"\n checked={termsAccepted}\n onCheckedChange={(checked) => onTermsAcceptedChange(checked === true)}\n data-testid={testIdOr(testIds?.termsCheckbox, { testId: 'accept-terms-checkbox' })}\n />\n <label\n htmlFor=\"accept-terms\"\n className=\"cursor-pointer text-sm leading-relaxed text-muted-foreground\"\n >\n {l.acknowledge}{' '}\n <a\n href={termsLink.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={LEGAL_LINK_CLASS}\n >\n {termsLink.label}\n </a>{' '}\n {l.and}{' '}\n <a\n href={privacyLink.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={LEGAL_LINK_CLASS}\n >\n {privacyLink.label}\n </a>\n </label>\n </div>\n <div className=\"flex items-start gap-2\">\n <Checkbox\n id=\"save-recovery-key\"\n checked={saveRecoveryKey}\n onCheckedChange={(checked) => onSaveRecoveryKeyChange(checked === true)}\n data-testid={testIdOr(testIds?.recoveryKeyCheckbox, {\n testId: 'save-recovery-key-checkbox',\n })}\n />\n <label\n htmlFor=\"save-recovery-key\"\n className=\"cursor-pointer text-sm leading-relaxed text-muted-foreground\"\n >\n {l.downloadRecoveryKey}\n </label>\n </div>\n {/* Only shown on opt-out: the default path stays free of warnings. */}\n {!saveRecoveryKey && (\n <p\n className=\"text-sm text-red-text\"\n role=\"alert\"\n data-testid={testIdOr(testIds?.noRecoveryKeyWarning, {\n testId: 'no-recovery-key-warning',\n })}\n >\n {noRecoveryKeyWarning}\n </p>\n )}\n </div>\n )\n}\n\nexport interface AuthInstallOption {\n id: string\n label: ReactNode\n icon?: ReactNode\n onSelect: () => void\n disabled?: boolean\n testId?: string\n}\n\nexport interface AuthFooterLinksProps {\n privacyLink: AuthLegalLink\n /** Entries of the \"Install\" kebab menu. Omit/empty to hide the menu. */\n installOptions?: AuthInstallOption[]\n /** Dialog or other overlay owned by the host, rendered inside the footer. */\n children?: ReactNode\n labels?: Partial<AuthFooterLinksLabels>\n /** Install menu trigger id (default `install-options-trigger`). */\n installTriggerTestId?: string\n}\n\n/** Sign-in footer: privacy link on the left, an \"Install\" kebab menu on the right. */\nexport function AuthFooterLinks({\n privacyLink,\n installOptions = [],\n children,\n labels,\n installTriggerTestId,\n}: AuthFooterLinksProps) {\n const l = useMemo(() => ({ ...DEFAULT_AUTH_FOOTER_LINKS_LABELS, ...labels }), [labels])\n return (\n <div\n data-slot=\"auth-footer-links\"\n className=\"flex items-center justify-between pt-2 text-sm text-muted-foreground\"\n >\n <a\n href={privacyLink.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-center transition-colors hover:text-primary pointer-coarse:min-h-11\"\n >\n {privacyLink.label}\n </a>\n\n {installOptions.length > 0 && (\n <DropdownMenu>\n <DropdownMenuTrigger\n className=\"flex items-center gap-1 rounded-md px-1.5 py-1 transition-colors hover:text-primary focus:outline-none focus-visible:ring-1 focus-visible:ring-ring pointer-coarse:min-h-11\"\n aria-label={l.installOptions}\n data-testid={testIdOr(installTriggerTestId, { testId: 'install-options-trigger' })}\n >\n {l.install}\n <MoreVertical size={14} />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {installOptions.map((option) => (\n <DropdownMenuItem\n key={option.id}\n onClick={option.onSelect}\n disabled={option.disabled}\n className=\"gap-2\"\n data-testid={option.testId}\n >\n {option.icon}\n {option.label}\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n {children}\n </div>\n )\n}\n","/**\n * Auth Error Parsing Utility\n *\n * Parses API error responses into user-friendly messages.\n * Handles FastAPI/Pydantic error formats (detail field) and standard Error objects.\n */\n\nexport interface ParseAuthErrorOptions {\n /** Default message if error cannot be parsed */\n defaultMessage?: string\n /** Check for 429 rate limit errors */\n checkRateLimit?: boolean\n /** Map specific error messages to custom messages */\n messageMap?: Record<string, string>\n}\n\n/**\n * Parse an API error into a user-friendly message\n */\nexport function parseAuthError(error: unknown, options: ParseAuthErrorOptions = {}): string {\n const {\n defaultMessage = 'Unable to communicate with the server',\n checkRateLimit = false,\n messageMap = {},\n } = options\n\n if (!error) return defaultMessage\n\n // An Error carrying the server's answer (`detail`, `status`: what the SDK's auth calls throw) is\n // read like the answer itself.\n if (error instanceof Error && !('detail' in error) && !('status' in error)) {\n return isNetworkError(error.message)\n ? defaultMessage\n : applyMessageMap(error.message, messageMap)\n }\n\n if (typeof error !== 'object') return defaultMessage\n\n const errorObj = error as {\n detail?: string | Array<{ msg: string }>\n message?: string\n status?: number\n }\n // The server's answer wins over a wrapping message (\"Login failed: …\").\n const message = errorObj.detail === undefined ? errorObj.message : undefined\n\n // Check for rate limiting (429)\n if (checkRateLimit) {\n if (\n errorObj.status === 429 ||\n errorObj.message?.includes('429') ||\n (typeof errorObj.detail === 'string' && errorObj.detail.includes('429'))\n ) {\n return 'Error: duplicate request'\n }\n }\n\n // Handle detail field (FastAPI/Pydantic style)\n if (errorObj.detail) {\n if (Array.isArray(errorObj.detail)) {\n return errorObj.detail[0]?.msg || 'Validation error occurred'\n }\n if (typeof errorObj.detail === 'string') {\n return applyMessageMap(errorObj.detail, messageMap)\n }\n }\n\n // Handle message field\n if (message) {\n return isNetworkError(message) ? defaultMessage : applyMessageMap(message, messageMap)\n }\n\n return defaultMessage\n}\n\nfunction isNetworkError(message: string): boolean {\n const lower = message.toLowerCase()\n return lower.includes('fetch') || lower.includes('network')\n}\n\nfunction applyMessageMap(message: string, messageMap: Record<string, string>): string {\n return messageMap[message] ?? message\n}\n","/**\n * Password rules: the requirements a new password must meet (registration, a new SSO account's\n * master password, a password change), as one value a site configures once (`createPasswordRules`)\n * and every form reads: the one-line hint of `PasswordStrengthInput`, the submit gate, the error.\n */\n\nexport interface PasswordRequirements {\n minLength: boolean\n hasUpperOrSpecial: boolean\n hasNumber: boolean\n}\n\nexport interface PasswordRules {\n minLength: number\n /** Which requirements the password meets. */\n check(password: string): PasswordRequirements\n /** The first unmet requirement as a short hint, or `null` when the password is acceptable. */\n unmet(password: string): string | null\n isValid(password: string): boolean\n /** The first unmet requirement as a sentence (an error to show), or `null`. */\n error(password: string): string | null\n}\n\n/** The rules with a minimum length (default 8): one uppercase or special character, one number. */\nexport function createPasswordRules(minLength = 8): PasswordRules {\n const check = (password: string): PasswordRequirements => ({\n minLength: password.length >= minLength,\n hasUpperOrSpecial: /[A-Z!@#$%^&*()_+\\-=[\\]{};':\"\\\\|,.<>/?]/.test(password),\n hasNumber: /[0-9]/.test(password),\n })\n return {\n minLength,\n check,\n unmet(password) {\n const met = check(password)\n if (!met.minLength) return `Minimum ${minLength} characters`\n if (!met.hasUpperOrSpecial) return 'At least one uppercase letter or special character'\n if (!met.hasNumber) return 'At least one number'\n return null\n },\n isValid(password) {\n const met = check(password)\n return met.minLength && met.hasUpperOrSpecial && met.hasNumber\n },\n error(password) {\n const met = check(password)\n if (!met.minLength) return `Password must be at least ${minLength} characters long.`\n if (!met.hasUpperOrSpecial) {\n return 'Password must contain at least one uppercase letter or special character.'\n }\n if (!met.hasNumber) return 'Password must contain at least one number.'\n return null\n },\n }\n}\n\n/** The default rules (8 characters). */\nexport const DEFAULT_PASSWORD_RULES = createPasswordRules()\n","/**\n * Credential Storage Utilities\n *\n * Uses the Credential Management API to prompt browsers to save passwords.\n * This helps users store passwords in their browser's built-in password manager.\n */\n\n/**\n * Prompt the browser to save credentials to its password manager.\n *\n * This uses the Credential Management API which is supported by:\n * - Chrome/Edge (full support, syncs to Google/Microsoft account)\n * - Firefox (limited support)\n * - Safari (uses Keychain instead)\n *\n * @param email - User's email address\n * @param password - User's password\n * @returns true if credential was stored, false otherwise\n */\nexport async function promptSaveCredential(email: string, password: string): Promise<boolean> {\n // Check if Credential Management API is supported\n if (!('credentials' in navigator) || !('PasswordCredential' in window)) {\n console.info('[CREDENTIAL] Credential Management API not supported')\n return false\n }\n\n try {\n // Create a PasswordCredential object\n const credential = new (\n window as unknown as {\n PasswordCredential: new (data: {\n id: string\n password: string\n name?: string\n }) => Credential\n }\n ).PasswordCredential({\n id: email,\n password: password,\n name: 'ARBI Account',\n })\n\n // Prompt the browser to store the credential\n await navigator.credentials.store(credential)\n console.info('[CREDENTIAL] Credential stored successfully')\n return true\n } catch (error) {\n // User may have declined or browser doesn't support\n console.info('[CREDENTIAL] Failed to store credential:', error)\n return false\n }\n}\n","import {\n useMemo,\n useRef,\n useState,\n type DragEvent,\n type FormEvent,\n type ReactNode,\n useId,\n} from 'react'\nimport { AlertCircle, Key, Loader2, Shield, Upload } from 'lucide-react'\nimport {\n Button,\n cn,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Input,\n} from '@arbidocs/react/ui'\nimport { testIdOr } from '../chat/test-id'\n\nfunction ErrorBox({ message, id }: { message: string; id?: string }) {\n return (\n <div id={id} role=\"alert\" className=\"rounded-md bg-red-bg p-3\">\n <div className=\"flex gap-2\">\n <AlertCircle className=\"h-5 w-5 flex-shrink-0 text-red-text\" aria-hidden=\"true\" />\n <p className=\"text-sm text-red-text\">{message}</p>\n </div>\n </div>\n )\n}\n\n/** Every fixed string of the recovery-key dialog. `title` / description props win. */\nexport interface RecoveryKeyDialogLabels {\n title: string\n verifiedDescription: string\n unverifiedDescription: string\n done: string\n currentPassword: string\n passwordPlaceholder: string\n cancel: string\n verifying: string\n verify: string\n}\n\nexport const DEFAULT_RECOVERY_KEY_DIALOG_LABELS: RecoveryKeyDialogLabels = {\n title: 'Save your recovery key',\n verifiedDescription:\n \"If you forget your password, this is the only way to get back into your account. Save it to your password manager so it's there when you need it.\",\n unverifiedDescription: 'Confirm your password to continue.',\n done: 'Done',\n currentPassword: 'Current Password',\n passwordPlaceholder: 'Enter your password',\n cancel: 'Cancel',\n verifying: 'Verifying...',\n verify: 'Verify',\n}\n\n/** Every fixed string of the account-recovery dialog. */\nexport interface AccountRecoveryDialogLabels {\n title: string\n description: string\n emailAddress: string\n emailPlaceholder: string\n keyLoadedFromLink: string\n ssoProtectedKeyNotice: string\n recoveryKey: string\n ssoProtectedKey: string\n dropKeyHere: string\n uploadKeyPrompt: string\n ssoSignInNotice: string\n ssoSignIn: string\n afterRecoveryNotice: string\n cancel: string\n recovering: string\n recoverAccount: string\n}\n\nexport const DEFAULT_ACCOUNT_RECOVERY_DIALOG_LABELS: AccountRecoveryDialogLabels = {\n title: 'Recover Your Account',\n description: 'Upload your recovery key to regain access to your account',\n emailAddress: 'Email Address',\n emailPlaceholder: 'Enter your email',\n keyLoadedFromLink: 'Recovery key loaded from link',\n ssoProtectedKeyNotice: 'SSO-protected key — you must be signed into the matching SSO account.',\n recoveryKey: 'Recovery Key',\n ssoProtectedKey: 'SSO Protected Key',\n dropKeyHere: 'Drop your recovery key here',\n uploadKeyPrompt: 'Click or drag to upload your recovery key (.key file)',\n ssoSignInNotice:\n 'This account signs in with single sign-on. Sign in with your identity provider to continue — you won\\u2019t need your forgotten master password for that step.',\n ssoSignIn: 'Sign in with Auth0 to continue',\n afterRecoveryNotice:\n 'After successful recovery, you will be prompted to set a new password to secure your account.',\n cancel: 'Cancel',\n recovering: 'Recovering...',\n recoverAccount: 'Recover Account',\n}\n\nexport interface RecoveryKeyDialogProps {\n labels?: Partial<RecoveryKeyDialogLabels>\n open: boolean\n onClose: () => void\n /** Content shown once the password is verified (the key download). `null` while verifying. */\n verified: ReactNode | null\n password: string\n onPasswordChange: (password: string) => void\n onVerify: () => void\n isVerifying: boolean\n error: string | null\n title?: string\n verifiedDescription?: string\n unverifiedDescription?: string\n /** Dialog test id (default `download-recovery-key-dialog`). */\n testId?: string\n /** Part ids; defaults are the current ids. */\n testIds?: Partial<Record<'passwordInput', string>>\n}\n\n/**\n * \"Save your recovery key\": confirm the account password first, then reveal the key download\n * (`verified`) with a Done button.\n */\nexport function RecoveryKeyDialog({\n open,\n onClose,\n verified,\n password,\n onPasswordChange,\n onVerify,\n isVerifying,\n error,\n title,\n verifiedDescription,\n unverifiedDescription,\n labels,\n testId,\n testIds,\n}: RecoveryKeyDialogProps) {\n const verifyPasswordId = useId()\n const l = useMemo(() => ({ ...DEFAULT_RECOVERY_KEY_DIALOG_LABELS, ...labels }), [labels])\n const handleSubmit = (e: FormEvent) => {\n e.preventDefault()\n onVerify()\n }\n\n return (\n <Dialog open={open} onOpenChange={onClose}>\n <DialogContent\n presentation=\"sheet\"\n className=\"sm:max-w-md\"\n data-testid={testIdOr(testId, { testId: 'download-recovery-key-dialog' })}\n >\n <DialogHeader>\n <DialogTitle className=\"font-heading\">{title ?? l.title}</DialogTitle>\n <DialogDescription>\n {verified\n ? (verifiedDescription ?? l.verifiedDescription)\n : (unverifiedDescription ?? l.unverifiedDescription)}\n </DialogDescription>\n </DialogHeader>\n\n {verified ? (\n <div className=\"space-y-4\">\n {verified}\n <div className=\"flex justify-end\">\n <Button onClick={onClose}>{l.done}</Button>\n </div>\n </div>\n ) : (\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n <div className=\"space-y-2\">\n <label htmlFor={verifyPasswordId} className=\"text-sm font-medium\">\n {l.currentPassword}\n </label>\n <Input\n id={verifyPasswordId}\n type=\"password\"\n value={password}\n onChange={(e) => onPasswordChange(e.target.value)}\n placeholder={l.passwordPlaceholder}\n disabled={isVerifying}\n autoComplete=\"current-password\"\n aria-invalid={error ? true : undefined}\n aria-describedby={error ? `${verifyPasswordId}-error` : undefined}\n data-testid={testIdOr(testIds?.passwordInput, { testId: 'verify-password-input' })}\n />\n </div>\n\n {error && <ErrorBox message={error} id={`${verifyPasswordId}-error`} />}\n\n <div className=\"flex flex-col-reverse sm:flex-row sm:justify-end gap-3\">\n <Button type=\"button\" variant=\"outline\" onClick={onClose} disabled={isVerifying}>\n {l.cancel}\n </Button>\n <Button type=\"submit\" disabled={isVerifying || !password}>\n {isVerifying ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n {l.verifying}\n </>\n ) : (\n l.verify\n )}\n </Button>\n </div>\n </form>\n )}\n </DialogContent>\n </Dialog>\n )\n}\n\nexport interface AccountRecoveryDialogProps {\n labels?: Partial<AccountRecoveryDialogLabels>\n open: boolean\n onClose: () => void\n email: string\n onEmailChange: (email: string) => void\n /** The key arrived in the page URL (the /recover link): show a \"loaded\" notice, no file picker. */\n isKeyFromLink: boolean\n /** Name of the chosen key file, once one is loaded. */\n keyFileName: string | null\n /** The loaded key is wrapped with the user's SSO identity. */\n isKeyEncrypted: boolean\n /** A file was picked or dropped. */\n onKeyFile: (file: File) => void\n error: string | null\n /** SSO sign-in is the next required step (SSO-wrapped key or SSO-linked account). */\n needsSsoSignIn: boolean\n onSsoSignIn: () => void\n isProcessing: boolean\n /** Enables the submit button (email and key present). */\n canSubmit: boolean\n onSubmit: () => void\n /** Dialog test id (default `forgot-password-modal`). */\n testId?: string\n /** Part ids; defaults are the current ids. */\n testIds?: Partial<\n Record<'emailInput' | 'keyDropzone' | 'keyInput' | 'ssoSignIn' | 'cancel' | 'submit', string>\n >\n}\n\n/**\n * Account recovery: email + recovery key (file or link) -> sign in with the key. When the account\n * is SSO-linked, the SSO prompt replaces the submit button.\n */\nexport function AccountRecoveryDialog({\n open,\n onClose,\n email,\n onEmailChange,\n isKeyFromLink,\n keyFileName,\n isKeyEncrypted,\n onKeyFile,\n error,\n needsSsoSignIn,\n onSsoSignIn,\n isProcessing,\n canSubmit,\n onSubmit,\n labels,\n testId,\n testIds,\n}: AccountRecoveryDialogProps) {\n const recoveryEmailId = useId()\n const l = useMemo(() => ({ ...DEFAULT_ACCOUNT_RECOVERY_DIALOG_LABELS, ...labels }), [labels])\n const fileInputRef = useRef<HTMLInputElement>(null)\n const [isDragActive, setIsDragActive] = useState(false)\n\n const handleDragOver = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(true)\n }\n const handleDragLeave = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(false)\n }\n const handleDrop = (e: DragEvent) => {\n e.preventDefault()\n e.stopPropagation()\n setIsDragActive(false)\n const file = e.dataTransfer.files?.[0]\n if (file) onKeyFile(file)\n }\n\n return (\n <Dialog open={open} onOpenChange={onClose}>\n <DialogContent\n presentation=\"sheet\"\n className=\"sm:max-w-md\"\n data-testid={testIdOr(testId, { testId: 'forgot-password-modal' })}\n >\n <DialogHeader>\n <DialogTitle className=\"flex items-center gap-2\">\n <Key className=\"h-5 w-5 text-primary\" />\n {l.title}\n </DialogTitle>\n <DialogDescription>{l.description}</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-2\">\n <label htmlFor={recoveryEmailId} className=\"text-sm font-medium\">\n {l.emailAddress}\n </label>\n <Input\n id={recoveryEmailId}\n type=\"email\"\n value={email}\n onChange={(e) => onEmailChange(e.target.value)}\n placeholder={l.emailPlaceholder}\n disabled={isProcessing}\n data-testid={testIdOr(testIds?.emailInput, { testId: 'recovery-email-input' })}\n />\n </div>\n\n {isKeyFromLink ? (\n <div className=\"rounded-md bg-green-bg p-3\">\n <div className=\"flex items-center gap-2 text-sm\">\n <Key className=\"h-4 w-4 text-green-text\" />\n <span className=\"font-medium text-green-text\">{l.keyLoadedFromLink}</span>\n </div>\n {isKeyEncrypted && (\n <p className=\"mt-1 inline-flex items-center gap-1 text-sm text-primary\">\n <Shield className=\"h-3 w-3\" />\n {l.ssoProtectedKeyNotice}\n </p>\n )}\n </div>\n ) : (\n <div className=\"space-y-2\">\n <label className=\"text-sm font-medium\">{l.recoveryKey}</label>\n <div\n role=\"button\"\n tabIndex={0}\n className={cn(\n 'cursor-pointer rounded-lg p-4 text-center transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n isDragActive ? 'bg-accent' : 'bg-muted hover:bg-muted/70'\n )}\n onClick={() => fileInputRef.current?.click()}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n fileInputRef.current?.click()\n }\n }}\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n data-testid={testIdOr(testIds?.keyDropzone, { testId: 'recovery-key-dropzone' })}\n >\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\".key\"\n onClick={(e) => e.stopPropagation()}\n onChange={(e) => {\n const file = e.target.files?.[0]\n if (file) onKeyFile(file)\n }}\n className=\"hidden\"\n data-testid={testIdOr(testIds?.keyInput, { testId: 'recovery-key-input' })}\n />\n {keyFileName ? (\n <div className=\"flex flex-col items-center gap-1\">\n <div className=\"flex items-center justify-center gap-2 text-sm\">\n <Key className=\"h-4 w-4 text-green-text\" />\n <span className=\"font-medium text-green-text\">{keyFileName}</span>\n </div>\n {isKeyEncrypted && (\n <span className=\"inline-flex items-center gap-1 text-sm text-primary\">\n <Shield className=\"h-3 w-3\" />\n {l.ssoProtectedKey}\n </span>\n )}\n </div>\n ) : (\n <div className=\"space-y-2\">\n <Upload className=\"mx-auto h-8 w-8 text-muted-foreground\" />\n <p className=\"text-sm text-muted-foreground\">\n {isDragActive ? l.dropKeyHere : l.uploadKeyPrompt}\n </p>\n </div>\n )}\n </div>\n </div>\n )}\n\n {error && <ErrorBox message={error} />}\n\n {needsSsoSignIn ? (\n <div className=\"space-y-2 rounded-lg bg-muted p-3\">\n <div className=\"flex gap-2\">\n <Shield className=\"h-5 w-5 flex-shrink-0 text-primary\" />\n <p className=\"text-sm\">{l.ssoSignInNotice}</p>\n </div>\n <Button\n onClick={onSsoSignIn}\n className=\"w-full\"\n data-testid={testIdOr(testIds?.ssoSignIn, { testId: 'recovery-sso-signin-button' })}\n >\n {l.ssoSignIn}\n </Button>\n </div>\n ) : (\n <div className=\"rounded-md bg-muted p-3\">\n <p className=\"text-sm text-muted-foreground\">{l.afterRecoveryNotice}</p>\n </div>\n )}\n </div>\n\n <DialogFooter className=\"gap-2\">\n <Button\n variant=\"outline\"\n onClick={onClose}\n disabled={isProcessing}\n data-testid={testIdOr(testIds?.cancel, { testId: 'forgot-password-cancel' })}\n >\n {l.cancel}\n </Button>\n {/* Hidden when SSO sign-in is the next step, to avoid two competing options. */}\n {!needsSsoSignIn && (\n <Button\n onClick={onSubmit}\n disabled={isProcessing || !canSubmit}\n data-testid={testIdOr(testIds?.submit, { testId: 'forgot-password-submit' })}\n >\n {isProcessing ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n {l.recovering}\n </>\n ) : (\n l.recoverAccount\n )}\n </Button>\n )}\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n","/** The auth pages' URL fragment: `#verify=…&code=…&next=…`, and a fragment carried after it. */\n\n/**\n * Split an auth page's hash (`#verify=…&code=…&next=…`) from a second fragment appended after it.\n * A call invitation's registration link ends with the call key fragment (`…#k=…&v=…`) — a URL has\n * one fragment, so it arrives inside ours, after a second `#`.\n */\nexport function splitAuthHash(hash: string): {\n params: URLSearchParams\n /** `#k=…&v=…` (with its `#`), or '' when there is none. */\n trailingFragment: string\n} {\n const raw = hash.replace(/^#/, '')\n const cut = raw.indexOf('#')\n return {\n params: new URLSearchParams(cut >= 0 ? raw.slice(0, cut) : raw),\n trailingFragment: cut >= 0 ? raw.slice(cut) : '',\n }\n}\n\n/** `next` with the trailing fragment appended, unless `next` already carries a fragment. */\nexport function withTrailingFragment(next: string, trailingFragment: string): string {\n if (!trailingFragment || trailingFragment === '#' || next.includes('#')) return next\n return `${next}${trailingFragment}`\n}\n"]}
|