@cyberismo/backend 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts +5 -2
- package/dist/app.js +25 -10
- package/dist/app.js.map +1 -1
- package/dist/auth/index.d.ts +16 -0
- package/dist/auth/index.js +15 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/keycloak.d.ts +27 -0
- package/dist/auth/keycloak.js +81 -0
- package/dist/auth/keycloak.js.map +1 -0
- package/dist/auth/mock.d.ts +23 -0
- package/dist/auth/mock.js +28 -0
- package/dist/auth/mock.js.map +1 -0
- package/dist/auth/types.d.ts +16 -0
- package/dist/auth/types.js +14 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/domain/auth/index.d.ts +14 -0
- package/dist/domain/auth/index.js +30 -0
- package/dist/domain/auth/index.js.map +1 -0
- package/dist/domain/calculations/index.js +3 -1
- package/dist/domain/calculations/index.js.map +1 -1
- package/dist/domain/calculations/service.js +13 -11
- package/dist/domain/calculations/service.js.map +1 -1
- package/dist/domain/cardTypes/index.js +5 -3
- package/dist/domain/cardTypes/index.js.map +1 -1
- package/dist/domain/cardTypes/service.js +24 -72
- package/dist/domain/cardTypes/service.js.map +1 -1
- package/dist/domain/cards/index.js +124 -25
- package/dist/domain/cards/index.js.map +1 -1
- package/dist/domain/cards/lib.js +92 -93
- package/dist/domain/cards/lib.js.map +1 -1
- package/dist/domain/cards/presence.d.ts +50 -0
- package/dist/domain/cards/presence.js +93 -0
- package/dist/domain/cards/presence.js.map +1 -0
- package/dist/domain/cards/schema.d.ts +47 -0
- package/dist/domain/cards/schema.js +37 -0
- package/dist/domain/cards/schema.js.map +1 -0
- package/dist/domain/cards/service.d.ts +7 -3
- package/dist/domain/cards/service.js +81 -91
- package/dist/domain/cards/service.js.map +1 -1
- package/dist/domain/connectors/index.d.ts +15 -0
- package/dist/domain/connectors/index.js +37 -0
- package/dist/domain/connectors/index.js.map +1 -0
- package/dist/domain/connectors/service.d.ts +23 -0
- package/dist/domain/connectors/service.js +46 -0
- package/dist/domain/connectors/service.js.map +1 -0
- package/dist/domain/fieldTypes/index.js +4 -2
- package/dist/domain/fieldTypes/index.js.map +1 -1
- package/dist/domain/graphModels/index.js +3 -1
- package/dist/domain/graphModels/index.js.map +1 -1
- package/dist/domain/graphViews/index.js +3 -1
- package/dist/domain/graphViews/index.js.map +1 -1
- package/dist/domain/labels/index.js +4 -2
- package/dist/domain/labels/index.js.map +1 -1
- package/dist/domain/labels/service.d.ts +1 -1
- package/dist/domain/labels/service.js +2 -2
- package/dist/domain/labels/service.js.map +1 -1
- package/dist/domain/linkTypes/index.js +4 -2
- package/dist/domain/linkTypes/index.js.map +1 -1
- package/dist/domain/logicPrograms/index.js +3 -1
- package/dist/domain/logicPrograms/index.js.map +1 -1
- package/dist/domain/mcp/index.d.ts +15 -0
- package/dist/domain/mcp/index.js +127 -0
- package/dist/domain/mcp/index.js.map +1 -0
- package/dist/domain/project/index.js +19 -6
- package/dist/domain/project/index.js.map +1 -1
- package/dist/domain/project/schema.d.ts +3 -0
- package/dist/domain/project/schema.js +8 -0
- package/dist/domain/project/schema.js.map +1 -1
- package/dist/domain/project/service.d.ts +3 -1
- package/dist/domain/project/service.js +24 -14
- package/dist/domain/project/service.js.map +1 -1
- package/dist/domain/reports/index.js +3 -1
- package/dist/domain/reports/index.js.map +1 -1
- package/dist/domain/resources/index.js +6 -4
- package/dist/domain/resources/index.js.map +1 -1
- package/dist/domain/resources/service.js +66 -64
- package/dist/domain/resources/service.js.map +1 -1
- package/dist/domain/templates/index.js +5 -3
- package/dist/domain/templates/index.js.map +1 -1
- package/dist/domain/tree/index.js +3 -1
- package/dist/domain/tree/index.js.map +1 -1
- package/dist/domain/tree/service.js +0 -1
- package/dist/domain/tree/service.js.map +1 -1
- package/dist/domain/workflows/index.js +3 -1
- package/dist/domain/workflows/index.js.map +1 -1
- package/dist/export.d.ts +6 -5
- package/dist/export.js +16 -13
- package/dist/export.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +12 -4
- package/dist/index.js.map +1 -1
- package/dist/main.js +29 -2
- package/dist/main.js.map +1 -1
- package/dist/middleware/auth.d.ts +40 -0
- package/dist/middleware/auth.js +68 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/commandManager.d.ts +2 -2
- package/dist/middleware/commandManager.js +9 -11
- package/dist/middleware/commandManager.js.map +1 -1
- package/dist/public/THIRD-PARTY.txt +1212 -605
- package/dist/public/assets/index-Cdn_jRWy.js +720 -0
- package/dist/public/assets/index-ypsafPwV.css +1 -0
- package/dist/public/config.json +1 -0
- package/dist/public/images/broken_link.svg +7 -0
- package/dist/public/index.html +2 -2
- package/dist/types.d.ts +25 -0
- package/dist/types.js +13 -1
- package/dist/types.js.map +1 -1
- package/package.json +10 -7
- package/src/app.ts +37 -15
- package/src/auth/index.ts +17 -0
- package/src/auth/keycloak.ts +109 -0
- package/src/auth/mock.ts +38 -0
- package/src/auth/types.ts +18 -0
- package/src/domain/auth/index.ts +35 -0
- package/src/domain/calculations/index.ts +13 -6
- package/src/domain/calculations/service.ts +16 -14
- package/src/domain/cardTypes/index.ts +24 -16
- package/src/domain/cardTypes/service.ts +41 -95
- package/src/domain/cards/index.ts +258 -90
- package/src/domain/cards/lib.ts +102 -100
- package/src/domain/cards/presence.ts +124 -0
- package/src/domain/cards/schema.ts +41 -0
- package/src/domain/cards/service.ts +138 -93
- package/src/domain/connectors/index.ts +39 -0
- package/src/domain/connectors/service.ts +67 -0
- package/src/domain/fieldTypes/index.ts +23 -16
- package/src/domain/graphModels/index.ts +13 -6
- package/src/domain/graphViews/index.ts +13 -6
- package/src/domain/labels/index.ts +5 -2
- package/src/domain/labels/service.ts +2 -2
- package/src/domain/linkTypes/index.ts +14 -7
- package/src/domain/logicPrograms/index.ts +3 -0
- package/src/domain/mcp/index.ts +159 -0
- package/src/domain/project/index.ts +40 -9
- package/src/domain/project/schema.ts +9 -0
- package/src/domain/project/service.ts +37 -17
- package/src/domain/reports/index.ts +13 -6
- package/src/domain/resources/index.ts +6 -1
- package/src/domain/resources/service.ts +102 -97
- package/src/domain/templates/index.ts +31 -19
- package/src/domain/tree/index.ts +3 -1
- package/src/domain/tree/service.ts +0 -1
- package/src/domain/workflows/index.ts +13 -6
- package/src/export.ts +17 -15
- package/src/index.ts +18 -7
- package/src/main.ts +44 -2
- package/src/middleware/auth.ts +90 -0
- package/src/middleware/commandManager.ts +11 -14
- package/src/types.ts +27 -0
- package/dist/public/assets/index-CRSBseQM.css +0 -1
- package/dist/public/assets/index-Ca10XaMv.js +0 -164156
|
@@ -15,6 +15,8 @@ import { Hono } from 'hono';
|
|
|
15
15
|
import * as reportService from './service.js';
|
|
16
16
|
import { createReportSchema } from './schema.js';
|
|
17
17
|
import { zValidator } from '../../middleware/zvalidator.js';
|
|
18
|
+
import { UserRole } from '../../types.js';
|
|
19
|
+
import { requireRole } from '../../middleware/auth.js';
|
|
18
20
|
|
|
19
21
|
const router = new Hono();
|
|
20
22
|
|
|
@@ -43,12 +45,17 @@ const router = new Hono();
|
|
|
43
45
|
* 500:
|
|
44
46
|
* description: Server error
|
|
45
47
|
*/
|
|
46
|
-
router.post(
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
router.post(
|
|
49
|
+
'/',
|
|
50
|
+
requireRole(UserRole.Admin),
|
|
51
|
+
zValidator('json', createReportSchema),
|
|
52
|
+
async (c) => {
|
|
53
|
+
const commands = c.get('commands');
|
|
54
|
+
const { identifier } = c.req.valid('json');
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
56
|
+
await reportService.createReport(commands, identifier);
|
|
57
|
+
return c.json({ message: 'Report created successfully' });
|
|
58
|
+
},
|
|
59
|
+
);
|
|
53
60
|
|
|
54
61
|
export default router;
|
|
@@ -14,12 +14,14 @@
|
|
|
14
14
|
import { Hono } from 'hono';
|
|
15
15
|
import * as resourceService from './service.js';
|
|
16
16
|
import type { ResourceValidationResponse } from '../../types.js';
|
|
17
|
+
import { UserRole } from '../../types.js';
|
|
17
18
|
import { resourceParamsSchema } from '../../common/validationSchemas.js';
|
|
18
19
|
import { zValidator } from '../../middleware/zvalidator.js';
|
|
19
20
|
import {
|
|
20
21
|
validateResourceParamsSchema,
|
|
21
22
|
updateOperationBodySchema,
|
|
22
23
|
} from './schema.js';
|
|
24
|
+
import { requireRole } from '../../middleware/auth.js';
|
|
23
25
|
|
|
24
26
|
const router = new Hono();
|
|
25
27
|
|
|
@@ -35,7 +37,7 @@ const router = new Hono();
|
|
|
35
37
|
* 500:
|
|
36
38
|
* description: project_path not set or other internal error
|
|
37
39
|
*/
|
|
38
|
-
router.get('/tree', async (c) => {
|
|
40
|
+
router.get('/tree', requireRole(UserRole.Reader), async (c) => {
|
|
39
41
|
const commands = c.get('commands');
|
|
40
42
|
|
|
41
43
|
try {
|
|
@@ -97,6 +99,7 @@ router.get('/tree', async (c) => {
|
|
|
97
99
|
*/
|
|
98
100
|
router.get(
|
|
99
101
|
'/:prefix/:type/:identifier/validate',
|
|
102
|
+
requireRole(UserRole.Reader),
|
|
100
103
|
zValidator('param', validateResourceParamsSchema),
|
|
101
104
|
async (c) => {
|
|
102
105
|
const commands = c.get('commands');
|
|
@@ -117,6 +120,7 @@ router.get(
|
|
|
117
120
|
|
|
118
121
|
router.delete(
|
|
119
122
|
'/:prefix/:type/:identifier',
|
|
123
|
+
requireRole(UserRole.Admin),
|
|
120
124
|
zValidator('param', resourceParamsSchema),
|
|
121
125
|
async (c) => {
|
|
122
126
|
const commands = c.get('commands');
|
|
@@ -130,6 +134,7 @@ router.delete(
|
|
|
130
134
|
|
|
131
135
|
router.post(
|
|
132
136
|
'/:prefix/:type/:identifier/operation',
|
|
137
|
+
requireRole(UserRole.Admin),
|
|
133
138
|
zValidator('param', resourceParamsSchema),
|
|
134
139
|
zValidator('json', updateOperationBodySchema),
|
|
135
140
|
async (c) => {
|
|
@@ -42,7 +42,7 @@ const resourceTypes: ResourceFolderType[] = [
|
|
|
42
42
|
|
|
43
43
|
async function getModules(commands: CommandManager) {
|
|
44
44
|
try {
|
|
45
|
-
const moduleNames = commands.showCmd.showModules();
|
|
45
|
+
const moduleNames = await commands.showCmd.showModules();
|
|
46
46
|
return Promise.all(
|
|
47
47
|
moduleNames.map(async (moduleName) => {
|
|
48
48
|
try {
|
|
@@ -77,102 +77,104 @@ function sortTemplateCardsByRank(
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
export async function buildResourceTree(commands: CommandManager) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
(a
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const modules = await getModules(commands);
|
|
93
|
-
|
|
94
|
-
// General section first (single node with project + modules metadata)
|
|
95
|
-
tree.push({
|
|
96
|
-
id: 'general-project',
|
|
97
|
-
type: 'general',
|
|
98
|
-
name: 'project',
|
|
99
|
-
data: {
|
|
100
|
-
name: project.name,
|
|
101
|
-
cardKeyPrefix: project.prefix,
|
|
102
|
-
modules,
|
|
103
|
-
},
|
|
104
|
-
readOnly: false,
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// Process each resource type
|
|
108
|
-
for (const resourceType of resourceTypes) {
|
|
109
|
-
let rootResources: unknown[];
|
|
110
|
-
let moduleResources: { [prefix: string]: unknown[] };
|
|
111
|
-
|
|
112
|
-
if (resourceType === 'templates') {
|
|
113
|
-
({ rootResources, moduleResources } = await processTemplates(
|
|
114
|
-
commands,
|
|
115
|
-
project.prefix,
|
|
116
|
-
));
|
|
117
|
-
} else {
|
|
118
|
-
({ rootResources, moduleResources } = await groupResourcesByPrefix(
|
|
119
|
-
commands,
|
|
120
|
-
resourceType,
|
|
121
|
-
project.prefix,
|
|
122
|
-
));
|
|
123
|
-
}
|
|
80
|
+
return commands.consistent(async () => {
|
|
81
|
+
const project = await commands.showCmd.showProject();
|
|
82
|
+
const tree: unknown[] = [];
|
|
83
|
+
|
|
84
|
+
const sortByDisplayName = (
|
|
85
|
+
nodes: { data: { displayName: string; name: string } }[],
|
|
86
|
+
) =>
|
|
87
|
+
nodes.sort((a, b) =>
|
|
88
|
+
(a.data.displayName || a.data.name.split('/')[2] || '').localeCompare(
|
|
89
|
+
b.data.displayName || b.data.name.split('/')[2] || '',
|
|
90
|
+
),
|
|
91
|
+
);
|
|
124
92
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
93
|
+
const modules = await getModules(commands);
|
|
94
|
+
|
|
95
|
+
// General section first (single node with project + modules metadata)
|
|
96
|
+
tree.push({
|
|
97
|
+
id: 'general-project',
|
|
98
|
+
type: 'general',
|
|
99
|
+
name: 'project',
|
|
100
|
+
data: {
|
|
101
|
+
name: project.name,
|
|
102
|
+
cardKeyPrefix: project.prefix,
|
|
103
|
+
modules,
|
|
104
|
+
},
|
|
105
|
+
readOnly: false,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Process each resource type
|
|
109
|
+
for (const resourceType of resourceTypes) {
|
|
110
|
+
let rootResources: unknown[];
|
|
111
|
+
let moduleResources: { [prefix: string]: unknown[] };
|
|
112
|
+
|
|
113
|
+
if (resourceType === 'templates') {
|
|
114
|
+
({ rootResources, moduleResources } = await processTemplates(
|
|
115
|
+
commands,
|
|
116
|
+
project.prefix,
|
|
117
|
+
));
|
|
118
|
+
} else {
|
|
119
|
+
({ rootResources, moduleResources } = await groupResourcesByPrefix(
|
|
120
|
+
commands,
|
|
121
|
+
resourceType,
|
|
122
|
+
project.prefix,
|
|
123
|
+
));
|
|
124
|
+
}
|
|
129
125
|
|
|
130
|
-
|
|
126
|
+
// Sort resources by display name if present
|
|
131
127
|
sortByDisplayName(
|
|
132
|
-
|
|
133
|
-
)
|
|
134
|
-
|
|
128
|
+
rootResources as { data: { displayName: string; name: string } }[],
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
Object.values(moduleResources).forEach((resources) =>
|
|
132
|
+
sortByDisplayName(
|
|
133
|
+
resources as { data: { displayName: string; name: string } }[],
|
|
134
|
+
),
|
|
135
|
+
);
|
|
135
136
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
137
|
+
const projectNode =
|
|
138
|
+
rootResources.length > 0
|
|
139
|
+
? [
|
|
140
|
+
{
|
|
141
|
+
id: `${resourceType}-project`,
|
|
142
|
+
type: 'module',
|
|
143
|
+
name: 'project',
|
|
144
|
+
children: rootResources,
|
|
145
|
+
readOnly: false,
|
|
146
|
+
},
|
|
147
|
+
]
|
|
148
|
+
: [];
|
|
149
|
+
|
|
150
|
+
const moduleNodes = Object.entries(moduleResources)
|
|
151
|
+
.map(([prefix, resources]) => ({
|
|
152
|
+
id: `${resourceType}-module-${prefix}`,
|
|
153
|
+
type: 'module',
|
|
154
|
+
name:
|
|
155
|
+
modules.find((module) => module.cardKeyPrefix === prefix)?.name ||
|
|
156
|
+
prefix,
|
|
155
157
|
prefix,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
158
|
+
children: resources,
|
|
159
|
+
readOnly: true,
|
|
160
|
+
}))
|
|
161
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
162
|
+
|
|
163
|
+
const allResources = [...projectNode, ...moduleNodes];
|
|
164
|
+
|
|
165
|
+
// Add combined resources (project + modules nested under module nodes) under the same group
|
|
166
|
+
if (allResources.length > 0) {
|
|
167
|
+
tree.push({
|
|
168
|
+
id: resourceType,
|
|
169
|
+
type: 'resourceGroup',
|
|
170
|
+
name: resourceType,
|
|
171
|
+
children: allResources,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
172
174
|
}
|
|
173
|
-
}
|
|
174
175
|
|
|
175
|
-
|
|
176
|
+
return tree;
|
|
177
|
+
});
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
// Helper function to parse resource prefix
|
|
@@ -456,9 +458,8 @@ export async function validateResource(
|
|
|
456
458
|
commands: CommandManager,
|
|
457
459
|
resource: ValidateResourceParams,
|
|
458
460
|
) {
|
|
459
|
-
const errors = await commands.
|
|
460
|
-
resource,
|
|
461
|
-
commands.project,
|
|
461
|
+
const errors = await commands.consistent(() =>
|
|
462
|
+
commands.validateCmd.validateResource(resource, commands.project),
|
|
462
463
|
);
|
|
463
464
|
|
|
464
465
|
return {
|
|
@@ -476,9 +477,13 @@ export async function updateResourceWithOperation(
|
|
|
476
477
|
body: UpdateOperationBody,
|
|
477
478
|
) {
|
|
478
479
|
const { updateKey, operation } = body;
|
|
479
|
-
await commands.
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
480
|
+
await commands.atomic(
|
|
481
|
+
() =>
|
|
482
|
+
commands.updateCmd.applyResourceOperation(
|
|
483
|
+
resourceNameToString(resource),
|
|
484
|
+
updateKey,
|
|
485
|
+
operation,
|
|
486
|
+
),
|
|
487
|
+
`Update ${resource.type} ${resource.identifier}`,
|
|
483
488
|
);
|
|
484
489
|
}
|
|
@@ -16,6 +16,8 @@ import * as templateService from './service.js';
|
|
|
16
16
|
import { createTemplateSchema, addTemplateCardSchema } from './schema.js';
|
|
17
17
|
import { zValidator } from '../../middleware/zvalidator.js';
|
|
18
18
|
import { isSSGContext } from 'hono/ssg';
|
|
19
|
+
import { UserRole } from '../../types.js';
|
|
20
|
+
import { requireRole } from '../../middleware/auth.js';
|
|
19
21
|
|
|
20
22
|
const router = new Hono();
|
|
21
23
|
|
|
@@ -33,7 +35,7 @@ const router = new Hono();
|
|
|
33
35
|
* 500:
|
|
34
36
|
* description: project_path not set or other internal error
|
|
35
37
|
*/
|
|
36
|
-
router.get('/', async (c) => {
|
|
38
|
+
router.get('/', requireRole(UserRole.Reader), async (c) => {
|
|
37
39
|
// We do not need templates in ssg context
|
|
38
40
|
if (isSSGContext(c)) {
|
|
39
41
|
return c.json([]);
|
|
@@ -78,13 +80,18 @@ router.get('/', async (c) => {
|
|
|
78
80
|
* 500:
|
|
79
81
|
* description: Server error
|
|
80
82
|
*/
|
|
81
|
-
router.post(
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
router.post(
|
|
84
|
+
'/',
|
|
85
|
+
requireRole(UserRole.Admin),
|
|
86
|
+
zValidator('json', createTemplateSchema),
|
|
87
|
+
async (c) => {
|
|
88
|
+
const commands = c.get('commands');
|
|
89
|
+
const { identifier } = c.req.valid('json');
|
|
84
90
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
91
|
+
await templateService.createTemplate(commands, identifier);
|
|
92
|
+
return c.json({ message: 'Template created successfully' });
|
|
93
|
+
},
|
|
94
|
+
);
|
|
88
95
|
|
|
89
96
|
/**
|
|
90
97
|
* @swagger
|
|
@@ -119,18 +126,23 @@ router.post('/', zValidator('json', createTemplateSchema), async (c) => {
|
|
|
119
126
|
* 500:
|
|
120
127
|
* description: Server error
|
|
121
128
|
*/
|
|
122
|
-
router.post(
|
|
123
|
-
|
|
124
|
-
|
|
129
|
+
router.post(
|
|
130
|
+
'/card',
|
|
131
|
+
requireRole(UserRole.Admin),
|
|
132
|
+
zValidator('json', addTemplateCardSchema),
|
|
133
|
+
async (c) => {
|
|
134
|
+
const commands = c.get('commands');
|
|
135
|
+
const { template, cardType, parentKey, count } = c.req.valid('json');
|
|
125
136
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
137
|
+
const added = await templateService.addTemplateCard(
|
|
138
|
+
commands,
|
|
139
|
+
template,
|
|
140
|
+
cardType,
|
|
141
|
+
parentKey,
|
|
142
|
+
count,
|
|
143
|
+
);
|
|
144
|
+
return c.json({ cards: added });
|
|
145
|
+
},
|
|
146
|
+
);
|
|
135
147
|
|
|
136
148
|
export default router;
|
package/src/domain/tree/index.ts
CHANGED
|
@@ -15,6 +15,8 @@ import { Hono } from 'hono';
|
|
|
15
15
|
import * as treeService from './service.js';
|
|
16
16
|
import { isSSGContext } from 'hono/ssg';
|
|
17
17
|
import type { AppContext } from '../../types.js';
|
|
18
|
+
import { UserRole } from '../../types.js';
|
|
19
|
+
import { requireRole } from '../../middleware/auth.js';
|
|
18
20
|
|
|
19
21
|
const router = new Hono();
|
|
20
22
|
|
|
@@ -32,7 +34,7 @@ const router = new Hono();
|
|
|
32
34
|
* 500:
|
|
33
35
|
* description: project_path not set or other internal error
|
|
34
36
|
*/
|
|
35
|
-
router.get('/', async (c: AppContext) => {
|
|
37
|
+
router.get('/', requireRole(UserRole.Reader), async (c: AppContext) => {
|
|
36
38
|
const commands = c.get('commands');
|
|
37
39
|
const tree = c.get('tree');
|
|
38
40
|
|
|
@@ -27,7 +27,6 @@ export async function getCardTree(
|
|
|
27
27
|
cardKey?: string,
|
|
28
28
|
recursive?: boolean,
|
|
29
29
|
): ReturnType<typeof commands.calculateCmd.runQuery> {
|
|
30
|
-
await commands.calculateCmd.generate();
|
|
31
30
|
return commands.calculateCmd.runQuery(
|
|
32
31
|
'tree',
|
|
33
32
|
isSsg ? 'exportedSite' : 'localApp',
|
|
@@ -15,6 +15,8 @@ import { Hono } from 'hono';
|
|
|
15
15
|
import * as workflowService from './service.js';
|
|
16
16
|
import { createWorkflowSchema } from './schema.js';
|
|
17
17
|
import { zValidator } from '../../middleware/zvalidator.js';
|
|
18
|
+
import { UserRole } from '../../types.js';
|
|
19
|
+
import { requireRole } from '../../middleware/auth.js';
|
|
18
20
|
|
|
19
21
|
const router = new Hono();
|
|
20
22
|
|
|
@@ -43,12 +45,17 @@ const router = new Hono();
|
|
|
43
45
|
* 500:
|
|
44
46
|
* description: Server error
|
|
45
47
|
*/
|
|
46
|
-
router.post(
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
router.post(
|
|
49
|
+
'/',
|
|
50
|
+
requireRole(UserRole.Admin),
|
|
51
|
+
zValidator('json', createWorkflowSchema),
|
|
52
|
+
async (c) => {
|
|
53
|
+
const commands = c.get('commands');
|
|
54
|
+
const { identifier } = c.req.valid('json');
|
|
49
55
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
56
|
+
await workflowService.createWorkflow(commands, identifier);
|
|
57
|
+
return c.json({ message: 'Workflow created successfully' });
|
|
58
|
+
},
|
|
59
|
+
);
|
|
53
60
|
|
|
54
61
|
export default router;
|
package/src/export.ts
CHANGED
|
@@ -15,8 +15,9 @@ import path from 'node:path';
|
|
|
15
15
|
|
|
16
16
|
import fs, { readFile } from 'node:fs/promises';
|
|
17
17
|
|
|
18
|
-
import { CommandManager } from '@cyberismo/data-handler';
|
|
18
|
+
import type { CommandManager } from '@cyberismo/data-handler';
|
|
19
19
|
import { createApp } from './app.js';
|
|
20
|
+
import { MockAuthProvider } from './auth/mock.js';
|
|
20
21
|
import { cp, writeFile } from 'node:fs/promises';
|
|
21
22
|
import { staticFrontendDirRelative } from './utils.js';
|
|
22
23
|
import type { QueryResult } from '@cyberismo/data-handler/types/queries';
|
|
@@ -41,18 +42,17 @@ export function reset() {
|
|
|
41
42
|
/**
|
|
42
43
|
* Get the card query result for a given card key. Should only be called during
|
|
43
44
|
* static site generation
|
|
44
|
-
* @param
|
|
45
|
+
* @param commands - CommandManager instance for the project.
|
|
45
46
|
* @param cardKey - Key of the card to get the query result for.
|
|
46
47
|
* @returns The card query result for the given card key.
|
|
47
48
|
*/
|
|
48
49
|
export async function getCardQueryResult(
|
|
49
|
-
|
|
50
|
+
commands: CommandManager,
|
|
50
51
|
cardKey?: string,
|
|
51
52
|
): Promise<QueryResult<'card'>[]> {
|
|
52
53
|
if (!_cardQueryPromise) {
|
|
53
|
-
const commands = await CommandManager.getInstance(projectPath);
|
|
54
54
|
// fetch all cards
|
|
55
|
-
_cardQueryPromise = commands.
|
|
55
|
+
_cardQueryPromise = commands.calculateCmd.runQuery(
|
|
56
56
|
'card',
|
|
57
57
|
'exportedSite',
|
|
58
58
|
{},
|
|
@@ -73,20 +73,19 @@ export async function getCardQueryResult(
|
|
|
73
73
|
/**
|
|
74
74
|
* Export the site to a given directory.
|
|
75
75
|
* Note: Do not call this function in parallel.
|
|
76
|
-
* @param
|
|
76
|
+
* @param commands - CommandManager instance for the project.
|
|
77
|
+
* @param exportDir - Directory to export to.
|
|
77
78
|
* @param options - Export options.
|
|
78
79
|
* @param options.recursive - Whether to export cards recursively.
|
|
79
80
|
* @param options.cardKey - Key of the card to export. If not provided, all cards will be exported.
|
|
80
|
-
* @param exportDir - Directory to export to.
|
|
81
81
|
* @param level - Log level for the operation.
|
|
82
82
|
* @param onProgress - Optional progress callback function.
|
|
83
83
|
* @returns An object containing any errors that occurred during export.
|
|
84
84
|
*/
|
|
85
85
|
export async function exportSite(
|
|
86
|
-
|
|
86
|
+
commands: CommandManager,
|
|
87
87
|
exportDir?: string,
|
|
88
88
|
options?: TreeOptions,
|
|
89
|
-
level?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal',
|
|
90
89
|
onProgress?: (current: number, total: number) => void,
|
|
91
90
|
): Promise<{ errors: string[] }> {
|
|
92
91
|
exportDir = exportDir || 'static';
|
|
@@ -96,7 +95,7 @@ export async function exportSite(
|
|
|
96
95
|
...options,
|
|
97
96
|
};
|
|
98
97
|
|
|
99
|
-
const app = createApp(
|
|
98
|
+
const app = createApp(new MockAuthProvider(), commands, opts);
|
|
100
99
|
|
|
101
100
|
// copy whole frontend to the same directory
|
|
102
101
|
await cp(staticFrontendDirRelative, exportDir, { recursive: true });
|
|
@@ -109,12 +108,7 @@ export async function exportSite(
|
|
|
109
108
|
JSON.stringify(configJson),
|
|
110
109
|
);
|
|
111
110
|
|
|
112
|
-
const commands = await CommandManager.getInstance(projectPath, {
|
|
113
|
-
logLevel: level,
|
|
114
|
-
});
|
|
115
|
-
|
|
116
111
|
reset();
|
|
117
|
-
await commands.project.calculationEngine.generate();
|
|
118
112
|
|
|
119
113
|
// estimate total based on the number of cards to export
|
|
120
114
|
const cards = await findAllCards(commands, opts);
|
|
@@ -130,6 +124,14 @@ export async function exportSite(
|
|
|
130
124
|
concurrency: 5,
|
|
131
125
|
plugins: [
|
|
132
126
|
{
|
|
127
|
+
beforeRequestHook: (req) => {
|
|
128
|
+
const url = new URL(req.url);
|
|
129
|
+
// Skip MCP routes — they require session state and are not part of the static site
|
|
130
|
+
if (url.pathname.startsWith('/mcp')) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
return req;
|
|
134
|
+
},
|
|
133
135
|
afterResponseHook: async (response) => {
|
|
134
136
|
if (![200, 201, 204].includes(response.status)) {
|
|
135
137
|
const error = await response.json();
|
package/src/index.ts
CHANGED
|
@@ -16,8 +16,13 @@ import { Hono } from 'hono';
|
|
|
16
16
|
import { serveStatic } from '@hono/node-server/serve-static';
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
import { readFile } from 'node:fs/promises';
|
|
19
|
+
import type { CommandManager } from '@cyberismo/data-handler';
|
|
19
20
|
import { findFreePort } from './utils.js';
|
|
20
21
|
import { createApp } from './app.js';
|
|
22
|
+
import type { AuthProvider } from './auth/types.js';
|
|
23
|
+
export { MockAuthProvider } from './auth/mock.js';
|
|
24
|
+
export type { MockUserConfig } from './auth/mock.js';
|
|
25
|
+
export type { AuthProvider } from './auth/types.js';
|
|
21
26
|
export { exportSite } from './export.js';
|
|
22
27
|
|
|
23
28
|
const DEFAULT_PORT = 3000;
|
|
@@ -31,11 +36,14 @@ const DEFAULT_MAX_PORT = DEFAULT_PORT + 100;
|
|
|
31
36
|
export async function previewSite(dir: string, findPort: boolean = true) {
|
|
32
37
|
const app = new Hono();
|
|
33
38
|
app.use(serveStatic({ root: dir }));
|
|
34
|
-
app.get('*', (c) =>
|
|
35
|
-
c.
|
|
39
|
+
app.get('*', (c) => {
|
|
40
|
+
if (c.req.path.startsWith('/api/')) {
|
|
41
|
+
return c.json({ error: 'Resource not found' }, 404);
|
|
42
|
+
}
|
|
43
|
+
return c.html(
|
|
36
44
|
readFile(path.join(dir, 'index.html')).then((file) => file.toString()),
|
|
37
|
-
)
|
|
38
|
-
);
|
|
45
|
+
);
|
|
46
|
+
});
|
|
39
47
|
|
|
40
48
|
let port = parseInt(process.env.PORT || DEFAULT_PORT.toString(), 10);
|
|
41
49
|
|
|
@@ -47,11 +55,13 @@ export async function previewSite(dir: string, findPort: boolean = true) {
|
|
|
47
55
|
|
|
48
56
|
/**
|
|
49
57
|
* Start the server
|
|
50
|
-
* @param
|
|
58
|
+
* @param authProvider - Authentication provider
|
|
59
|
+
* @param commands - CommandManager instance for the project
|
|
51
60
|
* @param findPort - If true, find a free port
|
|
52
61
|
*/
|
|
53
62
|
export async function startServer(
|
|
54
|
-
|
|
63
|
+
authProvider: AuthProvider,
|
|
64
|
+
commands: CommandManager,
|
|
55
65
|
findPort: boolean = true,
|
|
56
66
|
) {
|
|
57
67
|
let port = parseInt(process.env.PORT || DEFAULT_PORT.toString(), 10);
|
|
@@ -59,7 +69,7 @@ export async function startServer(
|
|
|
59
69
|
if (findPort) {
|
|
60
70
|
port = await findFreePort(port, DEFAULT_MAX_PORT);
|
|
61
71
|
}
|
|
62
|
-
const app = createApp(
|
|
72
|
+
const app = createApp(authProvider, commands);
|
|
63
73
|
startApp(app, port);
|
|
64
74
|
}
|
|
65
75
|
|
|
@@ -71,6 +81,7 @@ function startApp<E extends Env, S extends Schema, P extends string>(
|
|
|
71
81
|
{
|
|
72
82
|
fetch: app.fetch,
|
|
73
83
|
port: port,
|
|
84
|
+
hostname: process.env.HOST || '127.0.0.1',
|
|
74
85
|
},
|
|
75
86
|
(info) => {
|
|
76
87
|
console.log(`Running Cyberismo app on http://localhost:${info.port}`);
|
package/src/main.ts
CHANGED
|
@@ -10,15 +10,57 @@
|
|
|
10
10
|
details. You should have received a copy of the GNU Affero General Public
|
|
11
11
|
License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
12
12
|
*/
|
|
13
|
+
import { CommandManager } from '@cyberismo/data-handler';
|
|
13
14
|
import { startServer } from './index.js';
|
|
14
15
|
import { exportSite } from './export.js';
|
|
16
|
+
import { MockAuthProvider } from './auth/mock.js';
|
|
17
|
+
import { KeycloakAuthProvider } from './auth/keycloak.js';
|
|
18
|
+
import type { AuthProvider } from './auth/types.js';
|
|
15
19
|
import dotenv from 'dotenv';
|
|
16
20
|
|
|
17
21
|
// Load environment variables from .env file
|
|
18
22
|
dotenv.config();
|
|
19
23
|
|
|
24
|
+
function createAuthProvider(): AuthProvider {
|
|
25
|
+
const authMode = process.env.AUTH_MODE;
|
|
26
|
+
|
|
27
|
+
if (!authMode) {
|
|
28
|
+
console.error(
|
|
29
|
+
'Fatal: AUTH_MODE environment variable is required. Set to "mock" or "idp".',
|
|
30
|
+
);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (authMode === 'mock') {
|
|
35
|
+
return new MockAuthProvider();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (authMode === 'idp') {
|
|
39
|
+
const issuer = process.env.OIDC_ISSUER;
|
|
40
|
+
const clientId = process.env.OIDC_CLIENT_ID;
|
|
41
|
+
|
|
42
|
+
if (!issuer || !clientId) {
|
|
43
|
+
console.error(
|
|
44
|
+
'Fatal: OIDC_ISSUER and OIDC_CLIENT_ID environment variables are required when AUTH_MODE=idp.',
|
|
45
|
+
);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return new KeycloakAuthProvider({ issuer, audience: clientId });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
console.error(
|
|
53
|
+
`Fatal: Unrecognized AUTH_MODE "${authMode}". Must be "mock" or "idp".`,
|
|
54
|
+
);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const projectPath = process.env.npm_config_project_path || '';
|
|
59
|
+
const commands = await CommandManager.getInstance(projectPath);
|
|
60
|
+
|
|
20
61
|
if (process.argv.includes('--export')) {
|
|
21
|
-
await exportSite(
|
|
62
|
+
await exportSite(commands);
|
|
22
63
|
} else {
|
|
23
|
-
|
|
64
|
+
const authProvider = createAuthProvider();
|
|
65
|
+
await startServer(authProvider, commands);
|
|
24
66
|
}
|