@arch-cadre/panel 0.0.1 → 1.0.2
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/actions/activity-log/index.cjs +19 -0
- package/dist/actions/activity-log/index.d.ts +1 -0
- package/dist/actions/activity-log/index.mjs +10 -0
- package/dist/actions/rbac/index.cjs +130 -0
- package/dist/actions/rbac/index.d.ts +35 -0
- package/dist/actions/rbac/index.mjs +92 -0
- package/dist/actions/session-manager/index.cjs +99 -0
- package/dist/actions/session-manager/index.d.ts +21 -0
- package/dist/actions/session-manager/index.mjs +73 -0
- package/dist/index.cjs +68 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.mjs +90 -0
- package/dist/navigation.cjs +15 -1
- package/dist/navigation.mjs +17 -1
- package/dist/routes.cjs +31 -6
- package/dist/routes.mjs +34 -6
- package/dist/schema/activity-log.cjs +23 -0
- package/dist/schema/activity-log.d.ts +103 -0
- package/dist/schema/activity-log.mjs +15 -0
- package/dist/schema.cjs +16 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.mjs +1 -0
- package/dist/ui/activity-log/components/ActivityStatsWidget.cjs +35 -0
- package/dist/ui/activity-log/components/ActivityStatsWidget.d.ts +2 -0
- package/dist/ui/activity-log/components/ActivityStatsWidget.mjs +15 -0
- package/dist/ui/activity-log/components/RecentLogsWidget.cjs +50 -0
- package/dist/ui/activity-log/components/RecentLogsWidget.d.ts +2 -0
- package/dist/ui/activity-log/components/RecentLogsWidget.mjs +29 -0
- package/dist/ui/activity-log/pages/log-list.cjs +61 -0
- package/dist/ui/activity-log/pages/log-list.d.ts +2 -0
- package/dist/ui/activity-log/pages/log-list.mjs +36 -0
- package/dist/ui/components/app-user.cjs +4 -5
- package/dist/ui/components/app-user.mjs +5 -7
- package/dist/ui/components/profile/components.cjs +4 -1
- package/dist/ui/components/profile/components.d.ts +4 -3
- package/dist/ui/components/profile/components.mjs +1 -0
- package/dist/ui/components/profile/link.cjs +10 -1
- package/dist/ui/components/profile/link.d.ts +2 -1
- package/dist/ui/components/profile/link.mjs +2 -1
- package/dist/ui/components/profile/page.cjs +4 -1
- package/dist/ui/components/profile/page.d.ts +2 -1
- package/dist/ui/components/profile/page.mjs +9 -2
- package/dist/ui/dashboard/page.cjs +6 -16
- package/dist/ui/dashboard/page.d.ts +1 -1
- package/dist/ui/dashboard/page.mjs +14 -6
- package/dist/ui/dashboard/widgets/WelcomeBackUserWidget.cjs +43 -0
- package/dist/ui/dashboard/widgets/WelcomeBackUserWidget.d.ts +2 -0
- package/dist/ui/dashboard/widgets/WelcomeBackUserWidget.mjs +18 -0
- package/dist/ui/rbac/pages/rbac-admin.cjs +328 -0
- package/dist/ui/rbac/pages/rbac-admin.d.ts +2 -0
- package/dist/ui/rbac/pages/rbac-admin.mjs +375 -0
- package/dist/ui/session-manager/components/sessions-list.cjs +160 -0
- package/dist/ui/session-manager/components/sessions-list.d.ts +13 -0
- package/dist/ui/session-manager/components/sessions-list.mjs +193 -0
- package/dist/ui/session-manager/pages/sessions-page.cjs +29 -0
- package/dist/ui/session-manager/pages/sessions-page.d.ts +2 -0
- package/dist/ui/session-manager/pages/sessions-page.mjs +9 -0
- package/locales/en/global.json +109 -1
- package/locales/pl/global.json +188 -0
- package/package.json +7 -6
- package/dist/ui/[...catchAll]/page.cjs +0 -127
- package/dist/ui/[...catchAll]/page.d.ts +0 -13
- package/dist/ui/[...catchAll]/page.mjs +0 -88
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use server";
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getActivityLogs = getActivityLogs;
|
|
8
|
+
var _server = require("@arch-cadre/core/server");
|
|
9
|
+
var _drizzleOrm = require("drizzle-orm");
|
|
10
|
+
var _activityLog = require("../../schema/activity-log.cjs");
|
|
11
|
+
async function getActivityLogs() {
|
|
12
|
+
return await _server.db.select({
|
|
13
|
+
log: _activityLog.activityLogsTable,
|
|
14
|
+
user: {
|
|
15
|
+
name: _server.userTable.name,
|
|
16
|
+
email: _server.userTable.email
|
|
17
|
+
}
|
|
18
|
+
}).from(_activityLog.activityLogsTable).leftJoin(_server.userTable, (0, _drizzleOrm.eq)(_activityLog.activityLogsTable.userId, _server.userTable.id)).orderBy((0, _drizzleOrm.desc)(_activityLog.activityLogsTable.createdAt)).limit(100);
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getActivityLogs(): Promise<any>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
import { db, userTable } from "@arch-cadre/core/server";
|
|
3
|
+
import { desc, eq } from "drizzle-orm";
|
|
4
|
+
import { activityLogsTable } from "../../schema/activity-log.mjs";
|
|
5
|
+
export async function getActivityLogs() {
|
|
6
|
+
return await db.select({
|
|
7
|
+
log: activityLogsTable,
|
|
8
|
+
user: { name: userTable.name, email: userTable.email }
|
|
9
|
+
}).from(activityLogsTable).leftJoin(userTable, eq(activityLogsTable.userId, userTable.id)).orderBy(desc(activityLogsTable.createdAt)).limit(100);
|
|
10
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use server";
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.assignPermissionToRole = assignPermissionToRole;
|
|
8
|
+
exports.assignPermissionToUser = assignPermissionToUser;
|
|
9
|
+
exports.assignRoleToUser = assignRoleToUser;
|
|
10
|
+
exports.createPermission = createPermission;
|
|
11
|
+
exports.createRole = createRole;
|
|
12
|
+
exports.deletePermission = deletePermission;
|
|
13
|
+
exports.deleteRole = deleteRole;
|
|
14
|
+
exports.getPermissions = getPermissions;
|
|
15
|
+
exports.getRolePermissions = getRolePermissions;
|
|
16
|
+
exports.getRoles = getRoles;
|
|
17
|
+
exports.getUserRbacData = getUserRbacData;
|
|
18
|
+
exports.getUsers = getUsers;
|
|
19
|
+
exports.revokePermissionFromRole = revokePermissionFromRole;
|
|
20
|
+
exports.revokePermissionFromUser = revokePermissionFromUser;
|
|
21
|
+
exports.revokeRoleFromUser = revokeRoleFromUser;
|
|
22
|
+
var _server = _interopRequireWildcard(require("@arch-cadre/core/server"));
|
|
23
|
+
var rbac = _server;
|
|
24
|
+
var _cache = require("next/cache");
|
|
25
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
26
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
27
|
+
async function getRoles() {
|
|
28
|
+
return await rbac.getRoles();
|
|
29
|
+
}
|
|
30
|
+
async function createRole(name, description) {
|
|
31
|
+
const result = await rbac.createRole(name, description);
|
|
32
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
33
|
+
return JSON.parse(JSON.stringify(result));
|
|
34
|
+
}
|
|
35
|
+
async function deleteRole(roleId) {
|
|
36
|
+
await rbac.deleteRole(roleId);
|
|
37
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
38
|
+
return {
|
|
39
|
+
success: true
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
async function getPermissions() {
|
|
43
|
+
return await rbac.getPermissions();
|
|
44
|
+
}
|
|
45
|
+
async function createPermission(name, description) {
|
|
46
|
+
const result = await rbac.createPermission(name, description);
|
|
47
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
48
|
+
return JSON.parse(JSON.stringify(result));
|
|
49
|
+
}
|
|
50
|
+
async function deletePermission(permissionId) {
|
|
51
|
+
await rbac.deletePermission(permissionId);
|
|
52
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
53
|
+
return {
|
|
54
|
+
success: true
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
async function getRolePermissions(roleId) {
|
|
58
|
+
return await rbac.getRolePermissions(roleId);
|
|
59
|
+
}
|
|
60
|
+
async function assignPermissionToRole(roleId, permissionId) {
|
|
61
|
+
await rbac.assignPermissionToRole(roleId, permissionId);
|
|
62
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
63
|
+
return {
|
|
64
|
+
success: true
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async function revokePermissionFromRole(roleId, permissionId) {
|
|
68
|
+
await rbac.revokePermissionFromRole(roleId, permissionId);
|
|
69
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
70
|
+
return {
|
|
71
|
+
success: true
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
async function getUsers() {
|
|
75
|
+
return await _server.db.select({
|
|
76
|
+
id: _server.userTable.id,
|
|
77
|
+
name: _server.userTable.name,
|
|
78
|
+
email: _server.userTable.email,
|
|
79
|
+
image: _server.userTable.image
|
|
80
|
+
}).from(_server.userTable);
|
|
81
|
+
}
|
|
82
|
+
async function getUserRbacData(userId) {
|
|
83
|
+
return await rbac.getUserRbacData(userId);
|
|
84
|
+
}
|
|
85
|
+
async function assignRoleToUser(userId, roleId) {
|
|
86
|
+
const role = await rbac.getRoleById(roleId);
|
|
87
|
+
await rbac.assignRoleToUser(userId, roleId);
|
|
88
|
+
if (role) {
|
|
89
|
+
await _server.eventBus.publish("notification:send", {
|
|
90
|
+
userId,
|
|
91
|
+
title: "Role assigned",
|
|
92
|
+
content: `You have been assigned the role: ${role.name}`,
|
|
93
|
+
type: "info"
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
97
|
+
return {
|
|
98
|
+
success: true
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function revokeRoleFromUser(userId, roleId) {
|
|
102
|
+
const role = await rbac.getRoleById(roleId);
|
|
103
|
+
await rbac.revokeRoleFromUser(userId, roleId);
|
|
104
|
+
if (role) {
|
|
105
|
+
await _server.eventBus.publish("notification:send", {
|
|
106
|
+
userId,
|
|
107
|
+
title: "Role revoked",
|
|
108
|
+
content: `The role ${role.name} has been removed from your account`,
|
|
109
|
+
type: "warning"
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
113
|
+
return {
|
|
114
|
+
success: true
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async function assignPermissionToUser(userId, permissionId) {
|
|
118
|
+
await rbac.assignPermissionToUser(userId, permissionId);
|
|
119
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
120
|
+
return {
|
|
121
|
+
success: true
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
async function revokePermissionFromUser(userId, permissionId) {
|
|
125
|
+
await rbac.revokePermissionFromUser(userId, permissionId);
|
|
126
|
+
(0, _cache.revalidatePath)("/", "layout");
|
|
127
|
+
return {
|
|
128
|
+
success: true
|
|
129
|
+
};
|
|
130
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RBAC Manager Module Actions
|
|
3
|
+
* These actions act as a bridge between the UI and the Core RBAC Logic.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getRoles(): Promise<any>;
|
|
6
|
+
export declare function createRole(name: string, description?: string): Promise<any>;
|
|
7
|
+
export declare function deleteRole(roleId: string): Promise<{
|
|
8
|
+
success: boolean;
|
|
9
|
+
}>;
|
|
10
|
+
export declare function getPermissions(): Promise<any>;
|
|
11
|
+
export declare function createPermission(name: string, description?: string): Promise<any>;
|
|
12
|
+
export declare function deletePermission(permissionId: string): Promise<{
|
|
13
|
+
success: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function getRolePermissions(roleId: string): Promise<any>;
|
|
16
|
+
export declare function assignPermissionToRole(roleId: string, permissionId: string): Promise<{
|
|
17
|
+
success: boolean;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function revokePermissionFromRole(roleId: string, permissionId: string): Promise<{
|
|
20
|
+
success: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function getUsers(): Promise<any>;
|
|
23
|
+
export declare function getUserRbacData(userId: string): Promise<any>;
|
|
24
|
+
export declare function assignRoleToUser(userId: string, roleId: string): Promise<{
|
|
25
|
+
success: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function revokeRoleFromUser(userId: string, roleId: string): Promise<{
|
|
28
|
+
success: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
export declare function assignPermissionToUser(userId: string, permissionId: string): Promise<{
|
|
31
|
+
success: boolean;
|
|
32
|
+
}>;
|
|
33
|
+
export declare function revokePermissionFromUser(userId: string, permissionId: string): Promise<{
|
|
34
|
+
success: boolean;
|
|
35
|
+
}>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
import * as rbac from "@arch-cadre/core/server";
|
|
3
|
+
import { db, eventBus, userTable } from "@arch-cadre/core/server";
|
|
4
|
+
import { revalidatePath } from "next/cache";
|
|
5
|
+
export async function getRoles() {
|
|
6
|
+
return await rbac.getRoles();
|
|
7
|
+
}
|
|
8
|
+
export async function createRole(name, description) {
|
|
9
|
+
const result = await rbac.createRole(name, description);
|
|
10
|
+
revalidatePath("/", "layout");
|
|
11
|
+
return JSON.parse(JSON.stringify(result));
|
|
12
|
+
}
|
|
13
|
+
export async function deleteRole(roleId) {
|
|
14
|
+
await rbac.deleteRole(roleId);
|
|
15
|
+
revalidatePath("/", "layout");
|
|
16
|
+
return { success: true };
|
|
17
|
+
}
|
|
18
|
+
export async function getPermissions() {
|
|
19
|
+
return await rbac.getPermissions();
|
|
20
|
+
}
|
|
21
|
+
export async function createPermission(name, description) {
|
|
22
|
+
const result = await rbac.createPermission(name, description);
|
|
23
|
+
revalidatePath("/", "layout");
|
|
24
|
+
return JSON.parse(JSON.stringify(result));
|
|
25
|
+
}
|
|
26
|
+
export async function deletePermission(permissionId) {
|
|
27
|
+
await rbac.deletePermission(permissionId);
|
|
28
|
+
revalidatePath("/", "layout");
|
|
29
|
+
return { success: true };
|
|
30
|
+
}
|
|
31
|
+
export async function getRolePermissions(roleId) {
|
|
32
|
+
return await rbac.getRolePermissions(roleId);
|
|
33
|
+
}
|
|
34
|
+
export async function assignPermissionToRole(roleId, permissionId) {
|
|
35
|
+
await rbac.assignPermissionToRole(roleId, permissionId);
|
|
36
|
+
revalidatePath("/", "layout");
|
|
37
|
+
return { success: true };
|
|
38
|
+
}
|
|
39
|
+
export async function revokePermissionFromRole(roleId, permissionId) {
|
|
40
|
+
await rbac.revokePermissionFromRole(roleId, permissionId);
|
|
41
|
+
revalidatePath("/", "layout");
|
|
42
|
+
return { success: true };
|
|
43
|
+
}
|
|
44
|
+
export async function getUsers() {
|
|
45
|
+
return await db.select({
|
|
46
|
+
id: userTable.id,
|
|
47
|
+
name: userTable.name,
|
|
48
|
+
email: userTable.email,
|
|
49
|
+
image: userTable.image
|
|
50
|
+
}).from(userTable);
|
|
51
|
+
}
|
|
52
|
+
export async function getUserRbacData(userId) {
|
|
53
|
+
return await rbac.getUserRbacData(userId);
|
|
54
|
+
}
|
|
55
|
+
export async function assignRoleToUser(userId, roleId) {
|
|
56
|
+
const role = await rbac.getRoleById(roleId);
|
|
57
|
+
await rbac.assignRoleToUser(userId, roleId);
|
|
58
|
+
if (role) {
|
|
59
|
+
await eventBus.publish("notification:send", {
|
|
60
|
+
userId,
|
|
61
|
+
title: "Role assigned",
|
|
62
|
+
content: `You have been assigned the role: ${role.name}`,
|
|
63
|
+
type: "info"
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
revalidatePath("/", "layout");
|
|
67
|
+
return { success: true };
|
|
68
|
+
}
|
|
69
|
+
export async function revokeRoleFromUser(userId, roleId) {
|
|
70
|
+
const role = await rbac.getRoleById(roleId);
|
|
71
|
+
await rbac.revokeRoleFromUser(userId, roleId);
|
|
72
|
+
if (role) {
|
|
73
|
+
await eventBus.publish("notification:send", {
|
|
74
|
+
userId,
|
|
75
|
+
title: "Role revoked",
|
|
76
|
+
content: `The role ${role.name} has been removed from your account`,
|
|
77
|
+
type: "warning"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
revalidatePath("/", "layout");
|
|
81
|
+
return { success: true };
|
|
82
|
+
}
|
|
83
|
+
export async function assignPermissionToUser(userId, permissionId) {
|
|
84
|
+
await rbac.assignPermissionToUser(userId, permissionId);
|
|
85
|
+
revalidatePath("/", "layout");
|
|
86
|
+
return { success: true };
|
|
87
|
+
}
|
|
88
|
+
export async function revokePermissionFromUser(userId, permissionId) {
|
|
89
|
+
await rbac.revokePermissionFromUser(userId, permissionId);
|
|
90
|
+
revalidatePath("/", "layout");
|
|
91
|
+
return { success: true };
|
|
92
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use server";
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getSessionsAction = getSessionsAction;
|
|
8
|
+
exports.revokeAllOtherSessionsAction = revokeAllOtherSessionsAction;
|
|
9
|
+
exports.revokeSessionAction = revokeSessionAction;
|
|
10
|
+
var _server = require("@arch-cadre/core/server");
|
|
11
|
+
var _server2 = require("@arch-cadre/intl/server");
|
|
12
|
+
var _cache = require("next/cache");
|
|
13
|
+
async function getSessionsAction() {
|
|
14
|
+
const {
|
|
15
|
+
t
|
|
16
|
+
} = await (0, _server2.getTranslation)();
|
|
17
|
+
const {
|
|
18
|
+
session,
|
|
19
|
+
user
|
|
20
|
+
} = await (0, _server.getCurrentSession)();
|
|
21
|
+
if (!session || !user) return {
|
|
22
|
+
error: t("Not authenticated"),
|
|
23
|
+
sessions: []
|
|
24
|
+
};
|
|
25
|
+
const sessions = await (0, _server.getUserSessions)(user.id, session.id);
|
|
26
|
+
const sortedSessions = sessions.sort((a, b) => {
|
|
27
|
+
if (a.isCurrent) return -1;
|
|
28
|
+
if (b.isCurrent) return 1;
|
|
29
|
+
return b.createdAt.getTime() - a.createdAt.getTime();
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
sessions: sortedSessions.map(s => ({
|
|
33
|
+
id: s.id,
|
|
34
|
+
createdAt: s.createdAt,
|
|
35
|
+
expiresAt: s.expiresAt,
|
|
36
|
+
twoFactorVerified: s.twoFactorVerified,
|
|
37
|
+
isCurrent: s.isCurrent
|
|
38
|
+
}))
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
async function revokeSessionAction(sessionId) {
|
|
42
|
+
const {
|
|
43
|
+
t
|
|
44
|
+
} = await (0, _server2.getTranslation)();
|
|
45
|
+
const {
|
|
46
|
+
session,
|
|
47
|
+
user
|
|
48
|
+
} = await (0, _server.getCurrentSession)();
|
|
49
|
+
if (!session || !user) return {
|
|
50
|
+
error: t("Not authenticated")
|
|
51
|
+
};
|
|
52
|
+
if (sessionId === session.id) {
|
|
53
|
+
return {
|
|
54
|
+
error: t("Cannot revoke current session. Use sign out instead.")
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const userSessions = await (0, _server.getUserSessions)(user.id, session.id);
|
|
58
|
+
if (!userSessions.find(s => s.id === sessionId)) {
|
|
59
|
+
return {
|
|
60
|
+
error: t("Session not found")
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
await (0, _server.invalidateSession)(sessionId);
|
|
64
|
+
(0, _cache.revalidatePath)("/settings/sessions");
|
|
65
|
+
await _server.eventBus.publish("activity.create", {
|
|
66
|
+
action: "session.revoked",
|
|
67
|
+
description: `User ${user?.name} revoked a session`,
|
|
68
|
+
userId: user?.id,
|
|
69
|
+
metadata: {
|
|
70
|
+
sessionId
|
|
71
|
+
}
|
|
72
|
+
}, "session-manager");
|
|
73
|
+
return {
|
|
74
|
+
success: true
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function revokeAllOtherSessionsAction() {
|
|
78
|
+
const {
|
|
79
|
+
session,
|
|
80
|
+
user
|
|
81
|
+
} = await (0, _server.getCurrentSession)();
|
|
82
|
+
const {
|
|
83
|
+
t
|
|
84
|
+
} = await (0, _server2.getTranslation)();
|
|
85
|
+
if (!session || !user) return {
|
|
86
|
+
error: t("Not authenticated")
|
|
87
|
+
};
|
|
88
|
+
await (0, _server.invalidateOtherSessions)(user.id, session.id);
|
|
89
|
+
(0, _cache.revalidatePath)("/settings/sessions");
|
|
90
|
+
await _server.eventBus.publish("activity.create", {
|
|
91
|
+
action: "session.revoked.all-others",
|
|
92
|
+
description: `User ${user?.name} revoked all other sessions`,
|
|
93
|
+
userId: user?.id,
|
|
94
|
+
metadata: {}
|
|
95
|
+
}, "session-manager");
|
|
96
|
+
return {
|
|
97
|
+
success: true
|
|
98
|
+
};
|
|
99
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare function getSessionsAction(): Promise<{
|
|
2
|
+
error: any;
|
|
3
|
+
sessions: never[];
|
|
4
|
+
} | {
|
|
5
|
+
sessions: any;
|
|
6
|
+
error?: undefined;
|
|
7
|
+
}>;
|
|
8
|
+
export declare function revokeSessionAction(sessionId: string): Promise<{
|
|
9
|
+
error: any;
|
|
10
|
+
success?: undefined;
|
|
11
|
+
} | {
|
|
12
|
+
success: boolean;
|
|
13
|
+
error?: undefined;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function revokeAllOtherSessionsAction(): Promise<{
|
|
16
|
+
error: any;
|
|
17
|
+
success?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
success: boolean;
|
|
20
|
+
error?: undefined;
|
|
21
|
+
}>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
import {
|
|
3
|
+
eventBus,
|
|
4
|
+
getCurrentSession,
|
|
5
|
+
getUserSessions,
|
|
6
|
+
invalidateOtherSessions,
|
|
7
|
+
invalidateSession
|
|
8
|
+
} from "@arch-cadre/core/server";
|
|
9
|
+
import { getTranslation } from "@arch-cadre/intl/server";
|
|
10
|
+
import { revalidatePath } from "next/cache";
|
|
11
|
+
export async function getSessionsAction() {
|
|
12
|
+
const { t } = await getTranslation();
|
|
13
|
+
const { session, user } = await getCurrentSession();
|
|
14
|
+
if (!session || !user) return { error: t("Not authenticated"), sessions: [] };
|
|
15
|
+
const sessions = await getUserSessions(user.id, session.id);
|
|
16
|
+
const sortedSessions = sessions.sort((a, b) => {
|
|
17
|
+
if (a.isCurrent) return -1;
|
|
18
|
+
if (b.isCurrent) return 1;
|
|
19
|
+
return b.createdAt.getTime() - a.createdAt.getTime();
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
sessions: sortedSessions.map((s) => ({
|
|
23
|
+
id: s.id,
|
|
24
|
+
createdAt: s.createdAt,
|
|
25
|
+
expiresAt: s.expiresAt,
|
|
26
|
+
twoFactorVerified: s.twoFactorVerified,
|
|
27
|
+
isCurrent: s.isCurrent
|
|
28
|
+
}))
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export async function revokeSessionAction(sessionId) {
|
|
32
|
+
const { t } = await getTranslation();
|
|
33
|
+
const { session, user } = await getCurrentSession();
|
|
34
|
+
if (!session || !user) return { error: t("Not authenticated") };
|
|
35
|
+
if (sessionId === session.id) {
|
|
36
|
+
return { error: t("Cannot revoke current session. Use sign out instead.") };
|
|
37
|
+
}
|
|
38
|
+
const userSessions = await getUserSessions(user.id, session.id);
|
|
39
|
+
if (!userSessions.find((s) => s.id === sessionId)) {
|
|
40
|
+
return { error: t("Session not found") };
|
|
41
|
+
}
|
|
42
|
+
await invalidateSession(sessionId);
|
|
43
|
+
revalidatePath("/settings/sessions");
|
|
44
|
+
await eventBus.publish(
|
|
45
|
+
"activity.create",
|
|
46
|
+
{
|
|
47
|
+
action: "session.revoked",
|
|
48
|
+
description: `User ${user?.name} revoked a session`,
|
|
49
|
+
userId: user?.id,
|
|
50
|
+
metadata: { sessionId }
|
|
51
|
+
},
|
|
52
|
+
"session-manager"
|
|
53
|
+
);
|
|
54
|
+
return { success: true };
|
|
55
|
+
}
|
|
56
|
+
export async function revokeAllOtherSessionsAction() {
|
|
57
|
+
const { session, user } = await getCurrentSession();
|
|
58
|
+
const { t } = await getTranslation();
|
|
59
|
+
if (!session || !user) return { error: t("Not authenticated") };
|
|
60
|
+
await invalidateOtherSessions(user.id, session.id);
|
|
61
|
+
revalidatePath("/settings/sessions");
|
|
62
|
+
await eventBus.publish(
|
|
63
|
+
"activity.create",
|
|
64
|
+
{
|
|
65
|
+
action: "session.revoked.all-others",
|
|
66
|
+
description: `User ${user?.name} revoked all other sessions`,
|
|
67
|
+
userId: user?.id,
|
|
68
|
+
metadata: {}
|
|
69
|
+
},
|
|
70
|
+
"session-manager"
|
|
71
|
+
);
|
|
72
|
+
return { success: true };
|
|
73
|
+
}
|
package/dist/index.cjs
CHANGED
|
@@ -4,14 +4,81 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
|
|
7
|
+
var _server = require("@arch-cadre/core/server");
|
|
7
8
|
var _manifest = _interopRequireDefault(require("../manifest.json"));
|
|
8
9
|
var _navigation = require("./navigation.cjs");
|
|
9
10
|
var _routes = require("./routes.cjs");
|
|
11
|
+
var _activityLog = require("./schema/activity-log.cjs");
|
|
12
|
+
var _ActivityStatsWidget = _interopRequireDefault(require("./ui/activity-log/components/ActivityStatsWidget.cjs"));
|
|
13
|
+
var _RecentLogsWidget = _interopRequireDefault(require("./ui/activity-log/components/RecentLogsWidget.cjs"));
|
|
10
14
|
var _link = require("./ui/components/profile/link.cjs");
|
|
15
|
+
var _WelcomeBackUserWidget = _interopRequireDefault(require("./ui/dashboard/widgets/WelcomeBackUserWidget.cjs"));
|
|
11
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
17
|
const kryoPanelModule = {
|
|
13
18
|
manifest: _manifest.default,
|
|
14
|
-
init: async () => {
|
|
19
|
+
init: async () => {
|
|
20
|
+
console.log("[ActivityLog] Registering core system listeners...");
|
|
21
|
+
const logEvent = async (event, descriptionOverride) => {
|
|
22
|
+
try {
|
|
23
|
+
const userId = event.payload?.userId || void 0;
|
|
24
|
+
await _server.db.insert(_activityLog.activityLogsTable).values({
|
|
25
|
+
userId,
|
|
26
|
+
action: event.type,
|
|
27
|
+
description: descriptionOverride || `System event: ${event.type}`,
|
|
28
|
+
metadata: event.payload
|
|
29
|
+
});
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error(`[ActivityLog] Failed to save log for ${event.type}:`, error);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
_server.eventBus.subscribe("activity.create", "activity-log-manual", async event => {
|
|
35
|
+
const {
|
|
36
|
+
action,
|
|
37
|
+
description,
|
|
38
|
+
userId,
|
|
39
|
+
metadata
|
|
40
|
+
} = event.payload;
|
|
41
|
+
await _server.db.insert(_activityLog.activityLogsTable).values({
|
|
42
|
+
userId,
|
|
43
|
+
action,
|
|
44
|
+
description,
|
|
45
|
+
metadata
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
_server.eventBus.subscribe("auth:login", "activity-log-auth", e => logEvent(e, `User logged in: ${e.payload.email}`));
|
|
49
|
+
_server.eventBus.subscribe("auth:signup", "activity-log-auth", e => logEvent(e, `New user registered: ${e.payload.email}`));
|
|
50
|
+
_server.eventBus.subscribe("auth:logout", "activity-log-auth", e => logEvent(e, `User logged out: ${e.payload.email}`));
|
|
51
|
+
_server.eventBus.subscribe("system:module:toggle", "activity-log-system", e => logEvent(e, `Module "${e.payload.moduleId}" ${e.payload.isEnabled ? "enabled" : "disabled"}`));
|
|
52
|
+
_server.eventBus.subscribe("system:module:upload", "activity-log-system", e => logEvent(e, `New module uploaded: "${e.payload.moduleId}"`));
|
|
53
|
+
},
|
|
54
|
+
onDisable: async () => {
|
|
55
|
+
console.log("[ActivityLog] Unsubscribing listeners...");
|
|
56
|
+
_server.eventBus.unsubscribe("activity.create", "activity-log-manual");
|
|
57
|
+
_server.eventBus.unsubscribe("auth:login", "activity-log-auth");
|
|
58
|
+
_server.eventBus.unsubscribe("auth:signup", "activity-log-auth");
|
|
59
|
+
_server.eventBus.unsubscribe("auth:logout", "activity-log-auth");
|
|
60
|
+
_server.eventBus.unsubscribe("system:module:toggle", "activity-log-system");
|
|
61
|
+
_server.eventBus.unsubscribe("system:module:upload", "activity-log-system");
|
|
62
|
+
},
|
|
63
|
+
widgets: [{
|
|
64
|
+
id: "welcome-back-user",
|
|
65
|
+
name: "Welcome Back User",
|
|
66
|
+
area: "dashboard-stats",
|
|
67
|
+
component: _WelcomeBackUserWidget.default,
|
|
68
|
+
priority: 0
|
|
69
|
+
}, {
|
|
70
|
+
id: "recent-activity",
|
|
71
|
+
name: "Recent Activity",
|
|
72
|
+
area: "dashboard-main",
|
|
73
|
+
component: _RecentLogsWidget.default,
|
|
74
|
+
priority: 10
|
|
75
|
+
}, {
|
|
76
|
+
id: "activity-stats",
|
|
77
|
+
name: "Activity Stats",
|
|
78
|
+
area: "dashboard-stats",
|
|
79
|
+
component: _ActivityStatsWidget.default,
|
|
80
|
+
priority: 10
|
|
81
|
+
}],
|
|
15
82
|
routes: {
|
|
16
83
|
public: _routes.publicRoutes,
|
|
17
84
|
private: _routes.privateRoutes,
|
package/dist/index.d.ts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,101 @@
|
|
|
1
|
+
import { db, eventBus } from "@arch-cadre/core/server";
|
|
1
2
|
import manifest from "../manifest.json";
|
|
2
3
|
import { navigation } from "./navigation.mjs";
|
|
3
4
|
import { apiRoutes, privateRoutes, publicRoutes } from "./routes.mjs";
|
|
5
|
+
import { activityLogsTable } from "./schema/activity-log.mjs";
|
|
6
|
+
import ActivityStatsWidget from "./ui/activity-log/components/ActivityStatsWidget.mjs";
|
|
7
|
+
import RecentLogsWidget from "./ui/activity-log/components/RecentLogsWidget.mjs";
|
|
4
8
|
import { UserDropdownLink } from "./ui/components/profile/link.mjs";
|
|
9
|
+
import WelcomeBackUserWidget from "./ui/dashboard/widgets/WelcomeBackUserWidget.mjs";
|
|
5
10
|
const kryoPanelModule = {
|
|
6
11
|
manifest,
|
|
7
12
|
init: async () => {
|
|
13
|
+
console.log("[ActivityLog] Registering core system listeners...");
|
|
14
|
+
const logEvent = async (event, descriptionOverride) => {
|
|
15
|
+
try {
|
|
16
|
+
const userId = event.payload?.userId || void 0;
|
|
17
|
+
await db.insert(activityLogsTable).values({
|
|
18
|
+
userId,
|
|
19
|
+
action: event.type,
|
|
20
|
+
description: descriptionOverride || `System event: ${event.type}`,
|
|
21
|
+
metadata: event.payload
|
|
22
|
+
});
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(
|
|
25
|
+
`[ActivityLog] Failed to save log for ${event.type}:`,
|
|
26
|
+
error
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
eventBus.subscribe(
|
|
31
|
+
"activity.create",
|
|
32
|
+
"activity-log-manual",
|
|
33
|
+
async (event) => {
|
|
34
|
+
const { action, description, userId, metadata } = event.payload;
|
|
35
|
+
await db.insert(activityLogsTable).values({ userId, action, description, metadata });
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
eventBus.subscribe(
|
|
39
|
+
"auth:login",
|
|
40
|
+
"activity-log-auth",
|
|
41
|
+
(e) => logEvent(e, `User logged in: ${e.payload.email}`)
|
|
42
|
+
);
|
|
43
|
+
eventBus.subscribe(
|
|
44
|
+
"auth:signup",
|
|
45
|
+
"activity-log-auth",
|
|
46
|
+
(e) => logEvent(e, `New user registered: ${e.payload.email}`)
|
|
47
|
+
);
|
|
48
|
+
eventBus.subscribe(
|
|
49
|
+
"auth:logout",
|
|
50
|
+
"activity-log-auth",
|
|
51
|
+
(e) => logEvent(e, `User logged out: ${e.payload.email}`)
|
|
52
|
+
);
|
|
53
|
+
eventBus.subscribe(
|
|
54
|
+
"system:module:toggle",
|
|
55
|
+
"activity-log-system",
|
|
56
|
+
(e) => logEvent(
|
|
57
|
+
e,
|
|
58
|
+
`Module "${e.payload.moduleId}" ${e.payload.isEnabled ? "enabled" : "disabled"}`
|
|
59
|
+
)
|
|
60
|
+
);
|
|
61
|
+
eventBus.subscribe(
|
|
62
|
+
"system:module:upload",
|
|
63
|
+
"activity-log-system",
|
|
64
|
+
(e) => logEvent(e, `New module uploaded: "${e.payload.moduleId}"`)
|
|
65
|
+
);
|
|
8
66
|
},
|
|
67
|
+
onDisable: async () => {
|
|
68
|
+
console.log("[ActivityLog] Unsubscribing listeners...");
|
|
69
|
+
eventBus.unsubscribe("activity.create", "activity-log-manual");
|
|
70
|
+
eventBus.unsubscribe("auth:login", "activity-log-auth");
|
|
71
|
+
eventBus.unsubscribe("auth:signup", "activity-log-auth");
|
|
72
|
+
eventBus.unsubscribe("auth:logout", "activity-log-auth");
|
|
73
|
+
eventBus.unsubscribe("system:module:toggle", "activity-log-system");
|
|
74
|
+
eventBus.unsubscribe("system:module:upload", "activity-log-system");
|
|
75
|
+
},
|
|
76
|
+
widgets: [
|
|
77
|
+
{
|
|
78
|
+
id: "welcome-back-user",
|
|
79
|
+
name: "Welcome Back User",
|
|
80
|
+
area: "dashboard-stats",
|
|
81
|
+
component: WelcomeBackUserWidget,
|
|
82
|
+
priority: 0
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "recent-activity",
|
|
86
|
+
name: "Recent Activity",
|
|
87
|
+
area: "dashboard-main",
|
|
88
|
+
component: RecentLogsWidget,
|
|
89
|
+
priority: 10
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: "activity-stats",
|
|
93
|
+
name: "Activity Stats",
|
|
94
|
+
area: "dashboard-stats",
|
|
95
|
+
component: ActivityStatsWidget,
|
|
96
|
+
priority: 10
|
|
97
|
+
}
|
|
98
|
+
],
|
|
9
99
|
routes: {
|
|
10
100
|
public: publicRoutes,
|
|
11
101
|
private: privateRoutes,
|