@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.
- package/README.md +28 -0
- package/package.json +42 -0
- package/src/index.js +35 -0
- package/src/index.js.map +1 -0
- package/src/lib/BrightPassRoutes.js +33 -0
- package/src/lib/BrightPassRoutes.js.map +1 -0
- package/src/lib/components/BreadcrumbNav.js +70 -0
- package/src/lib/components/BreadcrumbNav.js.map +1 -0
- package/src/lib/components/CreateVaultDialog.js +57 -0
- package/src/lib/components/CreateVaultDialog.js.map +1 -0
- package/src/lib/components/EntryDetailView.js +167 -0
- package/src/lib/components/EntryDetailView.js.map +1 -0
- package/src/lib/components/EntryForm.js +196 -0
- package/src/lib/components/EntryForm.js.map +1 -0
- package/src/lib/components/MasterPasswordPrompt.js +56 -0
- package/src/lib/components/MasterPasswordPrompt.js.map +1 -0
- package/src/lib/components/SearchBar.js +137 -0
- package/src/lib/components/SearchBar.js.map +1 -0
- package/src/lib/context/BrightPassProvider.js +158 -0
- package/src/lib/context/BrightPassProvider.js.map +1 -0
- package/src/lib/dialogs/EmergencyAccessDialog.js +139 -0
- package/src/lib/dialogs/EmergencyAccessDialog.js.map +1 -0
- package/src/lib/dialogs/ImportDialog.js +146 -0
- package/src/lib/dialogs/ImportDialog.js.map +1 -0
- package/src/lib/dialogs/ShareDialog.js +82 -0
- package/src/lib/dialogs/ShareDialog.js.map +1 -0
- package/src/lib/hooks/useBrightPassApi.js +13 -0
- package/src/lib/hooks/useBrightPassApi.js.map +1 -0
- package/src/lib/hooks/useBrightPassAutofill.js +80 -0
- package/src/lib/hooks/useBrightPassAutofill.js.map +1 -0
- package/src/lib/hooks/useBrightPassExtensionBridge.js +108 -0
- package/src/lib/hooks/useBrightPassExtensionBridge.js.map +1 -0
- package/src/lib/hooks/useBrightPassTranslation.js +12 -0
- package/src/lib/hooks/useBrightPassTranslation.js.map +1 -0
- package/src/lib/services/BrightPassApiService.js +219 -0
- package/src/lib/services/BrightPassApiService.js.map +1 -0
- package/src/lib/views/AuditLogView.js +120 -0
- package/src/lib/views/AuditLogView.js.map +1 -0
- package/src/lib/views/PasswordGeneratorPage.js +20 -0
- package/src/lib/views/PasswordGeneratorPage.js.map +1 -0
- package/src/lib/views/VaultDetailView.js +93 -0
- package/src/lib/views/VaultDetailView.js.map +1 -0
- package/src/lib/views/VaultListView.js +99 -0
- package/src/lib/views/VaultListView.js.map +1 -0
- package/src/lib/widgets/BreachCheckWidget.js +57 -0
- package/src/lib/widgets/BreachCheckWidget.js.map +1 -0
- package/src/lib/widgets/PasswordGeneratorWidget.js +137 -0
- package/src/lib/widgets/PasswordGeneratorWidget.js.map +1 -0
- package/src/lib/widgets/TOTPWidget.js +165 -0
- package/src/lib/widgets/TOTPWidget.js.map +1 -0
- package/src/test-setup.js +13 -0
- package/src/test-setup.js.map +1 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BrightPassComponentId, getBrightChainI18nEngine, } from '@brightchain/brightchain-lib';
|
|
2
|
+
/**
|
|
3
|
+
* Hook that wraps the i18n engine for BrightPass components.
|
|
4
|
+
* Returns a `t` function scoped to the BrightPass component package.
|
|
5
|
+
*/
|
|
6
|
+
export function useBrightPassTranslation() {
|
|
7
|
+
const engine = getBrightChainI18nEngine();
|
|
8
|
+
return {
|
|
9
|
+
t: (key, vars) => engine.translate(BrightPassComponentId, key, vars),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=useBrightPassTranslation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBrightPassTranslation.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/hooks/useBrightPassTranslation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AAGtC;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,MAAM,MAAM,GAAG,wBAAwB,EAAE,CAAC;IAC1C,OAAO;QACL,CAAC,EAAE,CAAC,GAAwB,EAAE,IAA6B,EAAE,EAAE,CAC7D,MAAM,CAAC,SAAS,CAAC,qBAAqB,EAAE,GAAG,EAAE,IAAI,CAAC;KACrD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BrightPassApiService — typed service wrapping all 20 BrightPass REST API
|
|
3
|
+
* endpoints.
|
|
4
|
+
*
|
|
5
|
+
* Uses the existing `authenticatedApi` axios instance for all requests.
|
|
6
|
+
* Extracts the `data` payload from success responses and throws
|
|
7
|
+
* `IBrightPassError` on error responses. On 401, the existing axios
|
|
8
|
+
* interceptor handles the logout flow.
|
|
9
|
+
*
|
|
10
|
+
* Requirements: 2.1, 2.2, 2.3, 2.4, 2.6
|
|
11
|
+
*/
|
|
12
|
+
import { isAxiosError } from 'axios';
|
|
13
|
+
function extractData(responseData) {
|
|
14
|
+
return responseData.data;
|
|
15
|
+
}
|
|
16
|
+
function throwBrightPassError(error) {
|
|
17
|
+
if (isAxiosError(error) && error.response) {
|
|
18
|
+
const body = error.response.data;
|
|
19
|
+
const bpError = {
|
|
20
|
+
code: body?.code ?? `HTTP_${error.response.status}`,
|
|
21
|
+
message: body?.message ??
|
|
22
|
+
body?.error ??
|
|
23
|
+
error.message,
|
|
24
|
+
details: body?.details ?? undefined,
|
|
25
|
+
};
|
|
26
|
+
throw bpError;
|
|
27
|
+
}
|
|
28
|
+
const bpError = {
|
|
29
|
+
code: 'NETWORK_ERROR',
|
|
30
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
31
|
+
};
|
|
32
|
+
throw bpError;
|
|
33
|
+
}
|
|
34
|
+
const BASE = '/brightpass';
|
|
35
|
+
class BrightPassApiService {
|
|
36
|
+
constructor(api) {
|
|
37
|
+
this.api = api;
|
|
38
|
+
}
|
|
39
|
+
async createVault(name, masterPassword) {
|
|
40
|
+
try {
|
|
41
|
+
const res = await this.api.post(`${BASE}/vaults`, { name, masterPassword });
|
|
42
|
+
return extractData(res.data).vault;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
throwBrightPassError(error);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async listVaults() {
|
|
49
|
+
try {
|
|
50
|
+
const res = await this.api.get(`${BASE}/vaults`);
|
|
51
|
+
return extractData(res.data).vaults;
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
throwBrightPassError(error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async openVault(vaultId, masterPassword) {
|
|
58
|
+
try {
|
|
59
|
+
const res = await this.api.post(`${BASE}/vaults/${encodeURIComponent(vaultId)}/open`, {
|
|
60
|
+
masterPassword,
|
|
61
|
+
});
|
|
62
|
+
return extractData(res.data).vault;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
throwBrightPassError(error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async deleteVault(vaultId, masterPassword) {
|
|
69
|
+
try {
|
|
70
|
+
await this.api.delete(`${BASE}/vaults/${encodeURIComponent(vaultId)}`, { data: { masterPassword } });
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
throwBrightPassError(error);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async createEntry(vaultId, entry) {
|
|
77
|
+
try {
|
|
78
|
+
const res = await this.api.post(`${BASE}/vaults/${encodeURIComponent(vaultId)}/entries`, entry);
|
|
79
|
+
return extractData(res.data).entry;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
throwBrightPassError(error);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async getEntry(vaultId, entryId) {
|
|
86
|
+
try {
|
|
87
|
+
const res = await this.api.get(`${BASE}/vaults/${encodeURIComponent(vaultId)}/entries/${encodeURIComponent(entryId)}`);
|
|
88
|
+
return extractData(res.data).entry;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
throwBrightPassError(error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async updateEntry(vaultId, entryId, entry) {
|
|
95
|
+
try {
|
|
96
|
+
const res = await this.api.put(`${BASE}/vaults/${encodeURIComponent(vaultId)}/entries/${encodeURIComponent(entryId)}`, entry);
|
|
97
|
+
return extractData(res.data).entry;
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
throwBrightPassError(error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async deleteEntry(vaultId, entryId) {
|
|
104
|
+
try {
|
|
105
|
+
await this.api.delete(`${BASE}/vaults/${encodeURIComponent(vaultId)}/entries/${encodeURIComponent(entryId)}`);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
throwBrightPassError(error);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async searchEntries(vaultId, query) {
|
|
112
|
+
try {
|
|
113
|
+
const res = await this.api.post(`${BASE}/vaults/${encodeURIComponent(vaultId)}/search`, query);
|
|
114
|
+
return extractData(res.data).results;
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
throwBrightPassError(error);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async generatePassword(options) {
|
|
121
|
+
try {
|
|
122
|
+
const res = await this.api.post(`${BASE}/generate-password`, options);
|
|
123
|
+
return extractData(res.data).password;
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
throwBrightPassError(error);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async generateTotp(secret) {
|
|
130
|
+
try {
|
|
131
|
+
const res = await this.api.post(`${BASE}/totp/generate`, { secret });
|
|
132
|
+
return extractData(res.data).code;
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
throwBrightPassError(error);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async validateTotp(secret, code) {
|
|
139
|
+
try {
|
|
140
|
+
const res = await this.api.post(`${BASE}/totp/validate`, { secret, code });
|
|
141
|
+
const data = extractData(res.data);
|
|
142
|
+
return { valid: data.valid };
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
throwBrightPassError(error);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async checkBreach(password) {
|
|
149
|
+
try {
|
|
150
|
+
const res = await this.api.post(`${BASE}/breach-check`, { password });
|
|
151
|
+
return extractData(res.data);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
throwBrightPassError(error);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async getAutofill(vaultId, siteUrl) {
|
|
158
|
+
try {
|
|
159
|
+
const res = await this.api.post(`${BASE}/vaults/${encodeURIComponent(vaultId)}/autofill`, { siteUrl });
|
|
160
|
+
return extractData(res.data);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
throwBrightPassError(error);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async getAuditLog(vaultId) {
|
|
167
|
+
try {
|
|
168
|
+
const res = await this.api.get(`${BASE}/vaults/${encodeURIComponent(vaultId)}/audit-log`);
|
|
169
|
+
return extractData(res.data).entries;
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
throwBrightPassError(error);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
async shareVault(vaultId, memberIds) {
|
|
176
|
+
try {
|
|
177
|
+
await this.api.post(`${BASE}/vaults/${encodeURIComponent(vaultId)}/share`, { recipientMemberIds: memberIds });
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
throwBrightPassError(error);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async revokeShare(vaultId, memberId) {
|
|
184
|
+
try {
|
|
185
|
+
await this.api.post(`${BASE}/vaults/${encodeURIComponent(vaultId)}/revoke-share`, { memberId });
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
throwBrightPassError(error);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async configureEmergencyAccess(vaultId, config) {
|
|
192
|
+
try {
|
|
193
|
+
await this.api.post(`${BASE}/vaults/${encodeURIComponent(vaultId)}/emergency-access`, { threshold: config.threshold, trustees: config.trustees });
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
throwBrightPassError(error);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async recoverWithShares(vaultId, shares) {
|
|
200
|
+
try {
|
|
201
|
+
const res = await this.api.post(`${BASE}/vaults/${encodeURIComponent(vaultId)}/emergency-recover`, { shares });
|
|
202
|
+
return extractData(res.data).vault;
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
throwBrightPassError(error);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
async importEntries(vaultId, format, fileBase64) {
|
|
209
|
+
try {
|
|
210
|
+
const res = await this.api.post(`${BASE}/vaults/${encodeURIComponent(vaultId)}/import`, { format, fileContent: fileBase64 });
|
|
211
|
+
return extractData(res.data);
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
throwBrightPassError(error);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
export default BrightPassApiService;
|
|
219
|
+
//# sourceMappingURL=BrightPassApiService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrightPassApiService.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/services/BrightPassApiService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* AuditLogView — Displays the append-only audit trail for a vault.
|
|
4
|
+
*
|
|
5
|
+
* - Fetches and displays audit log entries (timestamp, action type, member ID)
|
|
6
|
+
* - Filters by action type
|
|
7
|
+
* - Displays in reverse chronological order (newest first)
|
|
8
|
+
* - All strings via useBrightPassTranslation()
|
|
9
|
+
*
|
|
10
|
+
* Requirements: 12.1, 12.2, 12.3, 12.4
|
|
11
|
+
*/
|
|
12
|
+
import { AuditAction, BrightPassStrings } from '@brightchain/brightchain-lib';
|
|
13
|
+
import FilterListIcon from '@mui/icons-material/FilterList';
|
|
14
|
+
import { Alert, Box, Container, FormControl, InputLabel, MenuItem, Select, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Typography, } from '@mui/material';
|
|
15
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
16
|
+
import { useParams } from 'react-router-dom';
|
|
17
|
+
import BreadcrumbNav from '../components/BreadcrumbNav';
|
|
18
|
+
import { useBrightPassTranslation } from '../hooks/useBrightPassTranslation';
|
|
19
|
+
import { useBrightPassApi } from '../hooks/useBrightPassApi';
|
|
20
|
+
/** All filterable action types. */
|
|
21
|
+
const AUDIT_ACTION_VALUES = Object.values(AuditAction);
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Pure helper functions (exported for property-based testing)
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/**
|
|
26
|
+
* Sorts audit entries in reverse chronological order (newest first).
|
|
27
|
+
*
|
|
28
|
+
* Property 18: For all adjacent pairs (entry[i], entry[i+1]),
|
|
29
|
+
* entry[i].timestamp >= entry[i+1].timestamp.
|
|
30
|
+
*/
|
|
31
|
+
export function sortAuditEntries(entries) {
|
|
32
|
+
return [...entries].sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Filters audit entries by action type. Returns all entries when
|
|
36
|
+
* actionType is null or empty string.
|
|
37
|
+
*
|
|
38
|
+
* Property 17: The filtered result contains exactly those entries
|
|
39
|
+
* whose actionType matches the selected filter.
|
|
40
|
+
*/
|
|
41
|
+
export function filterAuditEntries(entries, actionType) {
|
|
42
|
+
if (!actionType)
|
|
43
|
+
return entries;
|
|
44
|
+
return entries.filter((e) => e.actionType === actionType);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Formats an audit entry for display: ISO timestamp → locale string,
|
|
48
|
+
* action type as-is label.
|
|
49
|
+
*
|
|
50
|
+
* Property 16: The rendered row contains a formatted timestamp,
|
|
51
|
+
* the action type string, and the member ID.
|
|
52
|
+
*/
|
|
53
|
+
export function formatAuditEntry(entry) {
|
|
54
|
+
const d = new Date(entry.timestamp);
|
|
55
|
+
return {
|
|
56
|
+
formattedTimestamp: d.toLocaleString(),
|
|
57
|
+
actionLabel: entry.actionType,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Helpers
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
/** Maps an API AuditLogEntry to the view-layer AuditEntry. */
|
|
64
|
+
function toAuditEntry(entry) {
|
|
65
|
+
const ts = entry.timestamp instanceof Date
|
|
66
|
+
? entry.timestamp.toISOString()
|
|
67
|
+
: String(entry.timestamp);
|
|
68
|
+
return {
|
|
69
|
+
id: entry.id,
|
|
70
|
+
timestamp: ts,
|
|
71
|
+
actionType: entry.action,
|
|
72
|
+
memberId: entry.memberId,
|
|
73
|
+
details: entry.metadata
|
|
74
|
+
? Object.entries(entry.metadata)
|
|
75
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
76
|
+
.join(', ')
|
|
77
|
+
: undefined,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Component
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
const AuditLogView = () => {
|
|
84
|
+
const { t } = useBrightPassTranslation();
|
|
85
|
+
const brightPassApi = useBrightPassApi();
|
|
86
|
+
const { vaultId } = useParams();
|
|
87
|
+
const [entries, setEntries] = useState([]);
|
|
88
|
+
const [loading, setLoading] = useState(true);
|
|
89
|
+
const [error, setError] = useState(null);
|
|
90
|
+
const [actionFilter, setActionFilter] = useState('');
|
|
91
|
+
const fetchAuditLog = useCallback(async () => {
|
|
92
|
+
if (!vaultId)
|
|
93
|
+
return;
|
|
94
|
+
setLoading(true);
|
|
95
|
+
setError(null);
|
|
96
|
+
try {
|
|
97
|
+
const raw = await brightPassApi.getAuditLog(vaultId);
|
|
98
|
+
setEntries(raw.map(toAuditEntry));
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
setError(t(BrightPassStrings.AuditLog_Error));
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
setLoading(false);
|
|
105
|
+
}
|
|
106
|
+
}, [vaultId, t]);
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
fetchAuditLog();
|
|
109
|
+
}, [fetchAuditLog]);
|
|
110
|
+
const handleFilterChange = (event) => {
|
|
111
|
+
setActionFilter(event.target.value);
|
|
112
|
+
};
|
|
113
|
+
const displayed = sortAuditEntries(filterAuditEntries(entries, actionFilter || null));
|
|
114
|
+
return (_jsxs(Container, { maxWidth: "md", sx: { mt: 4 }, children: [_jsx(BreadcrumbNav, {}), _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2, children: [_jsx(Typography, { variant: "h4", component: "h1", children: t(BrightPassStrings.AuditLog_Title) }), _jsxs(FormControl, { size: "small", sx: { minWidth: 220 }, children: [_jsxs(InputLabel, { id: "audit-action-filter-label", children: [_jsx(FilterListIcon, { fontSize: "small", sx: { mr: 0.5, verticalAlign: 'middle' } }), t(BrightPassStrings.AuditLog_Action)] }), _jsxs(Select, { labelId: "audit-action-filter-label", id: "audit-action-filter", value: actionFilter, label: t(BrightPassStrings.AuditLog_Action), onChange: handleFilterChange, children: [_jsx(MenuItem, { value: "", children: t(BrightPassStrings.AuditLog_FilterAll) }), AUDIT_ACTION_VALUES.map((action) => (_jsx(MenuItem, { value: action, children: action }, action)))] })] })] }), error && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: error })), !loading && displayed.length === 0 && !error && (_jsx(Typography, { color: "text.secondary", sx: { mt: 4, textAlign: 'center' }, children: t(BrightPassStrings.AuditLog_NoEntries) })), displayed.length > 0 && (_jsx(TableContainer, { children: _jsxs(Table, { size: "small", "aria-label": t(BrightPassStrings.AuditLog_Title), children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableCell, { children: t(BrightPassStrings.AuditLog_Timestamp) }), _jsx(TableCell, { children: t(BrightPassStrings.AuditLog_Action) }), _jsx(TableCell, { children: t(BrightPassStrings.AuditLog_Member) })] }) }), _jsx(TableBody, { children: displayed.map((entry) => {
|
|
115
|
+
const { formattedTimestamp, actionLabel } = formatAuditEntry(entry);
|
|
116
|
+
return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: formattedTimestamp }), _jsx(TableCell, { children: actionLabel }), _jsx(TableCell, { children: entry.memberId })] }, entry.id));
|
|
117
|
+
}) })] }) }))] }));
|
|
118
|
+
};
|
|
119
|
+
export default AuditLogView;
|
|
120
|
+
//# sourceMappingURL=AuditLogView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuditLogView.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/views/AuditLogView.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAE9E,OAAO,cAAc,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EACL,KAAK,EACL,GAAG,EACH,SAAS,EACT,WAAW,EACX,UAAU,EACV,QAAQ,EACR,MAAM,EACN,KAAK,EACL,SAAS,EACT,SAAS,EACT,cAAc,EACd,SAAS,EACT,QAAQ,EACR,UAAU,GACX,MAAM,eAAe,CAAC;AAEvB,OAAc,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,aAAa,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAc7D,mCAAmC;AACnC,MAAM,mBAAmB,GAAa,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEjE,8EAA8E;AAC9E,8DAA8D;AAC9D,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAqB;IACpD,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CACtB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAC5E,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAqB,EACrB,UAAyB;IAEzB,IAAI,CAAC,UAAU;QAAE,OAAO,OAAO,CAAC;IAChC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;AAC5D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IAIhD,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACpC,OAAO;QACL,kBAAkB,EAAE,CAAC,CAAC,cAAc,EAAE;QACtC,WAAW,EAAE,KAAK,CAAC,UAAU;KAC9B,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,8DAA8D;AAC9D,SAAS,YAAY,CAAC,KAAoB;IACxC,MAAM,EAAE,GACN,KAAK,CAAC,SAAS,YAAY,IAAI;QAC7B,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,WAAW,EAAE;QAC/B,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC9B,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,KAAK,CAAC,MAAM;QACxB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,KAAK,CAAC,QAAQ;YACrB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;iBAC3B,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;iBAC5B,IAAI,CAAC,IAAI,CAAC;YACf,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,YAAY,GAAa,GAAG,EAAE;IAClC,MAAM,EAAE,CAAC,EAAE,GAAG,wBAAwB,EAAE,CAAC;IACzC,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IACzC,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,EAAuB,CAAC;IAErD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAe,EAAE,CAAC,CAAC;IACzD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IAE7D,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC3C,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YACrD,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC,CAAC;QAChD,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IAEjB,SAAS,CAAC,GAAG,EAAE;QACb,aAAa,EAAE,CAAC;IAClB,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,MAAM,kBAAkB,GAAG,CAAC,KAAgC,EAAE,EAAE;QAC9D,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,gBAAgB,CAAC,kBAAkB,CAAC,OAAO,EAAE,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC;IAEtF,OAAO,CACL,MAAC,SAAS,IAAC,QAAQ,EAAC,IAAI,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,aACpC,KAAC,aAAa,KAAG,EAEjB,MAAC,GAAG,IAAC,OAAO,EAAC,MAAM,EAAC,cAAc,EAAC,eAAe,EAAC,UAAU,EAAC,QAAQ,EAAC,EAAE,EAAE,CAAC,aAC1E,KAAC,UAAU,IAAC,OAAO,EAAC,IAAI,EAAC,SAAS,EAAC,IAAI,YACpC,CAAC,CAAC,iBAAiB,CAAC,cAAc,CAAC,GACzB,EAEb,MAAC,WAAW,IAAC,IAAI,EAAC,OAAO,EAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,aAC7C,MAAC,UAAU,IAAC,EAAE,EAAC,2BAA2B,aACxC,KAAC,cAAc,IAAC,QAAQ,EAAC,OAAO,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,GAAI,EAC5E,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAC1B,EACb,MAAC,MAAM,IACL,OAAO,EAAC,2BAA2B,EACnC,EAAE,EAAC,qBAAqB,EACxB,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC,EAC3C,QAAQ,EAAE,kBAAkB,aAE5B,KAAC,QAAQ,IAAC,KAAK,EAAC,EAAE,YAAE,CAAC,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,GAAY,EACtE,mBAAmB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CACnC,KAAC,QAAQ,IAAc,KAAK,EAAE,MAAM,YACjC,MAAM,IADM,MAAM,CAEV,CACZ,CAAC,IACK,IACG,IACV,EAEL,KAAK,IAAI,CACR,KAAC,KAAK,IAAC,QAAQ,EAAC,OAAO,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,YAClC,KAAK,GACA,CACT,EAEA,CAAC,OAAO,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAC/C,KAAC,UAAU,IAAC,KAAK,EAAC,gBAAgB,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,YAClE,CAAC,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,GAC7B,CACd,EAEA,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CACvB,KAAC,cAAc,cACb,MAAC,KAAK,IAAC,IAAI,EAAC,OAAO,gBAAa,CAAC,CAAC,iBAAiB,CAAC,cAAc,CAAC,aACjE,KAAC,SAAS,cACR,MAAC,QAAQ,eACP,KAAC,SAAS,cAAE,CAAC,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,GAAa,EAChE,KAAC,SAAS,cAAE,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC,GAAa,EAC7D,KAAC,SAAS,cAAE,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC,GAAa,IACpD,GACD,EACZ,KAAC,SAAS,cACP,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gCACvB,MAAM,EAAE,kBAAkB,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;gCACpE,OAAO,CACL,MAAC,QAAQ,eACP,KAAC,SAAS,cAAE,kBAAkB,GAAa,EAC3C,KAAC,SAAS,cAAE,WAAW,GAAa,EACpC,KAAC,SAAS,cAAE,KAAK,CAAC,QAAQ,GAAa,KAH1B,KAAK,CAAC,EAAE,CAIZ,CACZ,CAAC;4BACJ,CAAC,CAAC,GACQ,IACN,GACO,CAClB,IACS,CACb,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* PasswordGeneratorPage — Standalone password generator page.
|
|
4
|
+
*
|
|
5
|
+
* Wraps PasswordGeneratorWidget in a page layout with BreadcrumbNav.
|
|
6
|
+
* Accessible from `/brightpass/tools/generator`.
|
|
7
|
+
*
|
|
8
|
+
* Requirements: 6.6
|
|
9
|
+
*/
|
|
10
|
+
import { BrightPassStrings } from '@brightchain/brightchain-lib';
|
|
11
|
+
import { Container, Typography } from '@mui/material';
|
|
12
|
+
import BreadcrumbNav from '../components/BreadcrumbNav';
|
|
13
|
+
import { useBrightPassTranslation } from '../hooks/useBrightPassTranslation';
|
|
14
|
+
import PasswordGeneratorWidget from '../widgets/PasswordGeneratorWidget';
|
|
15
|
+
const PasswordGeneratorPage = () => {
|
|
16
|
+
const { t } = useBrightPassTranslation();
|
|
17
|
+
return (_jsxs(Container, { maxWidth: "md", sx: { mt: 4 }, children: [_jsx(BreadcrumbNav, {}), _jsx(Typography, { variant: "h4", component: "h1", sx: { mb: 3 }, children: t(BrightPassStrings.PasswordGen_Title) }), _jsx(PasswordGeneratorWidget, {})] }));
|
|
18
|
+
};
|
|
19
|
+
export default PasswordGeneratorPage;
|
|
20
|
+
//# sourceMappingURL=PasswordGeneratorPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PasswordGeneratorPage.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/views/PasswordGeneratorPage.tsx"],"names":[],"mappings":";AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEtD,OAAO,aAAa,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,uBAAuB,MAAM,oCAAoC,CAAC;AAEzE,MAAM,qBAAqB,GAAa,GAAG,EAAE;IAC3C,MAAM,EAAE,CAAC,EAAE,GAAG,wBAAwB,EAAE,CAAC;IAEzC,OAAO,CACL,MAAC,SAAS,IAAC,QAAQ,EAAC,IAAI,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,aACpC,KAAC,aAAa,KAAG,EACjB,KAAC,UAAU,IAAC,OAAO,EAAC,IAAI,EAAC,SAAS,EAAC,IAAI,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,YAClD,CAAC,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,GAC5B,EACb,KAAC,uBAAuB,KAAG,IACjB,CACb,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { BrightPassStrings, } from '@brightchain/brightchain-lib';
|
|
3
|
+
import AddIcon from '@mui/icons-material/Add';
|
|
4
|
+
import BadgeIcon from '@mui/icons-material/Badge';
|
|
5
|
+
import CreditCardIcon from '@mui/icons-material/CreditCard';
|
|
6
|
+
import LockIcon from '@mui/icons-material/Lock';
|
|
7
|
+
import NoteIcon from '@mui/icons-material/Note';
|
|
8
|
+
import StarIcon from '@mui/icons-material/Star';
|
|
9
|
+
import VpnKeyIcon from '@mui/icons-material/VpnKey';
|
|
10
|
+
import { Alert, Box, Button, Chip, Container, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, List, ListItem, ListItemButton, ListItemIcon, ListItemText, TextField, Tooltip, Typography, } from '@mui/material';
|
|
11
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
12
|
+
import { useNavigate, useParams } from 'react-router-dom';
|
|
13
|
+
import BreadcrumbNav from '../components/BreadcrumbNav';
|
|
14
|
+
import MasterPasswordPrompt from '../components/MasterPasswordPrompt';
|
|
15
|
+
import { useBrightPass } from '../context/BrightPassProvider';
|
|
16
|
+
import { useBrightPassTranslation } from '../hooks/useBrightPassTranslation';
|
|
17
|
+
/** Maps entry types to their corresponding MUI icon. */
|
|
18
|
+
function entryTypeIcon(entryType) {
|
|
19
|
+
switch (entryType) {
|
|
20
|
+
case 'login':
|
|
21
|
+
return _jsx(VpnKeyIcon, {});
|
|
22
|
+
case 'secure_note':
|
|
23
|
+
return _jsx(NoteIcon, {});
|
|
24
|
+
case 'credit_card':
|
|
25
|
+
return _jsx(CreditCardIcon, {});
|
|
26
|
+
case 'identity':
|
|
27
|
+
return _jsx(BadgeIcon, {});
|
|
28
|
+
default:
|
|
29
|
+
return _jsx(VpnKeyIcon, {});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** Maps entry types to their i18n string key. */
|
|
33
|
+
function entryTypeLabel(entryType, t) {
|
|
34
|
+
switch (entryType) {
|
|
35
|
+
case 'login':
|
|
36
|
+
return t(BrightPassStrings.EntryType_Login);
|
|
37
|
+
case 'secure_note':
|
|
38
|
+
return t(BrightPassStrings.EntryType_SecureNote);
|
|
39
|
+
case 'credit_card':
|
|
40
|
+
return t(BrightPassStrings.EntryType_CreditCard);
|
|
41
|
+
case 'identity':
|
|
42
|
+
return t(BrightPassStrings.EntryType_Identity);
|
|
43
|
+
default:
|
|
44
|
+
return entryType;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const VaultDetailView = () => {
|
|
48
|
+
const { vaultId } = useParams();
|
|
49
|
+
const { t } = useBrightPassTranslation();
|
|
50
|
+
const { vault, lockVault, isVaultUnlocked } = useBrightPass();
|
|
51
|
+
const navigate = useNavigate();
|
|
52
|
+
const [_showAddEntry, setShowAddEntry] = useState(false);
|
|
53
|
+
const [showLockConfirm, setShowLockConfirm] = useState(false);
|
|
54
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
55
|
+
const [error, _setError] = useState(null);
|
|
56
|
+
// --- Lock vault and navigate back ---
|
|
57
|
+
const handleLockVault = useCallback(() => {
|
|
58
|
+
lockVault();
|
|
59
|
+
navigate('/brightpass');
|
|
60
|
+
}, [lockVault, navigate]);
|
|
61
|
+
// --- Prompt to lock on browser close / tab navigation ---
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!isVaultUnlocked())
|
|
64
|
+
return;
|
|
65
|
+
const handleBeforeUnload = (e) => {
|
|
66
|
+
e.preventDefault();
|
|
67
|
+
};
|
|
68
|
+
window.addEventListener('beforeunload', handleBeforeUnload);
|
|
69
|
+
return () => {
|
|
70
|
+
window.removeEventListener('beforeunload', handleBeforeUnload);
|
|
71
|
+
};
|
|
72
|
+
}, [isVaultUnlocked]);
|
|
73
|
+
// --- Filter entries by search query ---
|
|
74
|
+
const filteredEntries = vault?.propertyRecords
|
|
75
|
+
? vault.propertyRecords.filter((entry) => {
|
|
76
|
+
if (!searchQuery.trim())
|
|
77
|
+
return true;
|
|
78
|
+
const query = searchQuery.toLowerCase();
|
|
79
|
+
return (entry.title.toLowerCase().includes(query) ||
|
|
80
|
+
entry.tags.some((tag) => tag.toLowerCase().includes(query)) ||
|
|
81
|
+
entry.siteUrl.toLowerCase().includes(query));
|
|
82
|
+
})
|
|
83
|
+
: [];
|
|
84
|
+
// --- If vault is not unlocked, show the master password prompt ---
|
|
85
|
+
if (!isVaultUnlocked() || !vault) {
|
|
86
|
+
return (_jsxs(Container, { maxWidth: "md", sx: { mt: 4 }, children: [_jsx(BreadcrumbNav, {}), _jsx(MasterPasswordPrompt, { open: true, onClose: () => navigate('/brightpass'), vaultId: vaultId || '', vaultName: vaultId || '' })] }));
|
|
87
|
+
}
|
|
88
|
+
return (_jsxs(Container, { maxWidth: "md", sx: { mt: 4 }, children: [_jsx(BreadcrumbNav, {}), _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2, children: [_jsx(Typography, { variant: "h4", component: "h1", children: t(BrightPassStrings.VaultDetail_Title, {
|
|
89
|
+
NAME: vault.metadata.name,
|
|
90
|
+
}) }), _jsxs(Box, { display: "flex", gap: 1, children: [_jsx(Button, { variant: "contained", startIcon: _jsx(AddIcon, {}), onClick: () => setShowAddEntry(true), children: t(BrightPassStrings.VaultDetail_AddEntry) }), _jsx(Button, { variant: "outlined", startIcon: _jsx(LockIcon, {}), onClick: () => setShowLockConfirm(true), children: t(BrightPassStrings.VaultDetail_LockVault) })] })] }), error && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: error })), _jsx(TextField, { fullWidth: true, variant: "outlined", size: "small", placeholder: t(BrightPassStrings.VaultDetail_Search), value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), sx: { mb: 2 } }), filteredEntries.length === 0 && !searchQuery && (_jsx(Typography, { color: "text.secondary", sx: { mt: 4, textAlign: 'center' }, children: t(BrightPassStrings.VaultDetail_NoEntries) })), _jsx(List, { children: filteredEntries.map((entry, index) => (_jsx(ListItem, { disablePadding: true, children: _jsxs(ListItemButton, { children: [_jsx(ListItemIcon, { children: _jsx(Tooltip, { title: entryTypeLabel(entry.entryType, t), children: entryTypeIcon(entry.entryType) }) }), _jsx(ListItemText, { primaryTypographyProps: { component: 'div' }, secondaryTypographyProps: { component: 'div' }, primary: _jsxs(Box, { display: "flex", alignItems: "center", gap: 1, children: [_jsx(Typography, { variant: "body1", children: entry.title }), entry.favorite && (_jsx(Tooltip, { title: t(BrightPassStrings.VaultDetail_Favorite), children: _jsx(StarIcon, { fontSize: "small", sx: { color: 'warning.main' } }) }))] }), secondary: _jsxs(Box, { display: "flex", alignItems: "center", gap: 0.5, flexWrap: "wrap", sx: { mt: 0.5 }, children: [entry.siteUrl && (_jsx(Typography, { variant: "caption", color: "text.secondary", component: "span", children: entry.siteUrl })), entry.tags.map((tag) => (_jsx(Chip, { label: tag, size: "small", variant: "outlined", sx: { ml: 0.5 } }, tag)))] }) })] }) }, `${entry.title}-${index}`))) }), _jsxs(Dialog, { open: showLockConfirm, onClose: () => setShowLockConfirm(false), maxWidth: "xs", fullWidth: true, children: [_jsx(DialogTitle, { children: t(BrightPassStrings.VaultDetail_ConfirmLockTitle) }), _jsx(DialogContent, { children: _jsx(DialogContentText, { children: t(BrightPassStrings.VaultDetail_ConfirmLockMessage) }) }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: () => setShowLockConfirm(false), children: t(BrightPassStrings.VaultDetail_Cancel) }), _jsx(Button, { onClick: handleLockVault, variant: "contained", children: t(BrightPassStrings.VaultDetail_Confirm) })] })] })] }));
|
|
91
|
+
};
|
|
92
|
+
export default VaultDetailView;
|
|
93
|
+
//# sourceMappingURL=VaultDetailView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VaultDetailView.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/views/VaultDetailView.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { BrightPassStrings } from '@brightchain/brightchain-lib';
|
|
3
|
+
import AddIcon from '@mui/icons-material/Add';
|
|
4
|
+
import DeleteIcon from '@mui/icons-material/Delete';
|
|
5
|
+
import LockIcon from '@mui/icons-material/Lock';
|
|
6
|
+
import PeopleIcon from '@mui/icons-material/People';
|
|
7
|
+
import { Alert, Box, Button, Container, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, IconButton, List, ListItem, ListItemButton, ListItemIcon, ListItemText, TextField, Tooltip, Typography, } from '@mui/material';
|
|
8
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
9
|
+
import BreadcrumbNav from '../components/BreadcrumbNav';
|
|
10
|
+
import CreateVaultDialog from '../components/CreateVaultDialog';
|
|
11
|
+
import MasterPasswordPrompt from '../components/MasterPasswordPrompt';
|
|
12
|
+
import { useBrightPassTranslation } from '../hooks/useBrightPassTranslation';
|
|
13
|
+
import { useBrightPassApi } from '../hooks/useBrightPassApi';
|
|
14
|
+
/** Formats a Date for display in the vault list. */
|
|
15
|
+
function formatDate(date) {
|
|
16
|
+
const d = date instanceof Date ? date : new Date(date);
|
|
17
|
+
return d.toLocaleDateString(undefined, {
|
|
18
|
+
year: 'numeric',
|
|
19
|
+
month: 'short',
|
|
20
|
+
day: 'numeric',
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const VaultListView = () => {
|
|
24
|
+
const { t } = useBrightPassTranslation();
|
|
25
|
+
const brightPassApi = useBrightPassApi();
|
|
26
|
+
const [vaults, setVaults] = useState([]);
|
|
27
|
+
const [loading, setLoading] = useState(true);
|
|
28
|
+
const [error, setError] = useState(null);
|
|
29
|
+
// Dialog state
|
|
30
|
+
const [dialog, setDialog] = useState({ kind: 'none' });
|
|
31
|
+
const [masterPassword, setMasterPassword] = useState('');
|
|
32
|
+
const [dialogError, setDialogError] = useState(null);
|
|
33
|
+
const [dialogLoading, setDialogLoading] = useState(false);
|
|
34
|
+
const fetchVaults = useCallback(async () => {
|
|
35
|
+
setLoading(true);
|
|
36
|
+
setError(null);
|
|
37
|
+
try {
|
|
38
|
+
const result = await brightPassApi.listVaults();
|
|
39
|
+
setVaults(result);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
setError(t(BrightPassStrings.Error_Generic));
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
setLoading(false);
|
|
46
|
+
}
|
|
47
|
+
}, [t]);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
fetchVaults();
|
|
50
|
+
}, [fetchVaults]);
|
|
51
|
+
const closeDialog = () => {
|
|
52
|
+
setDialog({ kind: 'none' });
|
|
53
|
+
setMasterPassword('');
|
|
54
|
+
setDialogError(null);
|
|
55
|
+
setDialogLoading(false);
|
|
56
|
+
};
|
|
57
|
+
// --- Unlock vault ---
|
|
58
|
+
const handleVaultClick = (vault) => {
|
|
59
|
+
setDialog({ kind: 'unlock', vault });
|
|
60
|
+
};
|
|
61
|
+
// --- Delete vault ---
|
|
62
|
+
const handleDeleteClick = (event, vault) => {
|
|
63
|
+
event.stopPropagation();
|
|
64
|
+
setDialog({ kind: 'delete', vault });
|
|
65
|
+
};
|
|
66
|
+
const handleDeleteSubmit = async () => {
|
|
67
|
+
if (dialog.kind !== 'delete')
|
|
68
|
+
return;
|
|
69
|
+
setDialogLoading(true);
|
|
70
|
+
setDialogError(null);
|
|
71
|
+
try {
|
|
72
|
+
await brightPassApi.deleteVault(dialog.vault.id, masterPassword);
|
|
73
|
+
closeDialog();
|
|
74
|
+
await fetchVaults();
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
setDialogError(t(BrightPassStrings.Error_InvalidMasterPassword));
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
setDialogLoading(false);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
// --- Create vault ---
|
|
84
|
+
const handleCreateClick = () => {
|
|
85
|
+
setDialog({ kind: 'create' });
|
|
86
|
+
};
|
|
87
|
+
return (_jsxs(Container, { maxWidth: "md", sx: { mt: 4 }, children: [_jsx(BreadcrumbNav, {}), _jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", mb: 2, children: [_jsx(Typography, { variant: "h4", component: "h1", children: t(BrightPassStrings.VaultList_Title) }), _jsx(Button, { variant: "contained", startIcon: _jsx(AddIcon, {}), onClick: handleCreateClick, children: t(BrightPassStrings.VaultList_CreateVault) })] }), error && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: error })), !loading && vaults.length === 0 && !error && (_jsx(Typography, { color: "text.secondary", sx: { mt: 4, textAlign: 'center' }, children: t(BrightPassStrings.VaultList_NoVaults) })), _jsx(List, { children: vaults.map((vault) => (_jsx(ListItem, { disablePadding: true, secondaryAction: _jsx(IconButton, { edge: "end", "aria-label": t(BrightPassStrings.VaultList_DeleteVault), onClick: (e) => handleDeleteClick(e, vault), children: _jsx(DeleteIcon, {}) }), children: _jsxs(ListItemButton, { onClick: () => handleVaultClick(vault), children: [_jsx(ListItemIcon, { children: _jsx(LockIcon, {}) }), _jsx(ListItemText, { primary: vault.name, secondary: formatDate(vault.createdAt) }), vault.sharedWith.length > 0 && (_jsx(Tooltip, { title: t(BrightPassStrings.VaultList_SharedWith, {
|
|
88
|
+
COUNT: String(vault.sharedWith.length),
|
|
89
|
+
}), children: _jsxs(Box, { display: "flex", alignItems: "center", mr: 2, children: [_jsx(PeopleIcon, { fontSize: "small", color: "action", sx: { mr: 0.5 } }), _jsx(Typography, { variant: "body2", color: "text.secondary", children: vault.sharedWith.length })] }) }))] }) }, vault.id))) }), _jsx(MasterPasswordPrompt, { open: dialog.kind === 'unlock', onClose: closeDialog, vaultId: dialog.kind === 'unlock' ? dialog.vault.id : '', vaultName: dialog.kind === 'unlock' ? dialog.vault.name : '' }), _jsxs(Dialog, { open: dialog.kind === 'delete', onClose: closeDialog, maxWidth: "xs", fullWidth: true, children: [_jsx(DialogTitle, { children: t(BrightPassStrings.VaultList_ConfirmDelete) }), _jsxs(DialogContent, { children: [_jsx(DialogContentText, { sx: { mb: 2 }, children: dialog.kind === 'delete'
|
|
90
|
+
? t(BrightPassStrings.VaultList_ConfirmDeleteMessage, {
|
|
91
|
+
NAME: dialog.vault.name,
|
|
92
|
+
})
|
|
93
|
+
: '' }), dialogError && (_jsx(Alert, { severity: "error", sx: { mb: 2 }, children: dialogError })), _jsx(TextField, { autoFocus: true, margin: "dense", label: t(BrightPassStrings.VaultList_EnterMasterPassword), type: "password", fullWidth: true, variant: "outlined", value: masterPassword, onChange: (e) => setMasterPassword(e.target.value), onKeyDown: (e) => {
|
|
94
|
+
if (e.key === 'Enter')
|
|
95
|
+
handleDeleteSubmit();
|
|
96
|
+
} })] }), _jsxs(DialogActions, { children: [_jsx(Button, { onClick: closeDialog, children: t(BrightPassStrings.VaultList_Cancel) }), _jsx(Button, { onClick: handleDeleteSubmit, variant: "contained", color: "error", disabled: dialogLoading || !masterPassword, children: t(BrightPassStrings.VaultList_Confirm) })] })] }), _jsx(CreateVaultDialog, { open: dialog.kind === 'create', onClose: closeDialog, onVaultCreated: fetchVaults })] }));
|
|
97
|
+
};
|
|
98
|
+
export default VaultListView;
|
|
99
|
+
//# sourceMappingURL=VaultListView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VaultListView.js","sourceRoot":"","sources":["../../../../../brightpass-react-components/src/lib/views/VaultListView.tsx"],"names":[],"mappings":"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"}
|