@agenticmail/enterprise 0.5.60 → 0.5.62
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/chunk-L6PN3MGP.js +898 -0
- package/dist/chunk-M5BY3ZSI.js +898 -0
- package/dist/chunk-PFSSNZ2W.js +2127 -0
- package/dist/chunk-VMRMCEL7.js +2133 -0
- package/dist/cli.js +1 -1
- package/dist/dashboard/pages/audit.js +67 -29
- package/dist/dashboard/pages/settings.js +2 -1
- package/dist/index.js +2 -2
- package/dist/server-ILNFKSZ4.js +12 -0
- package/dist/server-PDIHALIQ.js +12 -0
- package/dist/setup-OCRGZNUL.js +20 -0
- package/dist/setup-SPKFGFRP.js +20 -0
- package/package.json +1 -1
- package/src/dashboard/pages/audit.js +67 -29
- package/src/dashboard/pages/settings.js +2 -1
- package/src/server.ts +17 -0
package/dist/cli.js
CHANGED
|
@@ -1,33 +1,51 @@
|
|
|
1
|
-
import { h, useState, useEffect, Fragment, useApp, apiCall } from '../components/utils.js';
|
|
1
|
+
import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall } from '../components/utils.js';
|
|
2
2
|
import { I } from '../components/icons.js';
|
|
3
3
|
import { DetailModal } from '../components/modal.js';
|
|
4
4
|
|
|
5
|
+
var PAGE_SIZE = 50;
|
|
6
|
+
|
|
5
7
|
export function AuditPage() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
var [logs, setLogs] = useState([]);
|
|
9
|
+
var [loading, setLoading] = useState(true);
|
|
10
|
+
var [selected, setSelected] = useState(null);
|
|
11
|
+
var [filter, setFilter] = useState('');
|
|
12
|
+
var [page, setPage] = useState(0);
|
|
13
|
+
var [total, setTotal] = useState(0);
|
|
14
|
+
var [hasMore, setHasMore] = useState(false);
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
var loadPage = useCallback(function(p) {
|
|
17
|
+
setLoading(true);
|
|
18
|
+
var offset = p * PAGE_SIZE;
|
|
19
|
+
apiCall('/audit?limit=' + PAGE_SIZE + '&offset=' + offset)
|
|
20
|
+
.then(function(d) {
|
|
21
|
+
var arr = d.events || d.entries || d.logs || d;
|
|
22
|
+
arr = Array.isArray(arr) ? arr : [];
|
|
23
|
+
setLogs(arr);
|
|
24
|
+
setTotal(d.total || arr.length);
|
|
25
|
+
setHasMore(arr.length >= PAGE_SIZE);
|
|
26
|
+
setLoading(false);
|
|
27
|
+
})
|
|
28
|
+
.catch(function() { setLoading(false); });
|
|
13
29
|
}, []);
|
|
14
30
|
|
|
15
|
-
|
|
16
|
-
|
|
31
|
+
useEffect(function() { loadPage(0); }, []);
|
|
32
|
+
|
|
33
|
+
var goPage = function(p) { setPage(p); loadPage(p); };
|
|
34
|
+
|
|
35
|
+
var actorDisplay = function(l) {
|
|
17
36
|
if (l.details && l.details.email) return l.details.email;
|
|
18
37
|
if (l.actorType === 'system') return 'System';
|
|
19
38
|
return l.actor || l.userId || l.user || '-';
|
|
20
39
|
};
|
|
21
40
|
|
|
22
|
-
|
|
23
|
-
const actorRole = (l) => {
|
|
41
|
+
var actorRole = function(l) {
|
|
24
42
|
if (l.details && l.details.role) return l.details.role;
|
|
25
43
|
return l.actorType || null;
|
|
26
44
|
};
|
|
27
45
|
|
|
28
|
-
|
|
29
|
-
? logs.filter(l
|
|
30
|
-
|
|
46
|
+
var filtered = filter
|
|
47
|
+
? logs.filter(function(l) {
|
|
48
|
+
var s = filter.toLowerCase();
|
|
31
49
|
return (l.action || '').toLowerCase().includes(s)
|
|
32
50
|
|| actorDisplay(l).toLowerCase().includes(s)
|
|
33
51
|
|| (l.resource || '').toLowerCase().includes(s)
|
|
@@ -35,9 +53,9 @@ export function AuditPage() {
|
|
|
35
53
|
})
|
|
36
54
|
: logs;
|
|
37
55
|
|
|
38
|
-
|
|
56
|
+
var actionColor = function(action) {
|
|
39
57
|
if (!action) return 'badge-neutral';
|
|
40
|
-
|
|
58
|
+
var a = action.toLowerCase();
|
|
41
59
|
if (a.includes('create') || a.includes('add')) return 'badge-success';
|
|
42
60
|
if (a.includes('delete') || a.includes('remove') || a.includes('revoke')) return 'badge-danger';
|
|
43
61
|
if (a.includes('update') || a.includes('edit') || a.includes('patch')) return 'badge-warning';
|
|
@@ -45,7 +63,7 @@ export function AuditPage() {
|
|
|
45
63
|
return 'badge-neutral';
|
|
46
64
|
};
|
|
47
65
|
|
|
48
|
-
|
|
66
|
+
var roleColor = function(role) {
|
|
49
67
|
if (!role) return 'badge-neutral';
|
|
50
68
|
if (role === 'owner') return 'badge-danger';
|
|
51
69
|
if (role === 'admin') return 'badge-warning';
|
|
@@ -53,12 +71,13 @@ export function AuditPage() {
|
|
|
53
71
|
return 'badge-neutral';
|
|
54
72
|
};
|
|
55
73
|
|
|
56
|
-
|
|
57
|
-
const resourceDisplay = (r) => {
|
|
74
|
+
var resourceDisplay = function(r) {
|
|
58
75
|
if (!r) return '-';
|
|
59
76
|
return r.replace(/^\/api\//, '').replace(/^\//, '');
|
|
60
77
|
};
|
|
61
78
|
|
|
79
|
+
var totalPages = Math.max(1, Math.ceil((total || (hasMore ? (page + 2) * PAGE_SIZE : (page + 1) * PAGE_SIZE)) / PAGE_SIZE));
|
|
80
|
+
|
|
62
81
|
return h(Fragment, null,
|
|
63
82
|
h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 } },
|
|
64
83
|
h('div', null,
|
|
@@ -66,11 +85,11 @@ export function AuditPage() {
|
|
|
66
85
|
h('p', { style: { color: 'var(--text-muted)', fontSize: 13 } }, 'Complete record of all administrative actions and changes')
|
|
67
86
|
),
|
|
68
87
|
h('div', { style: { display: 'flex', gap: 8, alignItems: 'center' } },
|
|
69
|
-
h('span', { style: { fontSize: 12, color: 'var(--text-muted)' } },
|
|
88
|
+
total > 0 && h('span', { style: { fontSize: 12, color: 'var(--text-muted)' } }, total + ' total'),
|
|
70
89
|
h('input', {
|
|
71
90
|
className: 'input', placeholder: 'Filter by action, user, target...',
|
|
72
91
|
style: { width: 260, fontSize: 13 },
|
|
73
|
-
value: filter, onChange: e
|
|
92
|
+
value: filter, onChange: function(e) { setFilter(e.target.value); }
|
|
74
93
|
})
|
|
75
94
|
)
|
|
76
95
|
),
|
|
@@ -88,11 +107,11 @@ export function AuditPage() {
|
|
|
88
107
|
h('th', null, 'IP'),
|
|
89
108
|
h('th', { style: { width: 40 } })
|
|
90
109
|
)),
|
|
91
|
-
h('tbody', null, filtered.map((l, i)
|
|
92
|
-
h('tr', {
|
|
110
|
+
h('tbody', null, filtered.map(function(l, i) {
|
|
111
|
+
return h('tr', {
|
|
93
112
|
key: i,
|
|
94
113
|
style: { cursor: 'pointer' },
|
|
95
|
-
onClick: ()
|
|
114
|
+
onClick: function() { setSelected(l); },
|
|
96
115
|
title: 'Click to view details'
|
|
97
116
|
},
|
|
98
117
|
h('td', { style: { fontSize: 12, color: 'var(--text-muted)', whiteSpace: 'nowrap' } },
|
|
@@ -105,17 +124,36 @@ export function AuditPage() {
|
|
|
105
124
|
resourceDisplay(l.resource)
|
|
106
125
|
),
|
|
107
126
|
h('td', { style: { fontSize: 12, color: 'var(--text-muted)' } }, l.ip || '-'),
|
|
108
|
-
h('td', null, h('button', { className: 'btn btn-ghost btn-icon', style: { padding: 4, fontSize: 14, color: 'var(--text-muted)' }, onClick: e
|
|
109
|
-
)
|
|
110
|
-
))
|
|
127
|
+
h('td', null, h('button', { className: 'btn btn-ghost btn-icon', style: { padding: 4, fontSize: 14, color: 'var(--text-muted)' }, onClick: function(e) { e.stopPropagation(); setSelected(l); } }, '\u203A'))
|
|
128
|
+
);
|
|
129
|
+
}))
|
|
111
130
|
)
|
|
131
|
+
),
|
|
132
|
+
|
|
133
|
+
// Pagination
|
|
134
|
+
(hasMore || page > 0) && h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 16px', borderTop: '1px solid var(--border)', fontSize: 13 } },
|
|
135
|
+
h('span', { style: { color: 'var(--text-muted)' } },
|
|
136
|
+
'Showing ' + (page * PAGE_SIZE + 1) + '–' + (page * PAGE_SIZE + filtered.length) + (total ? ' of ' + total : '')
|
|
137
|
+
),
|
|
138
|
+
h('div', { style: { display: 'flex', gap: 4 } },
|
|
139
|
+
h('button', {
|
|
140
|
+
className: 'btn btn-secondary btn-sm',
|
|
141
|
+
disabled: page === 0,
|
|
142
|
+
onClick: function() { goPage(page - 1); }
|
|
143
|
+
}, '\u2190 Previous'),
|
|
144
|
+
h('span', { style: { padding: '4px 12px', fontSize: 12, color: 'var(--text-secondary)' } }, 'Page ' + (page + 1)),
|
|
145
|
+
h('button', {
|
|
146
|
+
className: 'btn btn-secondary btn-sm',
|
|
147
|
+
disabled: !hasMore,
|
|
148
|
+
onClick: function() { goPage(page + 1); }
|
|
149
|
+
}, 'Next \u2192')
|
|
150
|
+
)
|
|
112
151
|
)
|
|
113
152
|
),
|
|
114
153
|
|
|
115
|
-
// ─── Detail Modal ──────────────────────────────
|
|
116
154
|
selected && h(DetailModal, {
|
|
117
155
|
title: 'Audit Entry',
|
|
118
|
-
onClose: ()
|
|
156
|
+
onClose: function() { setSelected(null); },
|
|
119
157
|
data: {
|
|
120
158
|
timestamp: selected.timestamp,
|
|
121
159
|
action: selected.action,
|
|
@@ -260,7 +260,8 @@ export function SettingsPage() {
|
|
|
260
260
|
h('div', { className: 'card-header' }, h('h3', null, 'Info')),
|
|
261
261
|
h('div', { className: 'card-body' },
|
|
262
262
|
h('div', { style: { display: 'grid', gridTemplateColumns: '140px 1fr', gap: '6px 16px', fontSize: 13 } },
|
|
263
|
-
h('span', { style: { color: 'var(--text-muted)' } }, 'Organization ID'), h('span', { style: { fontFamily: 'var(--font-mono)', fontSize: 12 } }, settings.id || '-'),
|
|
263
|
+
h('span', { style: { color: 'var(--text-muted)' } }, 'Organization ID'), h('span', { style: { fontFamily: 'var(--font-mono)', fontSize: 12 } }, settings.orgId || settings.id || '-'),
|
|
264
|
+
h('span', { style: { color: 'var(--text-muted)' } }, 'Version'), h('span', { style: { fontFamily: 'var(--font-mono)', fontSize: 12 } }, settings.version || window.__ENTERPRISE_VERSION || '-'),
|
|
264
265
|
h('span', { style: { color: 'var(--text-muted)' } }, 'Created'), h('span', null, settings.createdAt ? new Date(settings.createdAt).toLocaleString() : '-'),
|
|
265
266
|
h('span', { style: { color: 'var(--text-muted)' } }, 'Last Updated'), h('span', null, settings.updatedAt ? new Date(settings.updatedAt).toLocaleString() : '-')
|
|
266
267
|
)
|
package/dist/index.js
CHANGED
|
@@ -50,11 +50,11 @@ import {
|
|
|
50
50
|
requireRole,
|
|
51
51
|
securityHeaders,
|
|
52
52
|
validate
|
|
53
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-VMRMCEL7.js";
|
|
54
54
|
import {
|
|
55
55
|
provision,
|
|
56
56
|
runSetupWizard
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-M5BY3ZSI.js";
|
|
58
58
|
import {
|
|
59
59
|
ENGINE_TABLES,
|
|
60
60
|
ENGINE_TABLES_POSTGRES,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createServer
|
|
3
|
+
} from "./chunk-VMRMCEL7.js";
|
|
4
|
+
import "./chunk-3SMTCIR4.js";
|
|
5
|
+
import "./chunk-JLSQOQ5L.js";
|
|
6
|
+
import "./chunk-RO537U6H.js";
|
|
7
|
+
import "./chunk-DRXMYYKN.js";
|
|
8
|
+
import "./chunk-67KZYSLU.js";
|
|
9
|
+
import "./chunk-KFQGP6VL.js";
|
|
10
|
+
export {
|
|
11
|
+
createServer
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createServer
|
|
3
|
+
} from "./chunk-PFSSNZ2W.js";
|
|
4
|
+
import "./chunk-3SMTCIR4.js";
|
|
5
|
+
import "./chunk-JLSQOQ5L.js";
|
|
6
|
+
import "./chunk-RO537U6H.js";
|
|
7
|
+
import "./chunk-DRXMYYKN.js";
|
|
8
|
+
import "./chunk-67KZYSLU.js";
|
|
9
|
+
import "./chunk-KFQGP6VL.js";
|
|
10
|
+
export {
|
|
11
|
+
createServer
|
|
12
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
promptCompanyInfo,
|
|
3
|
+
promptDatabase,
|
|
4
|
+
promptDeployment,
|
|
5
|
+
promptDomain,
|
|
6
|
+
promptRegistration,
|
|
7
|
+
provision,
|
|
8
|
+
runSetupWizard
|
|
9
|
+
} from "./chunk-L6PN3MGP.js";
|
|
10
|
+
import "./chunk-M4PRT53C.js";
|
|
11
|
+
import "./chunk-KFQGP6VL.js";
|
|
12
|
+
export {
|
|
13
|
+
promptCompanyInfo,
|
|
14
|
+
promptDatabase,
|
|
15
|
+
promptDeployment,
|
|
16
|
+
promptDomain,
|
|
17
|
+
promptRegistration,
|
|
18
|
+
provision,
|
|
19
|
+
runSetupWizard
|
|
20
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
promptCompanyInfo,
|
|
3
|
+
promptDatabase,
|
|
4
|
+
promptDeployment,
|
|
5
|
+
promptDomain,
|
|
6
|
+
promptRegistration,
|
|
7
|
+
provision,
|
|
8
|
+
runSetupWizard
|
|
9
|
+
} from "./chunk-M5BY3ZSI.js";
|
|
10
|
+
import "./chunk-M4PRT53C.js";
|
|
11
|
+
import "./chunk-KFQGP6VL.js";
|
|
12
|
+
export {
|
|
13
|
+
promptCompanyInfo,
|
|
14
|
+
promptDatabase,
|
|
15
|
+
promptDeployment,
|
|
16
|
+
promptDomain,
|
|
17
|
+
promptRegistration,
|
|
18
|
+
provision,
|
|
19
|
+
runSetupWizard
|
|
20
|
+
};
|
package/package.json
CHANGED
|
@@ -1,33 +1,51 @@
|
|
|
1
|
-
import { h, useState, useEffect, Fragment, useApp, apiCall } from '../components/utils.js';
|
|
1
|
+
import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall } from '../components/utils.js';
|
|
2
2
|
import { I } from '../components/icons.js';
|
|
3
3
|
import { DetailModal } from '../components/modal.js';
|
|
4
4
|
|
|
5
|
+
var PAGE_SIZE = 50;
|
|
6
|
+
|
|
5
7
|
export function AuditPage() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
var [logs, setLogs] = useState([]);
|
|
9
|
+
var [loading, setLoading] = useState(true);
|
|
10
|
+
var [selected, setSelected] = useState(null);
|
|
11
|
+
var [filter, setFilter] = useState('');
|
|
12
|
+
var [page, setPage] = useState(0);
|
|
13
|
+
var [total, setTotal] = useState(0);
|
|
14
|
+
var [hasMore, setHasMore] = useState(false);
|
|
10
15
|
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
var loadPage = useCallback(function(p) {
|
|
17
|
+
setLoading(true);
|
|
18
|
+
var offset = p * PAGE_SIZE;
|
|
19
|
+
apiCall('/audit?limit=' + PAGE_SIZE + '&offset=' + offset)
|
|
20
|
+
.then(function(d) {
|
|
21
|
+
var arr = d.events || d.entries || d.logs || d;
|
|
22
|
+
arr = Array.isArray(arr) ? arr : [];
|
|
23
|
+
setLogs(arr);
|
|
24
|
+
setTotal(d.total || arr.length);
|
|
25
|
+
setHasMore(arr.length >= PAGE_SIZE);
|
|
26
|
+
setLoading(false);
|
|
27
|
+
})
|
|
28
|
+
.catch(function() { setLoading(false); });
|
|
13
29
|
}, []);
|
|
14
30
|
|
|
15
|
-
|
|
16
|
-
|
|
31
|
+
useEffect(function() { loadPage(0); }, []);
|
|
32
|
+
|
|
33
|
+
var goPage = function(p) { setPage(p); loadPage(p); };
|
|
34
|
+
|
|
35
|
+
var actorDisplay = function(l) {
|
|
17
36
|
if (l.details && l.details.email) return l.details.email;
|
|
18
37
|
if (l.actorType === 'system') return 'System';
|
|
19
38
|
return l.actor || l.userId || l.user || '-';
|
|
20
39
|
};
|
|
21
40
|
|
|
22
|
-
|
|
23
|
-
const actorRole = (l) => {
|
|
41
|
+
var actorRole = function(l) {
|
|
24
42
|
if (l.details && l.details.role) return l.details.role;
|
|
25
43
|
return l.actorType || null;
|
|
26
44
|
};
|
|
27
45
|
|
|
28
|
-
|
|
29
|
-
? logs.filter(l
|
|
30
|
-
|
|
46
|
+
var filtered = filter
|
|
47
|
+
? logs.filter(function(l) {
|
|
48
|
+
var s = filter.toLowerCase();
|
|
31
49
|
return (l.action || '').toLowerCase().includes(s)
|
|
32
50
|
|| actorDisplay(l).toLowerCase().includes(s)
|
|
33
51
|
|| (l.resource || '').toLowerCase().includes(s)
|
|
@@ -35,9 +53,9 @@ export function AuditPage() {
|
|
|
35
53
|
})
|
|
36
54
|
: logs;
|
|
37
55
|
|
|
38
|
-
|
|
56
|
+
var actionColor = function(action) {
|
|
39
57
|
if (!action) return 'badge-neutral';
|
|
40
|
-
|
|
58
|
+
var a = action.toLowerCase();
|
|
41
59
|
if (a.includes('create') || a.includes('add')) return 'badge-success';
|
|
42
60
|
if (a.includes('delete') || a.includes('remove') || a.includes('revoke')) return 'badge-danger';
|
|
43
61
|
if (a.includes('update') || a.includes('edit') || a.includes('patch')) return 'badge-warning';
|
|
@@ -45,7 +63,7 @@ export function AuditPage() {
|
|
|
45
63
|
return 'badge-neutral';
|
|
46
64
|
};
|
|
47
65
|
|
|
48
|
-
|
|
66
|
+
var roleColor = function(role) {
|
|
49
67
|
if (!role) return 'badge-neutral';
|
|
50
68
|
if (role === 'owner') return 'badge-danger';
|
|
51
69
|
if (role === 'admin') return 'badge-warning';
|
|
@@ -53,12 +71,13 @@ export function AuditPage() {
|
|
|
53
71
|
return 'badge-neutral';
|
|
54
72
|
};
|
|
55
73
|
|
|
56
|
-
|
|
57
|
-
const resourceDisplay = (r) => {
|
|
74
|
+
var resourceDisplay = function(r) {
|
|
58
75
|
if (!r) return '-';
|
|
59
76
|
return r.replace(/^\/api\//, '').replace(/^\//, '');
|
|
60
77
|
};
|
|
61
78
|
|
|
79
|
+
var totalPages = Math.max(1, Math.ceil((total || (hasMore ? (page + 2) * PAGE_SIZE : (page + 1) * PAGE_SIZE)) / PAGE_SIZE));
|
|
80
|
+
|
|
62
81
|
return h(Fragment, null,
|
|
63
82
|
h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 } },
|
|
64
83
|
h('div', null,
|
|
@@ -66,11 +85,11 @@ export function AuditPage() {
|
|
|
66
85
|
h('p', { style: { color: 'var(--text-muted)', fontSize: 13 } }, 'Complete record of all administrative actions and changes')
|
|
67
86
|
),
|
|
68
87
|
h('div', { style: { display: 'flex', gap: 8, alignItems: 'center' } },
|
|
69
|
-
h('span', { style: { fontSize: 12, color: 'var(--text-muted)' } },
|
|
88
|
+
total > 0 && h('span', { style: { fontSize: 12, color: 'var(--text-muted)' } }, total + ' total'),
|
|
70
89
|
h('input', {
|
|
71
90
|
className: 'input', placeholder: 'Filter by action, user, target...',
|
|
72
91
|
style: { width: 260, fontSize: 13 },
|
|
73
|
-
value: filter, onChange: e
|
|
92
|
+
value: filter, onChange: function(e) { setFilter(e.target.value); }
|
|
74
93
|
})
|
|
75
94
|
)
|
|
76
95
|
),
|
|
@@ -88,11 +107,11 @@ export function AuditPage() {
|
|
|
88
107
|
h('th', null, 'IP'),
|
|
89
108
|
h('th', { style: { width: 40 } })
|
|
90
109
|
)),
|
|
91
|
-
h('tbody', null, filtered.map((l, i)
|
|
92
|
-
h('tr', {
|
|
110
|
+
h('tbody', null, filtered.map(function(l, i) {
|
|
111
|
+
return h('tr', {
|
|
93
112
|
key: i,
|
|
94
113
|
style: { cursor: 'pointer' },
|
|
95
|
-
onClick: ()
|
|
114
|
+
onClick: function() { setSelected(l); },
|
|
96
115
|
title: 'Click to view details'
|
|
97
116
|
},
|
|
98
117
|
h('td', { style: { fontSize: 12, color: 'var(--text-muted)', whiteSpace: 'nowrap' } },
|
|
@@ -105,17 +124,36 @@ export function AuditPage() {
|
|
|
105
124
|
resourceDisplay(l.resource)
|
|
106
125
|
),
|
|
107
126
|
h('td', { style: { fontSize: 12, color: 'var(--text-muted)' } }, l.ip || '-'),
|
|
108
|
-
h('td', null, h('button', { className: 'btn btn-ghost btn-icon', style: { padding: 4, fontSize: 14, color: 'var(--text-muted)' }, onClick: e
|
|
109
|
-
)
|
|
110
|
-
))
|
|
127
|
+
h('td', null, h('button', { className: 'btn btn-ghost btn-icon', style: { padding: 4, fontSize: 14, color: 'var(--text-muted)' }, onClick: function(e) { e.stopPropagation(); setSelected(l); } }, '\u203A'))
|
|
128
|
+
);
|
|
129
|
+
}))
|
|
111
130
|
)
|
|
131
|
+
),
|
|
132
|
+
|
|
133
|
+
// Pagination
|
|
134
|
+
(hasMore || page > 0) && h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '12px 16px', borderTop: '1px solid var(--border)', fontSize: 13 } },
|
|
135
|
+
h('span', { style: { color: 'var(--text-muted)' } },
|
|
136
|
+
'Showing ' + (page * PAGE_SIZE + 1) + '–' + (page * PAGE_SIZE + filtered.length) + (total ? ' of ' + total : '')
|
|
137
|
+
),
|
|
138
|
+
h('div', { style: { display: 'flex', gap: 4 } },
|
|
139
|
+
h('button', {
|
|
140
|
+
className: 'btn btn-secondary btn-sm',
|
|
141
|
+
disabled: page === 0,
|
|
142
|
+
onClick: function() { goPage(page - 1); }
|
|
143
|
+
}, '\u2190 Previous'),
|
|
144
|
+
h('span', { style: { padding: '4px 12px', fontSize: 12, color: 'var(--text-secondary)' } }, 'Page ' + (page + 1)),
|
|
145
|
+
h('button', {
|
|
146
|
+
className: 'btn btn-secondary btn-sm',
|
|
147
|
+
disabled: !hasMore,
|
|
148
|
+
onClick: function() { goPage(page + 1); }
|
|
149
|
+
}, 'Next \u2192')
|
|
150
|
+
)
|
|
112
151
|
)
|
|
113
152
|
),
|
|
114
153
|
|
|
115
|
-
// ─── Detail Modal ──────────────────────────────
|
|
116
154
|
selected && h(DetailModal, {
|
|
117
155
|
title: 'Audit Entry',
|
|
118
|
-
onClose: ()
|
|
156
|
+
onClose: function() { setSelected(null); },
|
|
119
157
|
data: {
|
|
120
158
|
timestamp: selected.timestamp,
|
|
121
159
|
action: selected.action,
|
|
@@ -260,7 +260,8 @@ export function SettingsPage() {
|
|
|
260
260
|
h('div', { className: 'card-header' }, h('h3', null, 'Info')),
|
|
261
261
|
h('div', { className: 'card-body' },
|
|
262
262
|
h('div', { style: { display: 'grid', gridTemplateColumns: '140px 1fr', gap: '6px 16px', fontSize: 13 } },
|
|
263
|
-
h('span', { style: { color: 'var(--text-muted)' } }, 'Organization ID'), h('span', { style: { fontFamily: 'var(--font-mono)', fontSize: 12 } }, settings.id || '-'),
|
|
263
|
+
h('span', { style: { color: 'var(--text-muted)' } }, 'Organization ID'), h('span', { style: { fontFamily: 'var(--font-mono)', fontSize: 12 } }, settings.orgId || settings.id || '-'),
|
|
264
|
+
h('span', { style: { color: 'var(--text-muted)' } }, 'Version'), h('span', { style: { fontFamily: 'var(--font-mono)', fontSize: 12 } }, settings.version || window.__ENTERPRISE_VERSION || '-'),
|
|
264
265
|
h('span', { style: { color: 'var(--text-muted)' } }, 'Created'), h('span', null, settings.createdAt ? new Date(settings.createdAt).toLocaleString() : '-'),
|
|
265
266
|
h('span', { style: { color: 'var(--text-muted)' } }, 'Last Updated'), h('span', null, settings.updatedAt ? new Date(settings.updatedAt).toLocaleString() : '-')
|
|
266
267
|
)
|
package/src/server.ts
CHANGED
|
@@ -319,6 +319,23 @@ export function createServer(config: ServerConfig): ServerInstance {
|
|
|
319
319
|
|
|
320
320
|
async function serveDashboard(c: any) {
|
|
321
321
|
let html = getDashboardHtml();
|
|
322
|
+
// Inject version — try multiple paths
|
|
323
|
+
let _version = '';
|
|
324
|
+
for (const rel of ['../package.json', './package.json', '../../package.json']) {
|
|
325
|
+
if (_version) break;
|
|
326
|
+
try {
|
|
327
|
+
const p = join(dirname(fileURLToPath(import.meta.url)), rel);
|
|
328
|
+
_version = JSON.parse(readFileSync(p, 'utf-8')).version;
|
|
329
|
+
} catch { /* try next */ }
|
|
330
|
+
}
|
|
331
|
+
if (!_version) {
|
|
332
|
+
// Fallback: search from cwd
|
|
333
|
+
try { _version = JSON.parse(readFileSync(join(process.cwd(), 'node_modules', '@agenticmail', 'enterprise', 'package.json'), 'utf-8')).version; } catch { /* noop */ }
|
|
334
|
+
}
|
|
335
|
+
if (_version) {
|
|
336
|
+
html = html.replace('</head>', `<script>window.__ENTERPRISE_VERSION__="${_version}";</script></head>`);
|
|
337
|
+
}
|
|
338
|
+
|
|
322
339
|
if (!_setupComplete) {
|
|
323
340
|
const injection = `<script>window.__EM_SETUP_STATE__=${JSON.stringify({ needsBootstrap: true })};</script>`;
|
|
324
341
|
html = html.replace('</head>', injection + '</head>');
|