@brightchain/brightpass-react-components 0.1.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.
Files changed (52) hide show
  1. package/README.md +28 -0
  2. package/package.json +42 -0
  3. package/src/index.js +35 -0
  4. package/src/index.js.map +1 -0
  5. package/src/lib/BrightPassRoutes.js +33 -0
  6. package/src/lib/BrightPassRoutes.js.map +1 -0
  7. package/src/lib/components/BreadcrumbNav.js +70 -0
  8. package/src/lib/components/BreadcrumbNav.js.map +1 -0
  9. package/src/lib/components/CreateVaultDialog.js +57 -0
  10. package/src/lib/components/CreateVaultDialog.js.map +1 -0
  11. package/src/lib/components/EntryDetailView.js +167 -0
  12. package/src/lib/components/EntryDetailView.js.map +1 -0
  13. package/src/lib/components/EntryForm.js +196 -0
  14. package/src/lib/components/EntryForm.js.map +1 -0
  15. package/src/lib/components/MasterPasswordPrompt.js +56 -0
  16. package/src/lib/components/MasterPasswordPrompt.js.map +1 -0
  17. package/src/lib/components/SearchBar.js +137 -0
  18. package/src/lib/components/SearchBar.js.map +1 -0
  19. package/src/lib/context/BrightPassProvider.js +158 -0
  20. package/src/lib/context/BrightPassProvider.js.map +1 -0
  21. package/src/lib/dialogs/EmergencyAccessDialog.js +139 -0
  22. package/src/lib/dialogs/EmergencyAccessDialog.js.map +1 -0
  23. package/src/lib/dialogs/ImportDialog.js +146 -0
  24. package/src/lib/dialogs/ImportDialog.js.map +1 -0
  25. package/src/lib/dialogs/ShareDialog.js +82 -0
  26. package/src/lib/dialogs/ShareDialog.js.map +1 -0
  27. package/src/lib/hooks/useBrightPassApi.js +13 -0
  28. package/src/lib/hooks/useBrightPassApi.js.map +1 -0
  29. package/src/lib/hooks/useBrightPassAutofill.js +80 -0
  30. package/src/lib/hooks/useBrightPassAutofill.js.map +1 -0
  31. package/src/lib/hooks/useBrightPassExtensionBridge.js +108 -0
  32. package/src/lib/hooks/useBrightPassExtensionBridge.js.map +1 -0
  33. package/src/lib/hooks/useBrightPassTranslation.js +12 -0
  34. package/src/lib/hooks/useBrightPassTranslation.js.map +1 -0
  35. package/src/lib/services/BrightPassApiService.js +219 -0
  36. package/src/lib/services/BrightPassApiService.js.map +1 -0
  37. package/src/lib/views/AuditLogView.js +120 -0
  38. package/src/lib/views/AuditLogView.js.map +1 -0
  39. package/src/lib/views/PasswordGeneratorPage.js +20 -0
  40. package/src/lib/views/PasswordGeneratorPage.js.map +1 -0
  41. package/src/lib/views/VaultDetailView.js +93 -0
  42. package/src/lib/views/VaultDetailView.js.map +1 -0
  43. package/src/lib/views/VaultListView.js +99 -0
  44. package/src/lib/views/VaultListView.js.map +1 -0
  45. package/src/lib/widgets/BreachCheckWidget.js +57 -0
  46. package/src/lib/widgets/BreachCheckWidget.js.map +1 -0
  47. package/src/lib/widgets/PasswordGeneratorWidget.js +137 -0
  48. package/src/lib/widgets/PasswordGeneratorWidget.js.map +1 -0
  49. package/src/lib/widgets/TOTPWidget.js +165 -0
  50. package/src/lib/widgets/TOTPWidget.js.map +1 -0
  51. package/src/test-setup.js +13 -0
  52. package/src/test-setup.js.map +1 -0
@@ -0,0 +1,139 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { BrightPassStrings } from '@brightchain/brightchain-lib';
3
+ import CloseIcon from '@mui/icons-material/Close';
4
+ import { Alert, Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, Tab, Tabs, TextField, } from '@mui/material';
5
+ import React, { useCallback, useState } from 'react';
6
+ import { useBrightPassTranslation } from '../hooks/useBrightPassTranslation';
7
+ import { useBrightPassApi } from '../hooks/useBrightPassApi';
8
+ /**
9
+ * Pure helper: returns true when `1 <= threshold <= trusteesCount` and `trusteesCount >= 1`.
10
+ * Exported for property-based testing (Property 13).
11
+ */
12
+ export function validateThreshold(threshold, trusteesCount) {
13
+ if (trusteesCount < 1)
14
+ return false;
15
+ return threshold >= 1 && threshold <= trusteesCount;
16
+ }
17
+ export const EmergencyAccessDialog = ({ vaultId, open, onClose, onSuccess, }) => {
18
+ const { t } = useBrightPassTranslation();
19
+ const brightPassApi = useBrightPassApi();
20
+ const [mode, setMode] = useState('configure');
21
+ const [loading, setLoading] = useState(false);
22
+ const [error, setError] = useState(null);
23
+ const [success, setSuccess] = useState(null);
24
+ // Configure mode state
25
+ const [threshold, setThreshold] = useState(1);
26
+ const [trusteesInput, setTrusteesInput] = useState('');
27
+ // Recover mode state
28
+ const [shareInputs, setShareInputs] = useState(['']);
29
+ // Reset state when dialog opens
30
+ React.useEffect(() => {
31
+ if (open) {
32
+ setError(null);
33
+ setSuccess(null);
34
+ setThreshold(1);
35
+ setTrusteesInput('');
36
+ setShareInputs(['']);
37
+ setMode('configure');
38
+ }
39
+ }, [open]);
40
+ const parseTrustees = useCallback(() => {
41
+ return trusteesInput
42
+ .split(',')
43
+ .map((s) => s.trim())
44
+ .filter((s) => s.length > 0);
45
+ }, [trusteesInput]);
46
+ const handleConfigure = useCallback(async () => {
47
+ setError(null);
48
+ setSuccess(null);
49
+ const trustees = parseTrustees();
50
+ if (!validateThreshold(threshold, trustees.length)) {
51
+ setError(t(BrightPassStrings.Emergency_InvalidThreshold));
52
+ return;
53
+ }
54
+ setLoading(true);
55
+ try {
56
+ await brightPassApi.configureEmergencyAccess(vaultId, {
57
+ vaultId,
58
+ threshold,
59
+ totalShares: trustees.length,
60
+ trustees,
61
+ });
62
+ setSuccess(t(BrightPassStrings.Emergency_Success));
63
+ onSuccess?.();
64
+ }
65
+ catch {
66
+ setError(t(BrightPassStrings.Emergency_Error));
67
+ }
68
+ finally {
69
+ setLoading(false);
70
+ }
71
+ }, [vaultId, threshold, parseTrustees, t, onSuccess]);
72
+ const handleRecover = useCallback(async () => {
73
+ setError(null);
74
+ setSuccess(null);
75
+ const filledShares = shareInputs.filter((s) => s.trim().length > 0);
76
+ if (filledShares.length === 0) {
77
+ setError(t(BrightPassStrings.Emergency_InsufficientShares, {
78
+ THRESHOLD: '1',
79
+ }));
80
+ return;
81
+ }
82
+ const shares = filledShares.map((shareData, idx) => ({
83
+ trusteeId: `trustee-${idx}`,
84
+ encryptedShareData: new TextEncoder().encode(shareData.trim()),
85
+ }));
86
+ setLoading(true);
87
+ try {
88
+ await brightPassApi.recoverWithShares(vaultId, shares);
89
+ setSuccess(t(BrightPassStrings.Emergency_Success));
90
+ onSuccess?.();
91
+ }
92
+ catch (err) {
93
+ const message = err && typeof err === 'object' && 'message' in err
94
+ ? String(err.message)
95
+ : t(BrightPassStrings.Emergency_Error);
96
+ // Check if the error indicates insufficient shares
97
+ if (message.toLowerCase().includes('insufficient')) {
98
+ setError(t(BrightPassStrings.Emergency_InsufficientShares, {
99
+ THRESHOLD: '?',
100
+ }));
101
+ }
102
+ else {
103
+ setError(t(BrightPassStrings.Emergency_Error));
104
+ }
105
+ }
106
+ finally {
107
+ setLoading(false);
108
+ }
109
+ }, [vaultId, shareInputs, t, onSuccess]);
110
+ const handleShareInputChange = useCallback((index, value) => {
111
+ setShareInputs((prev) => {
112
+ const next = [...prev];
113
+ next[index] = value;
114
+ return next;
115
+ });
116
+ }, []);
117
+ const addShareInput = useCallback(() => {
118
+ setShareInputs((prev) => [...prev, '']);
119
+ }, []);
120
+ const trustees = parseTrustees();
121
+ const isThresholdValid = validateThreshold(threshold, trustees.length);
122
+ return (_jsxs(Dialog, { open: open, onClose: onClose, maxWidth: "sm", fullWidth: true, children: [_jsx(DialogTitle, { children: _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", children: [t(BrightPassStrings.Emergency_Title), _jsx(IconButton, { "aria-label": t(BrightPassStrings.Emergency_Close), onClick: onClose, size: "small", children: _jsx(CloseIcon, {}) })] }) }), _jsxs(DialogContent, { children: [_jsxs(Tabs, { value: mode, onChange: (_, newMode) => {
123
+ setMode(newMode);
124
+ setError(null);
125
+ setSuccess(null);
126
+ }, sx: { mb: 2 }, children: [_jsx(Tab, { label: t(BrightPassStrings.Emergency_Configure), value: "configure" }), _jsx(Tab, { label: t(BrightPassStrings.Emergency_Recover), value: "recover" })] }), error && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: error })), success && (_jsx(Alert, { severity: "success", sx: { mb: 2 }, children: success })), mode === 'configure' && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(TextField, { label: t(BrightPassStrings.Emergency_Trustees), value: trusteesInput, onChange: (e) => {
127
+ setTrusteesInput(e.target.value);
128
+ setError(null);
129
+ }, fullWidth: true, disabled: loading, "aria-label": t(BrightPassStrings.Emergency_Trustees) }), _jsx(TextField, { label: t(BrightPassStrings.Emergency_Threshold), type: "number", value: threshold, onChange: (e) => {
130
+ setThreshold(Number(e.target.value));
131
+ setError(null);
132
+ }, inputProps: { min: 1, max: trustees.length || 1 }, error: trusteesInput.length > 0 && !isThresholdValid, fullWidth: true, disabled: loading, "aria-label": t(BrightPassStrings.Emergency_Threshold) })] })), mode === 'recover' && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [shareInputs.map((shareValue, idx) => (_jsx(TextField, { label: t(BrightPassStrings.Emergency_Shares, {
133
+ INDEX: String(idx + 1),
134
+ }), value: shareValue, onChange: (e) => handleShareInputChange(idx, e.target.value), fullWidth: true, multiline: true, minRows: 2, disabled: loading, "aria-label": t(BrightPassStrings.Emergency_Shares, {
135
+ INDEX: String(idx + 1),
136
+ }) }, idx))), _jsx(Button, { variant: "outlined", onClick: addShareInput, disabled: loading, size: "small", children: "+" })] }))] }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: onClose, disabled: loading, children: t(BrightPassStrings.Emergency_Close) }), mode === 'configure' && (_jsx(Button, { variant: "contained", onClick: handleConfigure, disabled: loading || !isThresholdValid, startIcon: loading ? _jsx(CircularProgress, { size: 16, color: "inherit" }) : undefined, children: t(BrightPassStrings.Emergency_Configure) })), mode === 'recover' && (_jsx(Button, { variant: "contained", onClick: handleRecover, disabled: loading || shareInputs.every((s) => s.trim().length === 0), startIcon: loading ? _jsx(CircularProgress, { size: 16, color: "inherit" }) : undefined, children: t(BrightPassStrings.Emergency_Recover) }))] })] }));
137
+ };
138
+ export default EmergencyAccessDialog;
139
+ //# sourceMappingURL=EmergencyAccessDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmergencyAccessDialog.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/dialogs/EmergencyAccessDialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { BrightPassStrings } from '@brightchain/brightchain-lib';
3
+ import CloseIcon from '@mui/icons-material/Close';
4
+ import UploadFileIcon from '@mui/icons-material/UploadFile';
5
+ import { Alert, Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, MenuItem, Select, Typography, } from '@mui/material';
6
+ import React, { useCallback, useRef, useState } from 'react';
7
+ import { useBrightPassTranslation } from '../hooks/useBrightPassTranslation';
8
+ import { useBrightPassApi } from '../hooks/useBrightPassApi';
9
+ /**
10
+ * Maps an ImportFormat to the accepted file extensions and MIME types.
11
+ * Exported for property-based testing (Property 14).
12
+ */
13
+ export function getAcceptedFileTypes(format) {
14
+ switch (format) {
15
+ case '1password_1pux':
16
+ return { extensions: ['.1pux'], mimeTypes: [] };
17
+ case '1password_csv':
18
+ case 'lastpass_csv':
19
+ case 'bitwarden_csv':
20
+ case 'chrome_csv':
21
+ case 'firefox_csv':
22
+ return { extensions: ['.csv'], mimeTypes: ['text/csv'] };
23
+ case 'bitwarden_json':
24
+ case 'dashlane_json':
25
+ return { extensions: ['.json'], mimeTypes: ['application/json'] };
26
+ case 'keepass_xml':
27
+ return {
28
+ extensions: ['.xml'],
29
+ mimeTypes: ['application/xml', 'text/xml'],
30
+ };
31
+ default:
32
+ return { extensions: [], mimeTypes: [] };
33
+ }
34
+ }
35
+ /**
36
+ * Formats an import result into a summary object.
37
+ * Exported for property-based testing (Property 15).
38
+ */
39
+ export function formatImportSummary(result) {
40
+ return {
41
+ total: result.imported + result.skipped,
42
+ hasErrors: result.errors.length > 0,
43
+ };
44
+ }
45
+ const FORMAT_OPTIONS = [
46
+ { value: '1password_1pux', label: '1Password (1PUX)' },
47
+ { value: '1password_csv', label: '1Password (CSV)' },
48
+ { value: 'lastpass_csv', label: 'LastPass (CSV)' },
49
+ { value: 'bitwarden_json', label: 'Bitwarden (JSON)' },
50
+ { value: 'bitwarden_csv', label: 'Bitwarden (CSV)' },
51
+ { value: 'chrome_csv', label: 'Chrome (CSV)' },
52
+ { value: 'firefox_csv', label: 'Firefox (CSV)' },
53
+ { value: 'keepass_xml', label: 'KeePass (XML)' },
54
+ { value: 'dashlane_json', label: 'Dashlane (JSON)' },
55
+ ];
56
+ export const ImportDialog = ({ vaultId, open, onClose, onImportComplete, }) => {
57
+ const { t } = useBrightPassTranslation();
58
+ const brightPassApi = useBrightPassApi();
59
+ const fileInputRef = useRef(null);
60
+ const [format, setFormat] = useState('1password_1pux');
61
+ const [selectedFile, setSelectedFile] = useState(null);
62
+ const [loading, setLoading] = useState(false);
63
+ const [error, setError] = useState(null);
64
+ const [result, setResult] = useState(null);
65
+ // Reset state when dialog opens
66
+ React.useEffect(() => {
67
+ if (open) {
68
+ setFormat('1password_1pux');
69
+ setSelectedFile(null);
70
+ setLoading(false);
71
+ setError(null);
72
+ setResult(null);
73
+ if (fileInputRef.current) {
74
+ fileInputRef.current.value = '';
75
+ }
76
+ }
77
+ }, [open]);
78
+ // Reset file when format changes
79
+ const handleFormatChange = useCallback((newFormat) => {
80
+ setFormat(newFormat);
81
+ setSelectedFile(null);
82
+ setError(null);
83
+ setResult(null);
84
+ if (fileInputRef.current) {
85
+ fileInputRef.current.value = '';
86
+ }
87
+ }, []);
88
+ const handleFileChange = useCallback((event) => {
89
+ const file = event.target.files?.[0] ?? null;
90
+ setError(null);
91
+ setResult(null);
92
+ if (file) {
93
+ const accepted = getAcceptedFileTypes(format);
94
+ const fileExt = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
95
+ const extMatch = accepted.extensions.includes(fileExt);
96
+ const mimeMatch = accepted.mimeTypes.length === 0 ||
97
+ accepted.mimeTypes.includes(file.type);
98
+ if (!extMatch && !mimeMatch) {
99
+ setError(t(BrightPassStrings.Import_InvalidFormat));
100
+ setSelectedFile(null);
101
+ return;
102
+ }
103
+ }
104
+ setSelectedFile(file);
105
+ }, [format, t]);
106
+ const handleImport = useCallback(async () => {
107
+ if (!selectedFile)
108
+ return;
109
+ setLoading(true);
110
+ setError(null);
111
+ setResult(null);
112
+ try {
113
+ const arrayBuffer = await selectedFile.arrayBuffer();
114
+ const bytes = new Uint8Array(arrayBuffer);
115
+ let binary = '';
116
+ for (let i = 0; i < bytes.length; i++) {
117
+ binary += String.fromCharCode(bytes[i]);
118
+ }
119
+ const fileBase64 = btoa(binary);
120
+ const importResult = await brightPassApi.importEntries(vaultId, format, fileBase64);
121
+ setResult(importResult);
122
+ onImportComplete?.();
123
+ }
124
+ catch {
125
+ setError(t(BrightPassStrings.Import_Error));
126
+ }
127
+ finally {
128
+ setLoading(false);
129
+ }
130
+ }, [selectedFile, vaultId, format, t, onImportComplete]);
131
+ const accepted = getAcceptedFileTypes(format);
132
+ const acceptString = [
133
+ ...accepted.extensions,
134
+ ...accepted.mimeTypes,
135
+ ].join(',');
136
+ return (_jsxs(Dialog, { open: open, onClose: onClose, maxWidth: "sm", fullWidth: true, children: [_jsx(DialogTitle, { children: _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", children: [t(BrightPassStrings.Import_Title), _jsx(IconButton, { "aria-label": t(BrightPassStrings.Import_Close), onClick: onClose, size: "small", children: _jsx(CloseIcon, {}) })] }) }), _jsx(DialogContent, { children: _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2, mt: 1 }, children: [_jsx(Select, { value: format, onChange: (e) => handleFormatChange(e.target.value), fullWidth: true, size: "small", disabled: loading, "aria-label": t(BrightPassStrings.Import_SelectFormat), children: FORMAT_OPTIONS.map((opt) => (_jsx(MenuItem, { value: opt.value, children: opt.label }, opt.value))) }), _jsxs(Button, { variant: "outlined", component: "label", startIcon: _jsx(UploadFileIcon, {}), disabled: loading, children: [selectedFile ? selectedFile.name : t(BrightPassStrings.Import_Upload), _jsx("input", { ref: fileInputRef, type: "file", hidden: true, accept: acceptString, onChange: handleFileChange })] }), error && (_jsx(Alert, { severity: "error", children: error })), result && (_jsxs(Box, { children: [_jsx(Typography, { variant: "subtitle2", sx: { mb: 1 }, children: t(BrightPassStrings.Import_Summary) }), _jsx(Typography, { variant: "body2", children: t(BrightPassStrings.Import_Imported, {
137
+ COUNT: String(result.successfulImports),
138
+ }) }), _jsx(Typography, { variant: "body2", children: t(BrightPassStrings.Import_Skipped, {
139
+ COUNT: String(result.totalRecords - result.successfulImports),
140
+ }) }), result.errors.length > 0 && (_jsx(Box, { sx: { mt: 1 }, children: result.errors.map((err, idx) => (_jsx(Alert, { severity: "warning", sx: { mb: 0.5 }, children: t(BrightPassStrings.Import_Errors, {
141
+ INDEX: String(err.recordIndex),
142
+ MESSAGE: err.error,
143
+ }) }, idx))) }))] }))] }) }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: onClose, disabled: loading, children: t(BrightPassStrings.Import_Close) }), _jsx(Button, { variant: "contained", onClick: handleImport, disabled: loading || !selectedFile || result !== null, startIcon: loading ? _jsx(CircularProgress, { size: 16, color: "inherit" }) : undefined, children: t(BrightPassStrings.Import_Import) })] })] }));
144
+ };
145
+ export default ImportDialog;
146
+ //# sourceMappingURL=ImportDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImportDialog.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/dialogs/ImportDialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * ShareDialog — manages vault sharing with other BrightChain members.
4
+ *
5
+ * Provides a member search input, current share recipients list with
6
+ * "Revoke" buttons, and an "Add" action to share with searched members.
7
+ * Calls `shareVault()` and `revokeShare()` endpoints via BrightPassApiService.
8
+ *
9
+ * Requirements: 9.1, 9.2, 9.3, 9.4
10
+ */
11
+ import { BrightPassStrings } from '@brightchain/brightchain-lib';
12
+ import CloseIcon from '@mui/icons-material/Close';
13
+ import PersonAddIcon from '@mui/icons-material/PersonAdd';
14
+ import PersonRemoveIcon from '@mui/icons-material/PersonRemove';
15
+ import { Alert, Box, Button, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle, IconButton, List, ListItem, ListItemText, TextField, Typography, } from '@mui/material';
16
+ import React, { useCallback, useState } from 'react';
17
+ import { useBrightPassTranslation } from '../hooks/useBrightPassTranslation';
18
+ import { useBrightPassApi } from '../hooks/useBrightPassApi';
19
+ export const ShareDialog = ({ vaultId, open, onClose, sharedWith = [], onShareChanged, }) => {
20
+ const { t } = useBrightPassTranslation();
21
+ const brightPassApi = useBrightPassApi();
22
+ const [searchValue, setSearchValue] = useState('');
23
+ const [recipients, setRecipients] = useState(sharedWith);
24
+ const [sharing, setSharing] = useState(false);
25
+ const [revoking, setRevoking] = useState(null);
26
+ const [error, setError] = useState(null);
27
+ // Sync recipients when sharedWith prop changes (dialog re-opens)
28
+ React.useEffect(() => {
29
+ setRecipients(sharedWith);
30
+ }, [sharedWith]);
31
+ // Reset state when dialog opens
32
+ React.useEffect(() => {
33
+ if (open) {
34
+ setSearchValue('');
35
+ setError(null);
36
+ }
37
+ }, [open]);
38
+ const handleShare = useCallback(async () => {
39
+ const memberId = searchValue.trim();
40
+ if (!memberId)
41
+ return;
42
+ setSharing(true);
43
+ setError(null);
44
+ try {
45
+ await brightPassApi.shareVault(vaultId, [memberId]);
46
+ setRecipients((prev) => prev.includes(memberId) ? prev : [...prev, memberId]);
47
+ setSearchValue('');
48
+ onShareChanged?.();
49
+ }
50
+ catch {
51
+ setError(t(BrightPassStrings.Share_Error));
52
+ }
53
+ finally {
54
+ setSharing(false);
55
+ }
56
+ }, [searchValue, vaultId, t, onShareChanged]);
57
+ const handleRevoke = useCallback(async (memberId) => {
58
+ setRevoking(memberId);
59
+ setError(null);
60
+ try {
61
+ await brightPassApi.revokeShare(vaultId, memberId);
62
+ setRecipients((prev) => prev.filter((id) => id !== memberId));
63
+ onShareChanged?.();
64
+ }
65
+ catch {
66
+ setError(t(BrightPassStrings.Share_Error));
67
+ }
68
+ finally {
69
+ setRevoking(null);
70
+ }
71
+ }, [vaultId, t, onShareChanged]);
72
+ const isLoading = sharing || revoking !== null;
73
+ return (_jsxs(Dialog, { open: open, onClose: onClose, maxWidth: "sm", fullWidth: true, children: [_jsx(DialogTitle, { children: _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", children: [t(BrightPassStrings.Share_Title), _jsx(IconButton, { "aria-label": t(BrightPassStrings.Share_Close), onClick: onClose, size: "small", children: _jsx(CloseIcon, {}) })] }) }), _jsxs(DialogContent, { children: [_jsxs(Box, { sx: { display: 'flex', gap: 1, mb: 2, alignItems: 'flex-start' }, children: [_jsx(TextField, { value: searchValue, onChange: (e) => {
74
+ setSearchValue(e.target.value);
75
+ setError(null);
76
+ }, label: t(BrightPassStrings.Share_SearchMembers), size: "small", fullWidth: true, disabled: isLoading, "aria-label": t(BrightPassStrings.Share_SearchMembers), onKeyDown: (e) => {
77
+ if (e.key === 'Enter')
78
+ handleShare();
79
+ } }), _jsx(Button, { variant: "contained", onClick: handleShare, disabled: sharing || !searchValue.trim(), startIcon: sharing ? (_jsx(CircularProgress, { size: 16, color: "inherit" })) : (_jsx(PersonAddIcon, {})), sx: { whiteSpace: 'nowrap', minWidth: 'auto' }, children: t(BrightPassStrings.Share_Add) })] }), error && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: error })), _jsx(Typography, { variant: "subtitle2", sx: { mb: 1 }, children: t(BrightPassStrings.Share_CurrentRecipients) }), recipients.length === 0 ? (_jsx(Typography, { variant: "body2", color: "text.secondary", children: t(BrightPassStrings.Share_NoRecipients) })) : (_jsx(List, { dense: true, children: recipients.map((memberId) => (_jsx(ListItem, { secondaryAction: _jsx(IconButton, { edge: "end", "aria-label": t(BrightPassStrings.Share_Revoke), onClick: () => handleRevoke(memberId), disabled: revoking === memberId, color: "error", size: "small", children: revoking === memberId ? (_jsx(CircularProgress, { size: 16 })) : (_jsx(PersonRemoveIcon, {})) }), children: _jsx(ListItemText, { primary: memberId }) }, memberId))) }))] }), _jsx(DialogActions, { children: _jsx(Button, { onClick: onClose, children: t(BrightPassStrings.Share_Close) }) })] }));
80
+ };
81
+ export default ShareDialog;
82
+ //# sourceMappingURL=ShareDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShareDialog.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/dialogs/ShareDialog.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * useBrightPassApi — React hook providing a memoized BrightPassApiService
3
+ * instance backed by the shared authenticated Axios instance from
4
+ * AuthenticatedApiProvider.
5
+ */
6
+ import { useMemo } from 'react';
7
+ import { useAuthenticatedApi } from '@digitaldefiance/express-suite-react-components';
8
+ import BrightPassApiService from '../services/BrightPassApiService';
9
+ export const useBrightPassApi = () => {
10
+ const api = useAuthenticatedApi();
11
+ return useMemo(() => new BrightPassApiService(api), [api]);
12
+ };
13
+ //# sourceMappingURL=useBrightPassApi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBrightPassApi.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/hooks/useBrightPassApi.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iDAAiD,CAAC;AACtF,OAAO,oBAAoB,MAAM,kCAAkC,CAAC;AAEpE,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,EAAE;IACnC,MAAM,GAAG,GAAG,mBAAmB,EAAE,CAAC;IAClC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,oBAAoB,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AAC7D,CAAC,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * useBrightPassAutofill — React hook that accepts a site URL and returns
3
+ * matching login entries with TOTP codes via the autofill endpoint.
4
+ *
5
+ * Also exports a pure `matchSiteUrl` helper for property testing (Property 19).
6
+ *
7
+ * Requirements: 13.1, 13.3
8
+ */
9
+ import { useCallback, useEffect, useState } from 'react';
10
+ import { useBrightPassApi } from './useBrightPassApi';
11
+ /**
12
+ * Extract the hostname from a URL string, stripping protocol, port, and path.
13
+ * Returns the lowercased hostname, or the original lowercased string if parsing
14
+ * fails.
15
+ */
16
+ function extractHostname(url) {
17
+ const trimmed = url.trim();
18
+ if (trimmed.length === 0)
19
+ return '';
20
+ try {
21
+ // If the URL has no protocol, prepend one so the URL constructor works.
22
+ const withProtocol = /^https?:\/\//i.test(trimmed)
23
+ ? trimmed
24
+ : `https://${trimmed}`;
25
+ return new URL(withProtocol).hostname.toLowerCase();
26
+ }
27
+ catch {
28
+ return trimmed.toLowerCase();
29
+ }
30
+ }
31
+ /**
32
+ * Pure helper: returns `true` when `entryUrl` and `currentUrl` resolve to the
33
+ * same hostname (ignoring protocol, port, and path).
34
+ *
35
+ * Exported for property-based testing (Property 19).
36
+ */
37
+ export function matchSiteUrl(entryUrl, currentUrl) {
38
+ const entryHost = extractHostname(entryUrl);
39
+ const currentHost = extractHostname(currentUrl);
40
+ if (entryHost === '' || currentHost === '')
41
+ return false;
42
+ return entryHost === currentHost;
43
+ }
44
+ /**
45
+ * React hook that fetches autofill entries for the given `siteUrl` from all
46
+ * unlocked vaults via the BrightPass API.
47
+ *
48
+ * @param siteUrl - The URL of the site to match entries against.
49
+ * @param vaultId - The ID of the vault to query for autofill entries.
50
+ */
51
+ export function useBrightPassAutofill(siteUrl, vaultId) {
52
+ const [entries, setEntries] = useState([]);
53
+ const [loading, setLoading] = useState(false);
54
+ const [error, setError] = useState(null);
55
+ const brightPassApi = useBrightPassApi();
56
+ const fetchEntries = useCallback(async () => {
57
+ if (!siteUrl || !vaultId) {
58
+ setEntries([]);
59
+ return;
60
+ }
61
+ setLoading(true);
62
+ setError(null);
63
+ try {
64
+ const payload = await brightPassApi.getAutofill(vaultId, siteUrl);
65
+ setEntries(payload.entries);
66
+ }
67
+ catch (err) {
68
+ setError(err instanceof Error ? err : new Error(String(err.message ?? err)));
69
+ setEntries([]);
70
+ }
71
+ finally {
72
+ setLoading(false);
73
+ }
74
+ }, [siteUrl, vaultId]);
75
+ useEffect(() => {
76
+ void fetchEntries();
77
+ }, [fetchEntries]);
78
+ return { entries, loading, error };
79
+ }
80
+ //# sourceMappingURL=useBrightPassAutofill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBrightPassAutofill.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/hooks/useBrightPassAutofill.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAUtD;;;;GAIG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,wEAAwE;QACxE,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC;YAChD,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,WAAW,OAAO,EAAE,CAAC;QACzB,OAAO,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,WAAW,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,UAAkB;IAC/D,MAAM,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,SAAS,KAAK,EAAE,IAAI,WAAW,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IACzD,OAAO,SAAS,KAAK,WAAW,CAAC;AACnC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAe,EACf,OAAe;IAEf,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAkB,EAAE,CAAC,CAAC;IAC5D,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IACvD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAe,IAAI,CAAC,CAAC;IACvD,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IAEzC,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC1C,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;YACzB,UAAU,CAAC,EAAE,CAAC,CAAC;YACf,OAAO;QACT,CAAC;QAED,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QAEf,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAClE,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CACN,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAE,GAA+B,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAChG,CAAC;YACF,UAAU,CAAC,EAAE,CAAC,CAAC;QACjB,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,YAAY,EAAE,CAAC;IACtB,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * useBrightPassExtensionBridge — React hook exposing BrightPass capabilities
3
+ * to a browser extension via `window.postMessage` and direct method calls.
4
+ *
5
+ * On mount:
6
+ * - Dispatches a `BRIGHTPASS_READY` CustomEvent on `window`
7
+ * - Registers a `message` listener that handles `BRIGHTPASS_AUTOFILL_REQUEST`
8
+ * messages after validating the sender's origin against a configurable
9
+ * allowlist.
10
+ *
11
+ * Also exports a pure `isAllowedOrigin` helper for property testing (Property 20).
12
+ *
13
+ * Requirements: 13.2, 13.4, 13.5, 13.6
14
+ */
15
+ import { useCallback, useEffect, useMemo } from 'react';
16
+ import { useBrightPassApi } from './useBrightPassApi';
17
+ /** Default origin allowlist — empty by default (no origins allowed). */
18
+ const DEFAULT_ALLOWED_ORIGINS = [];
19
+ /**
20
+ * Pure helper: returns `true` when `origin` is present in the `allowlist`.
21
+ *
22
+ * Matching rules:
23
+ * - Exact string match (case-insensitive).
24
+ * - Wildcard pattern: a leading `*.` in the allowlist entry matches any
25
+ * subdomain. For example `https://*.example.com` matches
26
+ * `https://app.example.com` and `https://sub.app.example.com`.
27
+ *
28
+ * Exported for property-based testing (Property 20).
29
+ */
30
+ export function isAllowedOrigin(origin, allowlist) {
31
+ const lowerOrigin = origin.toLowerCase();
32
+ for (const entry of allowlist) {
33
+ const lowerEntry = entry.toLowerCase();
34
+ // Exact match
35
+ if (lowerOrigin === lowerEntry)
36
+ return true;
37
+ // Wildcard pattern: entry contains `*`
38
+ if (lowerEntry.includes('*')) {
39
+ // Convert the wildcard pattern to a regex:
40
+ // - Escape regex-special chars except `*`
41
+ // - Replace `*` with `[^/]*` (match any chars except slash)
42
+ const escaped = lowerEntry.replace(/([.+?^${}()|[\]\\])/g, '\\$1');
43
+ const pattern = escaped.replace(/\*/g, '[^/]*');
44
+ const re = new RegExp(`^${pattern}$`);
45
+ if (re.test(lowerOrigin))
46
+ return true;
47
+ }
48
+ }
49
+ return false;
50
+ }
51
+ /**
52
+ * React hook that bridges BrightPass functionality to a browser extension.
53
+ */
54
+ export function useBrightPassExtensionBridge(options = {}) {
55
+ const allowedOrigins = options.allowedOrigins ?? DEFAULT_ALLOWED_ORIGINS;
56
+ const brightPassApi = useBrightPassApi();
57
+ // ── Exposed methods ─────────────────────────────────────────────────
58
+ const getVaults = useCallback(async () => {
59
+ return brightPassApi.listVaults();
60
+ }, [brightPassApi]);
61
+ const searchEntries = useCallback(async (vaultId, query) => {
62
+ return brightPassApi.searchEntries(vaultId, { text: query });
63
+ }, [brightPassApi]);
64
+ const generatePassword = useCallback(async (opts) => {
65
+ return brightPassApi.generatePassword(opts);
66
+ }, [brightPassApi]);
67
+ const checkBreach = useCallback(async (password) => {
68
+ return brightPassApi.checkBreach(password);
69
+ }, [brightPassApi]);
70
+ // Memoize the allowlist to keep the effect dependency stable when the
71
+ // caller passes a literal array.
72
+ const memoizedAllowlist = useMemo(() => allowedOrigins,
73
+ // eslint-disable-next-line react-hooks/exhaustive-deps
74
+ [JSON.stringify(allowedOrigins)]);
75
+ // ── Lifecycle: BRIGHTPASS_READY + message listener ──────────────────
76
+ useEffect(() => {
77
+ // Signal to extensions that BrightPass is available.
78
+ window.dispatchEvent(new CustomEvent('BRIGHTPASS_READY'));
79
+ const handleMessage = async (event) => {
80
+ // Validate origin
81
+ if (!isAllowedOrigin(event.origin, memoizedAllowlist))
82
+ return;
83
+ const data = event.data;
84
+ if (!data || data.type !== 'BRIGHTPASS_AUTOFILL_REQUEST')
85
+ return;
86
+ const siteUrl = data.siteUrl;
87
+ const vaultId = data.vaultId;
88
+ if (!siteUrl || !vaultId)
89
+ return;
90
+ try {
91
+ const payload = await brightPassApi.getAutofill(vaultId, siteUrl);
92
+ event.source?.postMessage({ type: 'BRIGHTPASS_AUTOFILL_RESPONSE', payload }, { targetOrigin: event.origin });
93
+ }
94
+ catch (err) {
95
+ event.source?.postMessage({
96
+ type: 'BRIGHTPASS_AUTOFILL_ERROR',
97
+ error: err instanceof Error ? err.message : String(err),
98
+ }, { targetOrigin: event.origin });
99
+ }
100
+ };
101
+ window.addEventListener('message', handleMessage);
102
+ return () => {
103
+ window.removeEventListener('message', handleMessage);
104
+ };
105
+ }, [memoizedAllowlist, brightPassApi]);
106
+ return { getVaults, searchEntries, generatePassword, checkBreach };
107
+ }
108
+ //# sourceMappingURL=useBrightPassExtensionBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBrightPassExtensionBridge.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/hooks/useBrightPassExtensionBridge.ts"],"names":[],"mappings":"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"}