@jclvsh/iris 0.5.4 → 0.6.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/client.js +6 -3
- package/dist/tools/keys.js +11 -4
- package/dist/tools/webhooks.js +1 -1
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -41,9 +41,12 @@ export class IrisClient {
|
|
|
41
41
|
"Get a valid API key from https://iris-ai.dev/settings/api-keys");
|
|
42
42
|
}
|
|
43
43
|
this.apiKey = apiKey;
|
|
44
|
-
// Default to
|
|
45
|
-
//
|
|
46
|
-
|
|
44
|
+
// Default to api.iris-ai.dev (Stripe/GitHub/OpenAI convention). The api host
|
|
45
|
+
// rewrites /<resource> → /api/v1/<resource> via middleware (see iris/src/proxy.ts),
|
|
46
|
+
// so callers no longer pass the /api/v1/ prefix. Override via IRIS_API_URL if needed.
|
|
47
|
+
// Older versions (≤0.5.5) defaulted to https://www.iris-ai.dev/api/v1 — that host
|
|
48
|
+
// still responds, but the api host is canonical going forward.
|
|
49
|
+
this.baseUrl = (process.env.IRIS_API_URL || "https://api.iris-ai.dev").replace(/\/+$/, "");
|
|
47
50
|
}
|
|
48
51
|
async get(path, params) {
|
|
49
52
|
const url = new URL(`${this.baseUrl}${path}`);
|
package/dist/tools/keys.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
// Five-verb scope vocabulary. iris uses soft-deletes everywhere, so DELETE
|
|
3
3
|
// routes gate on `write` — there is no separate `delete` scope.
|
|
4
|
-
|
|
4
|
+
//
|
|
5
|
+
// `*` is also accepted at the API as a wildcard sentinel (expands to all 5
|
|
6
|
+
// scopes). It must be the SOLE element of the array — mixing it with named
|
|
7
|
+
// scopes was a privilege-escalation footgun (round-6 audit). Same rule as the
|
|
8
|
+
// API route schema in src/app/api/v1/keys/route.ts.
|
|
9
|
+
const NAMED_SCOPES = ["read", "write", "generate", "send", "admin"];
|
|
10
|
+
const SCOPES_WITH_WILDCARD = [...NAMED_SCOPES, "*"];
|
|
5
11
|
export function registerKeyTools(server, client) {
|
|
6
12
|
server.tool("get_current_api_key", "get details about the currently authenticated API key.", {}, async () => {
|
|
7
13
|
try {
|
|
@@ -45,11 +51,12 @@ export function registerKeyTools(server, client) {
|
|
|
45
51
|
server.tool("create_api_key", "create a new API key. requires admin scope.", {
|
|
46
52
|
name: z.string().min(1).max(100).describe("key name for identification"),
|
|
47
53
|
scopes: z
|
|
48
|
-
.array(z.enum(
|
|
54
|
+
.array(z.enum(SCOPES_WITH_WILDCARD))
|
|
49
55
|
.min(1, "scopes must be a non-empty array; omit the field for all scopes")
|
|
56
|
+
.refine((s) => !s.includes("*") || s.length === 1, "wildcard scope \"*\" must be the only element; mixing it with named scopes is rejected to prevent accidental privilege escalation")
|
|
50
57
|
.optional()
|
|
51
|
-
.describe("permission scopes
|
|
52
|
-
expires_at: z.string().optional().describe("expiration date in ISO 8601 format"),
|
|
58
|
+
.describe("permission scopes — any subset of [read, write, generate, send, admin], or [\"*\"] for all. omit the field for all scopes. empty array and mixed wildcard (e.g. [\"read\", \"*\"]) are rejected with 422."),
|
|
59
|
+
expires_at: z.string().optional().describe("expiration date in ISO 8601 format (must be in the future)"),
|
|
53
60
|
}, async (args) => {
|
|
54
61
|
try {
|
|
55
62
|
const result = await client.post("/keys", args);
|
package/dist/tools/webhooks.js
CHANGED
|
@@ -154,7 +154,7 @@ export function registerWebhookTools(server, client) {
|
|
|
154
154
|
};
|
|
155
155
|
}
|
|
156
156
|
});
|
|
157
|
-
server.tool("rotate_webhook_secret", "rotate the signing secret for a webhook. the new secret is returned in the response. the old secret is invalidated immediately — receivers must update their HMAC verification before the next delivery. requires
|
|
157
|
+
server.tool("rotate_webhook_secret", "rotate the signing secret for a webhook. the new secret is returned in the response. the old secret is invalidated immediately — receivers must update their HMAC verification before the next delivery. requires admin scope.", {
|
|
158
158
|
id: z.string().uuid().describe("webhook ID"),
|
|
159
159
|
}, async ({ id }) => {
|
|
160
160
|
try {
|