harper-kb 0.2.2 → 0.3.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/dist/core/embeddings.js +2 -2
- package/dist/core/embeddings.js.map +1 -1
- package/dist/hooks.d.ts +33 -11
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +6 -6
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +10 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/resources/HistoryResource.d.ts +1 -1
- package/dist/resources/HistoryResource.d.ts.map +1 -1
- package/dist/resources/HistoryResource.js +13 -1
- package/dist/resources/HistoryResource.js.map +1 -1
- package/dist/resources/KnowledgeBaseResource.d.ts +4 -4
- package/dist/resources/KnowledgeBaseResource.d.ts.map +1 -1
- package/dist/resources/KnowledgeBaseResource.js +75 -21
- package/dist/resources/KnowledgeBaseResource.js.map +1 -1
- package/dist/resources/KnowledgeEntryResource.d.ts.map +1 -1
- package/dist/resources/KnowledgeEntryResource.js +62 -12
- package/dist/resources/KnowledgeEntryResource.js.map +1 -1
- package/dist/resources/QueryLogResource.d.ts +1 -1
- package/dist/resources/QueryLogResource.d.ts.map +1 -1
- package/dist/resources/QueryLogResource.js +22 -7
- package/dist/resources/QueryLogResource.js.map +1 -1
- package/dist/resources/ServiceKeyResource.d.ts +3 -3
- package/dist/resources/ServiceKeyResource.d.ts.map +1 -1
- package/dist/resources/ServiceKeyResource.js +65 -22
- package/dist/resources/ServiceKeyResource.js.map +1 -1
- package/dist/resources/TagResource.d.ts +1 -1
- package/dist/resources/TagResource.d.ts.map +1 -1
- package/dist/resources/TagResource.js +13 -1
- package/dist/resources/TagResource.js.map +1 -1
- package/dist/resources/TriageResource.d.ts +3 -3
- package/dist/resources/TriageResource.d.ts.map +1 -1
- package/dist/resources/TriageResource.js +68 -25
- package/dist/resources/TriageResource.js.map +1 -1
- package/dist/resources/WebhookEndpointResource.d.ts +3 -3
- package/dist/resources/WebhookEndpointResource.d.ts.map +1 -1
- package/dist/resources/WebhookEndpointResource.js +65 -22
- package/dist/resources/WebhookEndpointResource.js.map +1 -1
- package/package.json +2 -2
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { createEntry, getEntry, updateEntry, deprecateEntry, stripEmbedding } from "../core/entries.js";
|
|
16
16
|
import { search, listEntries } from "../core/search.js";
|
|
17
|
+
import { checkAccess } from "../hooks.js";
|
|
17
18
|
function getResourceClass() {
|
|
18
19
|
return globalThis.Resource;
|
|
19
20
|
}
|
|
@@ -35,6 +36,16 @@ export class KnowledgeEntryResource extends getResourceClass() {
|
|
|
35
36
|
if (!kbId) {
|
|
36
37
|
return { status: 400, data: { error: 'kbId query parameter is required' } };
|
|
37
38
|
}
|
|
39
|
+
const accessResult = await checkAccess({
|
|
40
|
+
user: this.getCurrentUser(),
|
|
41
|
+
kbId,
|
|
42
|
+
resource: 'Knowledge',
|
|
43
|
+
operation: 'read',
|
|
44
|
+
channel: 'rest',
|
|
45
|
+
});
|
|
46
|
+
if (accessResult && !accessResult.allow) {
|
|
47
|
+
return { status: 403, data: { error: accessResult.reason || 'Access denied' } };
|
|
48
|
+
}
|
|
38
49
|
const id = this.getId();
|
|
39
50
|
if (id) {
|
|
40
51
|
const entry = await getEntry(String(id));
|
|
@@ -84,13 +95,25 @@ export class KnowledgeEntryResource extends getResourceClass() {
|
|
|
84
95
|
*/
|
|
85
96
|
async post(target, data) {
|
|
86
97
|
const user = this.getCurrentUser();
|
|
87
|
-
if (!user) {
|
|
88
|
-
return { status: 401, data: { error: 'Authentication required' } };
|
|
89
|
-
}
|
|
90
98
|
const kbId = extractKbId(target) || data?.kbId;
|
|
91
99
|
if (!kbId) {
|
|
92
100
|
return { status: 400, data: { error: 'kbId is required' } };
|
|
93
101
|
}
|
|
102
|
+
const accessResult = await checkAccess({
|
|
103
|
+
user,
|
|
104
|
+
kbId,
|
|
105
|
+
resource: 'Knowledge',
|
|
106
|
+
operation: 'write',
|
|
107
|
+
channel: 'rest',
|
|
108
|
+
});
|
|
109
|
+
if (accessResult) {
|
|
110
|
+
if (!accessResult.allow) {
|
|
111
|
+
return { status: user ? 403 : 401, data: { error: accessResult.reason || 'Access denied' } };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (!user) {
|
|
115
|
+
return { status: 401, data: { error: 'Authentication required' } };
|
|
116
|
+
}
|
|
94
117
|
if (!data?.title || !data?.content) {
|
|
95
118
|
return { status: 400, data: { error: 'title and content are required' } };
|
|
96
119
|
}
|
|
@@ -115,9 +138,6 @@ export class KnowledgeEntryResource extends getResourceClass() {
|
|
|
115
138
|
*/
|
|
116
139
|
async put(target, data) {
|
|
117
140
|
const user = this.getCurrentUser();
|
|
118
|
-
if (!user) {
|
|
119
|
-
return { status: 401, data: { error: 'Authentication required' } };
|
|
120
|
-
}
|
|
121
141
|
const id = this.getId();
|
|
122
142
|
if (!id) {
|
|
123
143
|
return { status: 400, data: { error: 'Entry ID required' } };
|
|
@@ -126,6 +146,21 @@ export class KnowledgeEntryResource extends getResourceClass() {
|
|
|
126
146
|
if (!kbId) {
|
|
127
147
|
return { status: 400, data: { error: 'kbId is required' } };
|
|
128
148
|
}
|
|
149
|
+
const accessResult = await checkAccess({
|
|
150
|
+
user,
|
|
151
|
+
kbId,
|
|
152
|
+
resource: 'Knowledge',
|
|
153
|
+
operation: 'write',
|
|
154
|
+
channel: 'rest',
|
|
155
|
+
});
|
|
156
|
+
if (accessResult) {
|
|
157
|
+
if (!accessResult.allow) {
|
|
158
|
+
return { status: user ? 403 : 401, data: { error: accessResult.reason || 'Access denied' } };
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else if (!user) {
|
|
162
|
+
return { status: 401, data: { error: 'Authentication required' } };
|
|
163
|
+
}
|
|
129
164
|
if (user.role === 'ai-agent') {
|
|
130
165
|
data.confidence = 'ai-generated';
|
|
131
166
|
}
|
|
@@ -157,12 +192,6 @@ export class KnowledgeEntryResource extends getResourceClass() {
|
|
|
157
192
|
*/
|
|
158
193
|
async delete(target) {
|
|
159
194
|
const user = this.getCurrentUser();
|
|
160
|
-
if (!user) {
|
|
161
|
-
return { status: 401, data: { error: 'Authentication required' } };
|
|
162
|
-
}
|
|
163
|
-
if (user.role !== 'team') {
|
|
164
|
-
return { status: 403, data: { error: 'Team role required' } };
|
|
165
|
-
}
|
|
166
195
|
const id = this.getId();
|
|
167
196
|
if (!id) {
|
|
168
197
|
return { status: 400, data: { error: 'Entry ID required' } };
|
|
@@ -171,6 +200,27 @@ export class KnowledgeEntryResource extends getResourceClass() {
|
|
|
171
200
|
if (!kbId) {
|
|
172
201
|
return { status: 400, data: { error: 'kbId query parameter is required' } };
|
|
173
202
|
}
|
|
203
|
+
const accessResult = await checkAccess({
|
|
204
|
+
user,
|
|
205
|
+
kbId,
|
|
206
|
+
resource: 'Knowledge',
|
|
207
|
+
operation: 'write',
|
|
208
|
+
channel: 'rest',
|
|
209
|
+
});
|
|
210
|
+
if (accessResult) {
|
|
211
|
+
if (!accessResult.allow) {
|
|
212
|
+
return { status: user ? 403 : 401, data: { error: accessResult.reason || 'Access denied' } };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
// Default behavior: auth + team role
|
|
217
|
+
if (!user) {
|
|
218
|
+
return { status: 401, data: { error: 'Authentication required' } };
|
|
219
|
+
}
|
|
220
|
+
if (user.role !== 'team') {
|
|
221
|
+
return { status: 403, data: { error: 'Team role required' } };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
174
224
|
// Verify entry belongs to this KB
|
|
175
225
|
const existing = await getEntry(String(id));
|
|
176
226
|
if (!existing || existing.kbId !== kbId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KnowledgeEntryResource.js","sourceRoot":"","sources":["../../src/resources/KnowledgeEntryResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACxG,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"KnowledgeEntryResource.js","sourceRoot":"","sources":["../../src/resources/KnowledgeEntryResource.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@ export declare class QueryLogResource extends QueryLogResource_base {
|
|
|
14
14
|
/**
|
|
15
15
|
* GET /QueryLog/?kbId=.. — list query logs, optionally filtered.
|
|
16
16
|
* GET /QueryLog/<id>?kbId=.. — get a single query log entry.
|
|
17
|
-
*
|
|
17
|
+
* Default: team role required. Hook can override.
|
|
18
18
|
*/
|
|
19
19
|
get(target?: any): Promise<Record<string, unknown> | Record<string, unknown>[]>;
|
|
20
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryLogResource.d.ts","sourceRoot":"","sources":["../../src/resources/QueryLogResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;
|
|
1
|
+
{"version":3,"file":"QueryLogResource.d.ts","sourceRoot":"","sources":["../../src/resources/QueryLogResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;AAYH,qBAAa,gBAAiB,SAAQ,qBAAkB;IACvD,MAAM,CAAC,cAAc,UAAS;IAE9B;;;;OAIG;IACG,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG;CAgEtB"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* GET /QueryLog/?kbId=.. — list recent query logs (team role required)
|
|
9
9
|
* GET /QueryLog/<id>?kbId=.. — get a single query log entry (team role required)
|
|
10
10
|
*/
|
|
11
|
+
import { checkAccess } from "../hooks.js";
|
|
11
12
|
function getResourceClass() {
|
|
12
13
|
return globalThis.Resource;
|
|
13
14
|
}
|
|
@@ -19,20 +20,34 @@ export class QueryLogResource extends getResourceClass() {
|
|
|
19
20
|
/**
|
|
20
21
|
* GET /QueryLog/?kbId=.. — list query logs, optionally filtered.
|
|
21
22
|
* GET /QueryLog/<id>?kbId=.. — get a single query log entry.
|
|
22
|
-
*
|
|
23
|
+
* Default: team role required. Hook can override.
|
|
23
24
|
*/
|
|
24
25
|
async get(target) {
|
|
25
26
|
const user = this.getCurrentUser();
|
|
26
|
-
if (!user) {
|
|
27
|
-
return { status: 401, data: { error: 'Authentication required' } };
|
|
28
|
-
}
|
|
29
|
-
if (user.role !== 'team') {
|
|
30
|
-
return { status: 403, data: { error: 'Team role required' } };
|
|
31
|
-
}
|
|
32
27
|
const kbId = extractKbId(target);
|
|
33
28
|
if (!kbId) {
|
|
34
29
|
return { status: 400, data: { error: 'kbId query parameter is required' } };
|
|
35
30
|
}
|
|
31
|
+
const accessResult = await checkAccess({
|
|
32
|
+
user,
|
|
33
|
+
kbId,
|
|
34
|
+
resource: 'QueryLog',
|
|
35
|
+
operation: 'read',
|
|
36
|
+
channel: 'rest',
|
|
37
|
+
});
|
|
38
|
+
if (accessResult) {
|
|
39
|
+
if (!accessResult.allow) {
|
|
40
|
+
return { status: user ? 403 : 401, data: { error: accessResult.reason || 'Access denied' } };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
if (!user) {
|
|
45
|
+
return { status: 401, data: { error: 'Authentication required' } };
|
|
46
|
+
}
|
|
47
|
+
if (user.role !== 'team') {
|
|
48
|
+
return { status: 403, data: { error: 'Team role required' } };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
36
51
|
const id = this.getId();
|
|
37
52
|
if (id) {
|
|
38
53
|
const entry = await databases.kb.QueryLog.get(String(id));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryLogResource.js","sourceRoot":"","sources":["../../src/resources/QueryLogResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,SAAS,gBAAgB;IACxB,OAAQ,UAAkB,CAAC,QAAQ,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,MAAY;IAChC,OAAO,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;AACtD,CAAC;AAED,MAAM,OAAO,gBAAiB,SAAQ,gBAAgB,EAAE;IACvD,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC;IAE9B;;;;OAIG;IACH,KAAK,CAAC,GAAG,CAAC,MAAY;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"QueryLogResource.js","sourceRoot":"","sources":["../../src/resources/QueryLogResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,SAAS,gBAAgB;IACxB,OAAQ,UAAkB,CAAC,QAAQ,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,MAAY;IAChC,OAAO,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;AACtD,CAAC;AAED,MAAM,OAAO,gBAAiB,SAAQ,gBAAgB,EAAE;IACvD,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC;IAE9B;;;;OAIG;IACH,KAAK,CAAC,GAAG,CAAC,MAAY;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,kCAAkC,EAAE,EAAE,CAAC;QAC7E,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC;YACtC,IAAI;YACJ,IAAI;YACJ,QAAQ,EAAE,UAAU;YACpB,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,YAAY,EAAE,CAAC;YAClB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,IAAI,eAAe,EAAE,EAAE,CAAC;YAC9F,CAAC;QACF,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,CAAC;YACpE,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,CAAC;YAC/D,CAAC;QACF,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,EAAE,EAAE,CAAC;YACR,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YAC1D,IAAI,CAAC,KAAK,IAAK,KAAa,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC5C,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,2BAA2B,EAAE,EAAE,CAAC;YACtE,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QAED,qDAAqD;QACrD,MAAM,UAAU,GAAG,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,MAAM,EAAE,KAAK,CAAC;QAC3D,MAAM,WAAW,GAAG,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,MAAM,EAAE,KAAK,CAAC;QAC5D,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAEjE,MAAM,UAAU,GAIX,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,IAAI,WAAW,EAAE,CAAC;YACjB,UAAU,CAAC,IAAI,CAAC;gBACf,SAAS,EAAE,OAAO;gBAClB,UAAU,EAAE,UAAU;gBACtB,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC;aAC1B,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAA8B,EAAE,CAAC;QAC9C,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;YACrD,UAAU;YACV,KAAK;SACL,CAAC,EAAE,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC"}
|
|
@@ -16,12 +16,12 @@ export declare class ServiceKeyResource extends ServiceKeyResource_base {
|
|
|
16
16
|
/**
|
|
17
17
|
* GET /ServiceKey/?kbId=.. — list all service keys (keyHash excluded).
|
|
18
18
|
* GET /ServiceKey/<id>?kbId=.. — get a single key (keyHash excluded).
|
|
19
|
-
*
|
|
19
|
+
* Default: team role required. Hook can override.
|
|
20
20
|
*/
|
|
21
21
|
get(target?: any): Promise<Record<string, unknown> | Record<string, unknown>[]>;
|
|
22
22
|
/**
|
|
23
23
|
* POST /ServiceKey/?kbId=.. — create a new API key.
|
|
24
|
-
*
|
|
24
|
+
* Default: team role required. Hook can override.
|
|
25
25
|
*
|
|
26
26
|
* Body: { name: string, role: "service_account" | "ai_agent", permissions?: object }
|
|
27
27
|
*
|
|
@@ -39,7 +39,7 @@ export declare class ServiceKeyResource extends ServiceKeyResource_base {
|
|
|
39
39
|
}>;
|
|
40
40
|
/**
|
|
41
41
|
* DELETE /ServiceKey/<id>?kbId=.. — delete a service key.
|
|
42
|
-
*
|
|
42
|
+
* Default: team role required. Hook can override.
|
|
43
43
|
*/
|
|
44
44
|
delete(target?: any): Promise<true | {
|
|
45
45
|
status: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceKeyResource.d.ts","sourceRoot":"","sources":["../../src/resources/ServiceKeyResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;;
|
|
1
|
+
{"version":3,"file":"ServiceKeyResource.d.ts","sourceRoot":"","sources":["../../src/resources/ServiceKeyResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;;AA6BH,qBAAa,kBAAmB,SAAQ,uBAAkB;IACzD,MAAM,CAAC,cAAc,UAAS;IAE9B;;;;OAIG;IACG,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG;IAmDtB;;;;;;;OAOG;IACG,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;;;;;;;;;;IA8DjC;;;OAGG;IACG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG;;;;;;CAwCzB"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* DELETE /ServiceKey/<id>?kbId=.. — delete a key (team role)
|
|
12
12
|
*/
|
|
13
13
|
import crypto from 'node:crypto';
|
|
14
|
+
import { checkAccess } from "../hooks.js";
|
|
14
15
|
function getResourceClass() {
|
|
15
16
|
return globalThis.Resource;
|
|
16
17
|
}
|
|
@@ -36,20 +37,34 @@ export class ServiceKeyResource extends getResourceClass() {
|
|
|
36
37
|
/**
|
|
37
38
|
* GET /ServiceKey/?kbId=.. — list all service keys (keyHash excluded).
|
|
38
39
|
* GET /ServiceKey/<id>?kbId=.. — get a single key (keyHash excluded).
|
|
39
|
-
*
|
|
40
|
+
* Default: team role required. Hook can override.
|
|
40
41
|
*/
|
|
41
42
|
async get(target) {
|
|
42
43
|
const user = this.getCurrentUser();
|
|
43
|
-
if (!user) {
|
|
44
|
-
return { status: 401, data: { error: 'Authentication required' } };
|
|
45
|
-
}
|
|
46
|
-
if (user.role !== 'team') {
|
|
47
|
-
return { status: 403, data: { error: 'Team role required' } };
|
|
48
|
-
}
|
|
49
44
|
const kbId = extractKbId(target);
|
|
50
45
|
if (!kbId) {
|
|
51
46
|
return { status: 400, data: { error: 'kbId query parameter is required' } };
|
|
52
47
|
}
|
|
48
|
+
const accessResult = await checkAccess({
|
|
49
|
+
user,
|
|
50
|
+
kbId,
|
|
51
|
+
resource: 'ServiceKey',
|
|
52
|
+
operation: 'read',
|
|
53
|
+
channel: 'rest',
|
|
54
|
+
});
|
|
55
|
+
if (accessResult) {
|
|
56
|
+
if (!accessResult.allow) {
|
|
57
|
+
return { status: user ? 403 : 401, data: { error: accessResult.reason || 'Access denied' } };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (!user) {
|
|
62
|
+
return { status: 401, data: { error: 'Authentication required' } };
|
|
63
|
+
}
|
|
64
|
+
if (user.role !== 'team') {
|
|
65
|
+
return { status: 403, data: { error: 'Team role required' } };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
53
68
|
const id = this.getId();
|
|
54
69
|
if (id) {
|
|
55
70
|
const record = await databases.kb.ServiceKey.get(String(id));
|
|
@@ -72,7 +87,7 @@ export class ServiceKeyResource extends getResourceClass() {
|
|
|
72
87
|
}
|
|
73
88
|
/**
|
|
74
89
|
* POST /ServiceKey/?kbId=.. — create a new API key.
|
|
75
|
-
*
|
|
90
|
+
* Default: team role required. Hook can override.
|
|
76
91
|
*
|
|
77
92
|
* Body: { name: string, role: "service_account" | "ai_agent", permissions?: object }
|
|
78
93
|
*
|
|
@@ -80,16 +95,30 @@ export class ServiceKeyResource extends getResourceClass() {
|
|
|
80
95
|
*/
|
|
81
96
|
async post(target, data) {
|
|
82
97
|
const user = this.getCurrentUser();
|
|
83
|
-
if (!user) {
|
|
84
|
-
return { status: 401, data: { error: 'Authentication required' } };
|
|
85
|
-
}
|
|
86
|
-
if (user.role !== 'team') {
|
|
87
|
-
return { status: 403, data: { error: 'Team role required' } };
|
|
88
|
-
}
|
|
89
98
|
const kbId = extractKbId(target) || data?.kbId;
|
|
90
99
|
if (!kbId) {
|
|
91
100
|
return { status: 400, data: { error: 'kbId is required' } };
|
|
92
101
|
}
|
|
102
|
+
const accessResult = await checkAccess({
|
|
103
|
+
user,
|
|
104
|
+
kbId,
|
|
105
|
+
resource: 'ServiceKey',
|
|
106
|
+
operation: 'write',
|
|
107
|
+
channel: 'rest',
|
|
108
|
+
});
|
|
109
|
+
if (accessResult) {
|
|
110
|
+
if (!accessResult.allow) {
|
|
111
|
+
return { status: user ? 403 : 401, data: { error: accessResult.reason || 'Access denied' } };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
if (!user) {
|
|
116
|
+
return { status: 401, data: { error: 'Authentication required' } };
|
|
117
|
+
}
|
|
118
|
+
if (user.role !== 'team') {
|
|
119
|
+
return { status: 403, data: { error: 'Team role required' } };
|
|
120
|
+
}
|
|
121
|
+
}
|
|
93
122
|
if (!data?.name) {
|
|
94
123
|
return { status: 400, data: { error: 'name is required' } };
|
|
95
124
|
}
|
|
@@ -111,7 +140,7 @@ export class ServiceKeyResource extends getResourceClass() {
|
|
|
111
140
|
keyHash: `${salt}:${hash}`,
|
|
112
141
|
role: data.role,
|
|
113
142
|
permissions: data.permissions || null,
|
|
114
|
-
createdBy: user
|
|
143
|
+
createdBy: user?.username || user?.id || 'unknown',
|
|
115
144
|
};
|
|
116
145
|
await databases.kb.ServiceKey.put(record);
|
|
117
146
|
// Return the record without keyHash, plus the plaintext key (shown only once)
|
|
@@ -122,16 +151,10 @@ export class ServiceKeyResource extends getResourceClass() {
|
|
|
122
151
|
}
|
|
123
152
|
/**
|
|
124
153
|
* DELETE /ServiceKey/<id>?kbId=.. — delete a service key.
|
|
125
|
-
*
|
|
154
|
+
* Default: team role required. Hook can override.
|
|
126
155
|
*/
|
|
127
156
|
async delete(target) {
|
|
128
157
|
const user = this.getCurrentUser();
|
|
129
|
-
if (!user) {
|
|
130
|
-
return { status: 401, data: { error: 'Authentication required' } };
|
|
131
|
-
}
|
|
132
|
-
if (user.role !== 'team') {
|
|
133
|
-
return { status: 403, data: { error: 'Team role required' } };
|
|
134
|
-
}
|
|
135
158
|
const id = this.getId();
|
|
136
159
|
if (!id) {
|
|
137
160
|
return { status: 400, data: { error: 'Service key ID required' } };
|
|
@@ -140,6 +163,26 @@ export class ServiceKeyResource extends getResourceClass() {
|
|
|
140
163
|
if (!kbId) {
|
|
141
164
|
return { status: 400, data: { error: 'kbId query parameter is required' } };
|
|
142
165
|
}
|
|
166
|
+
const accessResult = await checkAccess({
|
|
167
|
+
user,
|
|
168
|
+
kbId,
|
|
169
|
+
resource: 'ServiceKey',
|
|
170
|
+
operation: 'write',
|
|
171
|
+
channel: 'rest',
|
|
172
|
+
});
|
|
173
|
+
if (accessResult) {
|
|
174
|
+
if (!accessResult.allow) {
|
|
175
|
+
return { status: user ? 403 : 401, data: { error: accessResult.reason || 'Access denied' } };
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
if (!user) {
|
|
180
|
+
return { status: 401, data: { error: 'Authentication required' } };
|
|
181
|
+
}
|
|
182
|
+
if (user.role !== 'team') {
|
|
183
|
+
return { status: 403, data: { error: 'Team role required' } };
|
|
184
|
+
}
|
|
185
|
+
}
|
|
143
186
|
const existing = await databases.kb.ServiceKey.get(String(id));
|
|
144
187
|
if (!existing || existing.kbId !== kbId) {
|
|
145
188
|
return { status: 404, data: { error: 'Service key not found' } };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServiceKeyResource.js","sourceRoot":"","sources":["../../src/resources/ServiceKeyResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ServiceKeyResource.js","sourceRoot":"","sources":["../../src/resources/ServiceKeyResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,SAAS,gBAAgB;IACxB,OAAQ,UAAkB,CAAC,QAAQ,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,MAAY;IAChC,OAAO,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,GAAW,EAAE,IAAY;IACzC,OAAO,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,MAA+B;IACnD,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IAC9C,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,OAAO,kBAAmB,SAAQ,gBAAgB,EAAE;IACzD,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC;IAE9B;;;;OAIG;IACH,KAAK,CAAC,GAAG,CAAC,MAAY;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,kCAAkC,EAAE,EAAE,CAAC;QAC7E,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC;YACtC,IAAI;YACJ,IAAI;YACJ,QAAQ,EAAE,YAAY;YACtB,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,YAAY,EAAE,CAAC;YAClB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,IAAI,eAAe,EAAE,EAAE,CAAC;YAC9F,CAAC;QACF,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,CAAC;YACpE,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,CAAC;YAC/D,CAAC;QACF,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,EAAE,EAAE,CAAC;YACR,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7D,IAAI,CAAC,MAAM,IAAK,MAAc,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC9C,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,CAAC;YAClE,CAAC;YACD,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAED,YAAY;QACZ,MAAM,UAAU,GAAG,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,MAAM,EAAE,KAAK,CAAC;QAC3D,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAElE,MAAM,OAAO,GAA8B,EAAE,CAAC;QAC9C,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;YACvD,UAAU,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;YACtE,KAAK;SACL,CAAC,EAAE,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;QACjC,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,CAAC,MAAW,EAAE,IAAS;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACnC,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,IAAI,CAAC;QAC/C,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,CAAC;QAC7D,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC;YACtC,IAAI;YACJ,IAAI;YACJ,QAAQ,EAAE,YAAY;YACtB,SAAS,EAAE,OAAO;YAClB,OAAO,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,YAAY,EAAE,CAAC;YAClB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,IAAI,eAAe,EAAE,EAAE,CAAC;YAC9F,CAAC;QACF,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,CAAC;YACpE,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,CAAC;YAC/D,CAAC;QACF,CAAC;QAED,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;YACjB,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,CAAC;QAC7D,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,iBAAiB,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,EAAE,CAAC;YAClF,OAAO;gBACN,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,EAAE,KAAK,EAAE,8CAA8C,EAAE;aAC/D,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAEzC,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/B,MAAM,MAAM,GAA4B;YACvC,EAAE;YACF,IAAI;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE;YAC1B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;YACrC,SAAS,EAAE,IAAI,EAAE,QAAQ,IAAI,IAAI,EAAE,EAAE,IAAI,SAAS;SAClD,CAAC;QAEF,MAAM,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAE1C,8EAA8E;QAC9E,OAAO;YACN,GAAG,WAAW,CAAC,MAAM,CAAC;YACtB,GAAG,EAAE,YAAY;SACjB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,MAAY;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACnC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,EAAE,EAAE,CAAC;YACT,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,CAAC;QACpE,CAAC;QAED,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,kCAAkC,EAAE,EAAE,CAAC;QAC7E,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC;YACtC,IAAI;YACJ,IAAI;YACJ,QAAQ,EAAE,YAAY;YACtB,SAAS,EAAE,OAAO;YAClB,OAAO,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,YAAY,EAAE,CAAC;YAClB,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,IAAI,eAAe,EAAE,EAAE,CAAC;YAC9F,CAAC;QACF,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,IAAI,EAAE,CAAC;gBACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,yBAAyB,EAAE,EAAE,CAAC;YACpE,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,CAAC;YAC/D,CAAC;QACF,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,QAAQ,IAAK,QAAgB,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE,EAAE,CAAC;QAClE,CAAC;QAED,MAAM,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC;IACb,CAAC"}
|
|
@@ -14,7 +14,7 @@ export declare class TagResource extends TagResource_base {
|
|
|
14
14
|
/**
|
|
15
15
|
* GET /KnowledgeTag/?kbId=.. — list all tags.
|
|
16
16
|
* GET /KnowledgeTag/<id>?kbId=.. — get a single tag by name.
|
|
17
|
-
*
|
|
17
|
+
* Default: public. Hook can restrict.
|
|
18
18
|
*/
|
|
19
19
|
get(target?: any): Promise<import("../types.ts").KnowledgeTag | import("../types.ts").KnowledgeTag[] | {
|
|
20
20
|
status: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagResource.d.ts","sourceRoot":"","sources":["../../src/resources/TagResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;
|
|
1
|
+
{"version":3,"file":"TagResource.d.ts","sourceRoot":"","sources":["../../src/resources/TagResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;AAaH,qBAAa,WAAY,SAAQ,gBAAkB;IAClD,MAAM,CAAC,cAAc,UAAS;IAE9B;;;;OAIG;IACG,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG;;;;;;CA6BtB"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* GET /KnowledgeTag/<id>?kbId=.. — get a single tag by name (public)
|
|
10
10
|
*/
|
|
11
11
|
import { listTags, getTag } from "../core/tags.js";
|
|
12
|
+
import { checkAccess } from "../hooks.js";
|
|
12
13
|
function getResourceClass() {
|
|
13
14
|
return globalThis.Resource;
|
|
14
15
|
}
|
|
@@ -20,13 +21,24 @@ export class TagResource extends getResourceClass() {
|
|
|
20
21
|
/**
|
|
21
22
|
* GET /KnowledgeTag/?kbId=.. — list all tags.
|
|
22
23
|
* GET /KnowledgeTag/<id>?kbId=.. — get a single tag by name.
|
|
23
|
-
*
|
|
24
|
+
* Default: public. Hook can restrict.
|
|
24
25
|
*/
|
|
25
26
|
async get(target) {
|
|
26
27
|
const kbId = extractKbId(target);
|
|
27
28
|
if (!kbId) {
|
|
28
29
|
return { status: 400, data: { error: 'kbId query parameter is required' } };
|
|
29
30
|
}
|
|
31
|
+
const accessResult = await checkAccess({
|
|
32
|
+
user: this.getCurrentUser(),
|
|
33
|
+
kbId,
|
|
34
|
+
resource: 'KnowledgeTag',
|
|
35
|
+
operation: 'read',
|
|
36
|
+
channel: 'rest',
|
|
37
|
+
});
|
|
38
|
+
if (accessResult && !accessResult.allow) {
|
|
39
|
+
const user = this.getCurrentUser();
|
|
40
|
+
return { status: user ? 403 : 401, data: { error: accessResult.reason || 'Access denied' } };
|
|
41
|
+
}
|
|
30
42
|
const id = this.getId();
|
|
31
43
|
if (id) {
|
|
32
44
|
const tag = await getTag(kbId, String(id));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagResource.js","sourceRoot":"","sources":["../../src/resources/TagResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"TagResource.js","sourceRoot":"","sources":["../../src/resources/TagResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,SAAS,gBAAgB;IACxB,OAAQ,UAAkB,CAAC,QAAQ,CAAC;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,MAAY;IAChC,OAAO,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;AACtD,CAAC;AAED,MAAM,OAAO,WAAY,SAAQ,gBAAgB,EAAE;IAClD,MAAM,CAAC,cAAc,GAAG,KAAK,CAAC;IAE9B;;;;OAIG;IACH,KAAK,CAAC,GAAG,CAAC,MAAY;QACrB,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,kCAAkC,EAAE,EAAE,CAAC;QAC7E,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,WAAW,CAAC;YACtC,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE;YAC3B,IAAI;YACJ,QAAQ,EAAE,cAAc;YACxB,SAAS,EAAE,MAAM;YACjB,OAAO,EAAE,MAAM;SACf,CAAC,CAAC;QACH,IAAI,YAAY,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YACzC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YACnC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,IAAI,eAAe,EAAE,EAAE,CAAC;QAC9F,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,EAAE,EAAE,CAAC;YACR,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;gBACV,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,CAAC;YAC1D,CAAC;YACD,OAAO,GAAG,CAAC;QACZ,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC"}
|
|
@@ -14,7 +14,7 @@ export declare class TriageResource extends TriageResource_base {
|
|
|
14
14
|
static loadAsInstance: boolean;
|
|
15
15
|
/**
|
|
16
16
|
* GET /Triage/?kbId=.. — list pending triage items.
|
|
17
|
-
*
|
|
17
|
+
* Default: team role required. Hook can override.
|
|
18
18
|
*/
|
|
19
19
|
get(target?: any): Promise<import("../types.ts").TriageItem[] | {
|
|
20
20
|
status: number;
|
|
@@ -24,7 +24,7 @@ export declare class TriageResource extends TriageResource_base {
|
|
|
24
24
|
}>;
|
|
25
25
|
/**
|
|
26
26
|
* POST /Triage/?kbId=.. — submit a new triage item.
|
|
27
|
-
*
|
|
27
|
+
* Default: service_account or ai_agent role. Hook can override.
|
|
28
28
|
*/
|
|
29
29
|
post(target: any, data: any): Promise<import("../types.ts").TriageItem | {
|
|
30
30
|
status: number;
|
|
@@ -34,7 +34,7 @@ export declare class TriageResource extends TriageResource_base {
|
|
|
34
34
|
}>;
|
|
35
35
|
/**
|
|
36
36
|
* PUT /Triage/<id> — process a triage item.
|
|
37
|
-
*
|
|
37
|
+
* Default: team role required. Hook can override.
|
|
38
38
|
*
|
|
39
39
|
* Body should include:
|
|
40
40
|
* { action: "accepted" | "dismissed" | "linked",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TriageResource.d.ts","sourceRoot":"","sources":["../../src/resources/TriageResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;;
|
|
1
|
+
{"version":3,"file":"TriageResource.d.ts","sourceRoot":"","sources":["../../src/resources/TriageResource.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;;AAcH,qBAAa,cAAe,SAAQ,mBAAkB;IACrD,MAAM,CAAC,cAAc,UAAS;IAE9B;;;OAGG;IACG,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG;;;;;;IA8BtB;;;OAGG;IACG,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;;;;;;IAwCjC;;;;;;;;;OASG;IACG,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG;;;;;;CA4DjC"}
|