@ory/argus 0.11.1 → 0.12.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/agent-auth.d.ts +23 -0
- package/dist/agent-auth.js +42 -1
- package/dist/auth.js +76 -3
- package/dist/cli-invocation.d.ts +34 -0
- package/dist/cli-invocation.js +60 -0
- package/dist/cli.d.ts +15 -5
- package/dist/cli.js +161 -53
- package/dist/client.d.ts +27 -0
- package/dist/client.js +85 -5
- package/dist/config.d.ts +61 -0
- package/dist/config.js +81 -5
- package/dist/dev.d.ts +8 -0
- package/dist/dev.js +12 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +17 -3
- package/dist/interactive-setup.d.ts +123 -0
- package/dist/interactive-setup.js +1203 -0
- package/dist/local/cli.js +12 -11
- package/dist/local/index.d.ts +1 -1
- package/dist/local/index.js +3 -1
- package/dist/local/manager.js +1 -1
- package/dist/permissions-cli.js +55 -19
- package/dist/registry/config.js +7 -0
- package/dist/setup.d.ts +43 -3
- package/dist/setup.js +116 -23
- package/dist/status-cli.d.ts +2 -1
- package/dist/status-cli.js +34 -13
- package/dist/subject.d.ts +8 -5
- package/dist/subject.js +9 -6
- package/dist/tool-catalog.d.ts +2 -2
- package/dist/tool-catalog.js +14 -6
- package/dist/ui.d.ts +144 -0
- package/dist/ui.js +270 -0
- package/dist/uninstall.d.ts +47 -0
- package/dist/uninstall.js +90 -0
- package/dist/user-login.d.ts +5 -3
- package/dist/user-login.js +13 -9
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -47,10 +47,11 @@ exports.interactiveConfigPrompt = interactiveConfigPrompt;
|
|
|
47
47
|
exports.runAgentCommand = runAgentCommand;
|
|
48
48
|
const fs = __importStar(require("node:fs"));
|
|
49
49
|
const readline = __importStar(require("node:readline"));
|
|
50
|
-
const client_1 = require("@ory/client");
|
|
51
50
|
const config_js_1 = require("./config.js");
|
|
52
51
|
const agent_auth_js_1 = require("./agent-auth.js");
|
|
53
52
|
const tracer_js_1 = require("./tracer.js");
|
|
53
|
+
const cli_invocation_js_1 = require("./cli-invocation.js");
|
|
54
|
+
const client_js_1 = require("./client.js");
|
|
54
55
|
/**
|
|
55
56
|
* Shared `configure` command implementation for all plugin CLIs.
|
|
56
57
|
*
|
|
@@ -67,14 +68,27 @@ const tracer_js_1 = require("./tracer.js");
|
|
|
67
68
|
*/
|
|
68
69
|
function runConfigureCommand(binName, args) {
|
|
69
70
|
let projectUrl;
|
|
71
|
+
let projectId;
|
|
70
72
|
let apiKey;
|
|
71
73
|
let oauth2ClientId;
|
|
72
74
|
let auditOnly = false;
|
|
75
|
+
// `undefined` = not specified (leave the persisted value alone);
|
|
76
|
+
// true/false = explicit enable/disable of the interactive user login.
|
|
77
|
+
let userLogin;
|
|
78
|
+
// `undefined` = not specified; a string sets it; empty string ("") clears it
|
|
79
|
+
// (via --no-user-subject-namespace) to fall back to direct SubjectID.
|
|
80
|
+
let userSubjectNamespace;
|
|
73
81
|
for (let i = 0; i < args.length; i++) {
|
|
74
82
|
switch (args[i]) {
|
|
75
83
|
case "--project-url":
|
|
84
|
+
// `--sdk-url` is the name the Ory Console "Get Started" uses; accept it
|
|
85
|
+
// as an alias so the value copied from there works verbatim.
|
|
86
|
+
case "--sdk-url":
|
|
76
87
|
projectUrl = args[++i];
|
|
77
88
|
break;
|
|
89
|
+
case "--project-id":
|
|
90
|
+
projectId = args[++i];
|
|
91
|
+
break;
|
|
78
92
|
case "--api-key":
|
|
79
93
|
apiKey = args[++i];
|
|
80
94
|
break;
|
|
@@ -84,9 +98,27 @@ function runConfigureCommand(binName, args) {
|
|
|
84
98
|
case "--audit-only":
|
|
85
99
|
auditOnly = true;
|
|
86
100
|
break;
|
|
101
|
+
case "--user-login":
|
|
102
|
+
userLogin = true;
|
|
103
|
+
break;
|
|
104
|
+
case "--no-user-login":
|
|
105
|
+
userLogin = false;
|
|
106
|
+
break;
|
|
107
|
+
case "--user-subject-namespace":
|
|
108
|
+
userSubjectNamespace = args[++i];
|
|
109
|
+
break;
|
|
110
|
+
case "--no-user-subject-namespace":
|
|
111
|
+
userSubjectNamespace = "";
|
|
112
|
+
break;
|
|
87
113
|
}
|
|
88
114
|
}
|
|
89
|
-
if (!projectUrl &&
|
|
115
|
+
if (!projectUrl &&
|
|
116
|
+
!projectId &&
|
|
117
|
+
!apiKey &&
|
|
118
|
+
!oauth2ClientId &&
|
|
119
|
+
!auditOnly &&
|
|
120
|
+
userLogin === undefined &&
|
|
121
|
+
userSubjectNamespace === undefined) {
|
|
90
122
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
91
123
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
92
124
|
console.log("Ory Plugin Configuration");
|
|
@@ -94,35 +126,54 @@ function runConfigureCommand(binName, args) {
|
|
|
94
126
|
console.log("");
|
|
95
127
|
console.log(`Config file: ${configPath}`);
|
|
96
128
|
console.log(`Project URL: ${resolved.projectUrl ?? "(not set)"} [${resolved.projectUrlSource}]`);
|
|
129
|
+
console.log(`Project ID: ${resolved.projectId ?? "(not set)"} [${resolved.projectIdSource}]`);
|
|
97
130
|
console.log(`API Key: ${resolved.apiKey ? "(set)" : "(not set)"} [${resolved.apiKeySource}]`);
|
|
98
131
|
console.log(`OAuth2 Client ID: ${resolved.oauth2ClientId ?? "(not set)"} [${resolved.oauth2ClientIdSource}]`);
|
|
99
132
|
console.log(`Audit Only: ${resolved.auditOnly ? "yes" : "no"}`);
|
|
133
|
+
console.log(`User Login: ${resolved.userLogin ? "on" : "off"} [${resolved.userLoginSource}]`);
|
|
134
|
+
console.log(`User subject ns: ${resolved.userSubjectNamespace ?? "(direct subject id)"} [${resolved.userSubjectNamespaceSource}]`);
|
|
100
135
|
console.log("");
|
|
101
136
|
console.log("To configure:");
|
|
102
|
-
console.log(`
|
|
137
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url <URL> --oauth2-client-id <CLIENT_ID> [--api-key <KEY>]`);
|
|
138
|
+
console.log("");
|
|
139
|
+
console.log("To enable the interactive user login (PKCE browser flow at session start):");
|
|
140
|
+
console.log(` npx ${binName} configure --user-login (disable with --no-user-login)`);
|
|
141
|
+
console.log("");
|
|
142
|
+
console.log("To address the user as a SubjectSet in permission checks (must match your tuples):");
|
|
143
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --user-subject-namespace User (clear with --no-user-subject-namespace)`);
|
|
103
144
|
console.log("");
|
|
104
145
|
console.log("To enable audit logging only (no auth or permission checks):");
|
|
105
|
-
console.log(`
|
|
146
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --audit-only`);
|
|
106
147
|
console.log("");
|
|
107
148
|
console.log("Or set environment variables:");
|
|
108
149
|
console.log(" export ORY_PROJECT_URL=https://your-project.projects.oryapis.com");
|
|
150
|
+
console.log(" # ORY_SDK_URL (the Ory Console 'Get Started' name) is accepted as an alias.");
|
|
151
|
+
console.log(" # ORY_PROJECT_ID=<project uuid> is stored for admin operations (not an SDK URL).");
|
|
109
152
|
console.log(" export ORY_OAUTH2_CLIENT_ID=<public OAuth2 client id>");
|
|
110
153
|
console.log(" export ORY_AGENT_API_KEY=ory_pat_...");
|
|
154
|
+
console.log(" export ORY_USER_LOGIN=true");
|
|
111
155
|
return;
|
|
112
156
|
}
|
|
113
157
|
if (auditOnly) {
|
|
114
|
-
// Audit-only mode:
|
|
115
|
-
|
|
158
|
+
// Audit-only mode: set the kill switch. Persist an explicit user-login
|
|
159
|
+
// choice too if one was passed, so it takes effect once audit-only is
|
|
160
|
+
// later turned off; audit-only itself disables login regardless.
|
|
161
|
+
(0, config_js_1.saveConfig)({ auditOnly: true, ...(userLogin !== undefined ? { userLogin } : {}) });
|
|
116
162
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
117
163
|
console.log(`Configuration saved to ${configPath}`);
|
|
118
164
|
console.log(" Mode: audit-only (logging enabled, auth and permission checks disabled)");
|
|
165
|
+
if (userLogin !== undefined) {
|
|
166
|
+
console.log(` User login: ${userLogin ? "on" : "off"} (takes effect when audit-only is disabled)`);
|
|
167
|
+
}
|
|
119
168
|
console.log("");
|
|
120
169
|
console.log("This configuration is shared across all Ory agent plugins.");
|
|
121
170
|
return;
|
|
122
171
|
}
|
|
123
|
-
// When --project-url is provided we need a usable OAuth2 client
|
|
124
|
-
// the user PKCE flow — block the configure with a clear error if none
|
|
125
|
-
// is reachable from the flag, env, or already-persisted config.
|
|
172
|
+
// When --project-url / --sdk-url is provided we need a usable OAuth2 client
|
|
173
|
+
// id for the user PKCE flow — block the configure with a clear error if none
|
|
174
|
+
// is reachable from the flag, env, or already-persisted config. A bare
|
|
175
|
+
// --project-id sets an admin identifier only (not an SDK URL), so it doesn't
|
|
176
|
+
// trigger this gate on its own.
|
|
126
177
|
if (projectUrl) {
|
|
127
178
|
const persisted = (0, config_js_1.loadConfig)().oauth2ClientId;
|
|
128
179
|
const envClientId = process.env.ORY_OAUTH2_CLIENT_ID;
|
|
@@ -152,31 +203,67 @@ function runConfigureCommand(binName, args) {
|
|
|
152
203
|
" --redirect-uri http://127.0.0.1:47826/callback\n" +
|
|
153
204
|
"\n" +
|
|
154
205
|
"If you only want audit logging (no auth or permission checks), use:\n" +
|
|
155
|
-
`
|
|
206
|
+
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --audit-only`);
|
|
156
207
|
process.exit(1);
|
|
157
208
|
}
|
|
158
209
|
}
|
|
210
|
+
// Enabling user login needs a project URL and a public OAuth2 client id
|
|
211
|
+
// to complete the PKCE flow. Warn (don't block) if either is missing —
|
|
212
|
+
// the operator may supply them separately or via env before running.
|
|
213
|
+
if (userLogin === true) {
|
|
214
|
+
// resolveConfig() already folds in the ORY_SDK_URL alias and the config
|
|
215
|
+
// file; OR in the URL being set on this same invocation.
|
|
216
|
+
const nextProjectUrl = projectUrl ?? (0, config_js_1.resolveConfig)().projectUrl;
|
|
217
|
+
const nextClientId = oauth2ClientId ?? process.env.ORY_OAUTH2_CLIENT_ID ?? (0, config_js_1.loadConfig)().oauth2ClientId;
|
|
218
|
+
if (!nextProjectUrl || !nextClientId) {
|
|
219
|
+
const missing = [
|
|
220
|
+
!nextProjectUrl ? "a project URL (--project-url / --sdk-url / ORY_PROJECT_URL)" : null,
|
|
221
|
+
!nextClientId ? "an OAuth2 client id (--oauth2-client-id / ORY_OAUTH2_CLIENT_ID)" : null,
|
|
222
|
+
].filter(Boolean);
|
|
223
|
+
console.warn(`Warning: user login is enabled but still missing ${missing.join(" and ")}.\n` +
|
|
224
|
+
"The PKCE browser flow can't complete until both are configured.");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
159
227
|
const update = {};
|
|
160
228
|
if (projectUrl)
|
|
161
229
|
update.projectUrl = projectUrl;
|
|
230
|
+
if (projectId)
|
|
231
|
+
update.projectId = projectId;
|
|
162
232
|
if (apiKey)
|
|
163
233
|
update.apiKey = apiKey;
|
|
164
234
|
if (oauth2ClientId)
|
|
165
235
|
update.oauth2ClientId = oauth2ClientId;
|
|
166
|
-
|
|
167
|
-
|
|
236
|
+
if (userLogin !== undefined)
|
|
237
|
+
update.userLogin = userLogin;
|
|
238
|
+
// A non-empty namespace sets the SubjectSet namespace; the empty string
|
|
239
|
+
// (from --no-user-subject-namespace) clears it (null ⇒ delete the key).
|
|
240
|
+
if (userSubjectNamespace !== undefined) {
|
|
241
|
+
update.userSubjectNamespace = userSubjectNamespace === "" ? null : userSubjectNamespace;
|
|
242
|
+
}
|
|
243
|
+
// Configuring an actual connection (a slug-based URL, api key, or client id)
|
|
244
|
+
// implies leaving audit-only mode. A bare project id is only an admin
|
|
245
|
+
// identifier — it doesn't connect anything on its own — so it doesn't flip
|
|
246
|
+
// the flag; nor does a standalone user-login toggle.
|
|
247
|
+
if (projectUrl || apiKey || oauth2ClientId)
|
|
248
|
+
update.auditOnly = false;
|
|
168
249
|
(0, config_js_1.saveConfig)(update);
|
|
169
250
|
const configPath = (0, config_js_1.getConfigPath)();
|
|
170
251
|
console.log(`Configuration saved to ${configPath}`);
|
|
171
252
|
if (projectUrl)
|
|
172
253
|
console.log(` Project URL: ${projectUrl}`);
|
|
254
|
+
if (projectId)
|
|
255
|
+
console.log(` Project ID: ${projectId}`);
|
|
173
256
|
if (apiKey)
|
|
174
257
|
console.log(` API Key: (set)`);
|
|
175
258
|
if (oauth2ClientId)
|
|
176
259
|
console.log(` OAuth2 Client ID: ${oauth2ClientId}`);
|
|
260
|
+
if (userLogin !== undefined)
|
|
261
|
+
console.log(` User Login: ${userLogin ? "on" : "off"}`);
|
|
262
|
+
if (userSubjectNamespace !== undefined)
|
|
263
|
+
console.log(` User subject namespace: ${userSubjectNamespace === "" ? "(cleared — direct subject id)" : userSubjectNamespace}`);
|
|
177
264
|
console.log("");
|
|
178
265
|
console.log("This configuration is shared across all Ory agent plugins.");
|
|
179
|
-
console.log("Environment variables (ORY_PROJECT_URL, ORY_AGENT_API_KEY, ORY_OAUTH2_CLIENT_ID) take precedence when set.");
|
|
266
|
+
console.log("Environment variables (ORY_PROJECT_URL, ORY_AGENT_API_KEY, ORY_OAUTH2_CLIENT_ID, ORY_USER_LOGIN) take precedence when set.");
|
|
180
267
|
}
|
|
181
268
|
/**
|
|
182
269
|
* Print the "Configuration:" block showing Ory project URL and API key status.
|
|
@@ -189,10 +276,13 @@ function printOryConfig() {
|
|
|
189
276
|
console.log(` Config file: ${configPath}`);
|
|
190
277
|
console.log(` Mode: ${resolved.auditOnly ? "audit-only" : "full"}`);
|
|
191
278
|
console.log(` Project URL: ${resolved.projectUrl ?? "NOT SET"} [source: ${resolved.projectUrlSource}]`);
|
|
279
|
+
console.log(` Project ID: ${resolved.projectId ?? "NOT SET"} [source: ${resolved.projectIdSource}]`);
|
|
192
280
|
console.log(` API Key: ${resolved.apiKey ? "(set)" : "NOT SET"} [source: ${resolved.apiKeySource}]`);
|
|
193
281
|
console.log(` OAuth2 Client: ${resolved.oauth2ClientId ?? "NOT SET"} [source: ${resolved.oauth2ClientIdSource}]`);
|
|
194
282
|
console.log(` Permission mode: ${resolved.permissionMode} [source: ${resolved.permissionModeSource}]`);
|
|
283
|
+
console.log(` User login: ${resolved.userLogin ? "on" : "off"} [source: ${resolved.userLoginSource}]`);
|
|
195
284
|
console.log(` Namespace: ${namespace}`);
|
|
285
|
+
console.log(` User subject ns: ${resolved.userSubjectNamespace ?? "(direct subject id)"} [source: ${resolved.userSubjectNamespaceSource}]`);
|
|
196
286
|
}
|
|
197
287
|
/**
|
|
198
288
|
* Print the "Environment:" block showing Ory-related environment variables.
|
|
@@ -201,6 +291,9 @@ function printEnvironment() {
|
|
|
201
291
|
console.log("");
|
|
202
292
|
console.log("Environment:");
|
|
203
293
|
const vars = [
|
|
294
|
+
["ORY_PROJECT_URL", process.env.ORY_PROJECT_URL, false],
|
|
295
|
+
["ORY_SDK_URL", process.env.ORY_SDK_URL, false],
|
|
296
|
+
["ORY_PROJECT_ID", process.env.ORY_PROJECT_ID, false],
|
|
204
297
|
["ORY_USER_LOGIN", process.env.ORY_USER_LOGIN, false],
|
|
205
298
|
[
|
|
206
299
|
"ORY_AGENT_API_KEY",
|
|
@@ -238,10 +331,17 @@ function printEnvironment() {
|
|
|
238
331
|
}
|
|
239
332
|
}
|
|
240
333
|
/**
|
|
241
|
-
* Print the last 5 debug log entries
|
|
334
|
+
* Print the last 5 debug log entries. When `harness` is given the path is
|
|
335
|
+
* resolved the same way the plugin does at runtime — the default per-harness
|
|
336
|
+
* data-dir location when `ORY_AGENT_LOG_FILE` is unset — so `status` finds the
|
|
337
|
+
* log without the reader hand-setting env vars. The debug log only exists when
|
|
338
|
+
* a session ran with `ORY_AGENT_DEBUG=true`; when it doesn't, this prints a
|
|
339
|
+
* one-line pointer on how to turn it on rather than staying silent.
|
|
242
340
|
*/
|
|
243
|
-
function printLogTail() {
|
|
244
|
-
const logFile =
|
|
341
|
+
function printLogTail(harness) {
|
|
342
|
+
const logFile = harness
|
|
343
|
+
? (0, client_js_1.resolveDebugLogPath)(harness)
|
|
344
|
+
: process.env.ORY_AGENT_LOG_FILE;
|
|
245
345
|
if (logFile && fs.existsSync(logFile)) {
|
|
246
346
|
const lines = fs.readFileSync(logFile, "utf-8").trim().split("\n");
|
|
247
347
|
console.log("");
|
|
@@ -257,6 +357,12 @@ function printLogTail() {
|
|
|
257
357
|
}
|
|
258
358
|
}
|
|
259
359
|
}
|
|
360
|
+
else if (harness) {
|
|
361
|
+
console.log("");
|
|
362
|
+
console.log(logFile
|
|
363
|
+
? `Debug log: none yet — run a session with ORY_AGENT_DEBUG=true to write ${logFile}`
|
|
364
|
+
: "Debug log: disabled (ORY_AGENT_LOG_FILE set empty)");
|
|
365
|
+
}
|
|
260
366
|
}
|
|
261
367
|
/**
|
|
262
368
|
* Print the "Configure your Ory credentials" help text.
|
|
@@ -266,7 +372,7 @@ function printEnvHelp(binName) {
|
|
|
266
372
|
console.log("Configure your Ory credentials (one of these methods):");
|
|
267
373
|
console.log("");
|
|
268
374
|
console.log(" Option 1 — Save to config file (persists across sessions):");
|
|
269
|
-
console.log(`
|
|
375
|
+
console.log(` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url https://your-project.projects.oryapis.com \\`);
|
|
270
376
|
console.log(" --oauth2-client-id <public OAuth2 client id> \\");
|
|
271
377
|
console.log(" --api-key ory_pat_...");
|
|
272
378
|
console.log("");
|
|
@@ -278,10 +384,17 @@ function printEnvHelp(binName) {
|
|
|
278
384
|
console.log("If neither is set when a session starts, the agent will prompt for configuration.");
|
|
279
385
|
}
|
|
280
386
|
/**
|
|
281
|
-
* Print the last 5 trace
|
|
387
|
+
* Print the last 5 trace spans. When `harness` is given the path is resolved
|
|
388
|
+
* the same way the plugin does at runtime — the default per-harness data-dir
|
|
389
|
+
* location when `ORY_AGENT_TRACE_FILE` is unset — so `status` shows recent
|
|
390
|
+
* activity out of the box (traces are written on every recorded span). When no
|
|
391
|
+
* spans have been recorded yet, prints a one-line pointer at the trace file so
|
|
392
|
+
* the reader knows where to look (and how to watch it live).
|
|
282
393
|
*/
|
|
283
|
-
function printTraceTail() {
|
|
284
|
-
const traceFile =
|
|
394
|
+
function printTraceTail(harness) {
|
|
395
|
+
const traceFile = harness
|
|
396
|
+
? (0, client_js_1.resolveTraceFilePath)(harness)
|
|
397
|
+
: process.env.ORY_AGENT_TRACE_FILE;
|
|
285
398
|
if (traceFile && fs.existsSync(traceFile)) {
|
|
286
399
|
const lines = fs.readFileSync(traceFile, "utf-8").trim().split("\n");
|
|
287
400
|
console.log("");
|
|
@@ -297,22 +410,32 @@ function printTraceTail() {
|
|
|
297
410
|
}
|
|
298
411
|
}
|
|
299
412
|
}
|
|
413
|
+
else if (harness) {
|
|
414
|
+
console.log("");
|
|
415
|
+
console.log(traceFile
|
|
416
|
+
? `Trace file: none yet — spans land in ${traceFile} once a session runs a tool`
|
|
417
|
+
: "Trace file: disabled (ORY_AGENT_TRACE_FILE set empty)");
|
|
418
|
+
}
|
|
300
419
|
}
|
|
301
420
|
/**
|
|
302
421
|
* Run the live trace watcher. Tails the NDJSON trace file and prints
|
|
303
422
|
* formatted spans to stdout as they arrive. Blocks until interrupted.
|
|
304
423
|
*/
|
|
305
|
-
function runWatchCommand(args) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
424
|
+
function runWatchCommand(harness, args) {
|
|
425
|
+
// Precedence: explicit arg → resolved default (honors ORY_AGENT_TRACE_FILE,
|
|
426
|
+
// falling back to the per-harness data-dir path). The resolver returns
|
|
427
|
+
// undefined only when tracing is explicitly disabled (ORY_AGENT_TRACE_FILE
|
|
428
|
+
// set empty), so that's the one case that dead-ends here.
|
|
429
|
+
const traceFile = args[0] || (0, client_js_1.resolveTraceFilePath)(harness);
|
|
310
430
|
if (!traceFile) {
|
|
311
|
-
console.error("
|
|
312
|
-
"
|
|
431
|
+
console.error("Trace file is disabled (ORY_AGENT_TRACE_FILE is set empty).\n" +
|
|
432
|
+
"Unset it, or pass a path: watch <trace-file>\n");
|
|
313
433
|
process.exit(1);
|
|
314
434
|
}
|
|
315
435
|
console.log(`Watching traces: ${traceFile}`);
|
|
436
|
+
if (!fs.existsSync(traceFile)) {
|
|
437
|
+
console.log("(file doesn't exist yet — waiting for the first span…)");
|
|
438
|
+
}
|
|
316
439
|
console.log("Press Ctrl+C to stop.\n");
|
|
317
440
|
const stop = (0, tracer_js_1.watchTraceFile)(traceFile, (span) => {
|
|
318
441
|
console.log((0, tracer_js_1.formatSpan)(span));
|
|
@@ -382,7 +505,7 @@ async function promptForProjectUrl(binName) {
|
|
|
382
505
|
"--------------------------------------------",
|
|
383
506
|
"",
|
|
384
507
|
"No Ory project URL is configured for this session.",
|
|
385
|
-
`Enter your Ory project URL to continue, or press Enter to skip and run
|
|
508
|
+
`Enter your Ory project URL to continue, or press Enter to skip and run \`${(0, cli_invocation_js_1.oryNpx)(binName)} configure\` later.`,
|
|
386
509
|
"",
|
|
387
510
|
"Example: https://your-project.projects.oryapis.com",
|
|
388
511
|
"",
|
|
@@ -430,10 +553,10 @@ async function interactiveConfigPrompt(binName) {
|
|
|
430
553
|
"Run one of the following commands in another terminal:",
|
|
431
554
|
"",
|
|
432
555
|
" Connect to Ory (enables auth & permission checks):",
|
|
433
|
-
`
|
|
556
|
+
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --project-url <URL> --oauth2-client-id <CLIENT_ID> [--api-key <KEY>]`,
|
|
434
557
|
"",
|
|
435
558
|
" Or, enable audit logging only (no auth or permission checks):",
|
|
436
|
-
`
|
|
559
|
+
` ${(0, cli_invocation_js_1.oryNpx)(binName)} configure --audit-only`,
|
|
437
560
|
"",
|
|
438
561
|
`Config is saved to ${configPath}`,
|
|
439
562
|
"and shared across all agent plugins.",
|
|
@@ -538,31 +661,16 @@ async function runAgentUnregister() {
|
|
|
538
661
|
console.log("No registered agent client to unregister. Nothing to do.");
|
|
539
662
|
return 0;
|
|
540
663
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
basePath: persisted.projectUrl,
|
|
544
|
-
accessToken: persisted.registrationAccessToken,
|
|
545
|
-
}));
|
|
546
|
-
try {
|
|
547
|
-
await oidc.deleteOidcDynamicClient({ id: persisted.clientId });
|
|
548
|
-
}
|
|
549
|
-
catch (err) {
|
|
550
|
-
const status = err?.response?.status;
|
|
551
|
-
if (status === 404) {
|
|
552
|
-
// Already gone server-side; nothing to warn about.
|
|
553
|
-
}
|
|
554
|
-
else if (typeof status === "number") {
|
|
555
|
-
console.warn(`Warning: server-side DELETE returned HTTP ${status}. Local state will be cleared anyway.`);
|
|
556
|
-
}
|
|
557
|
-
else {
|
|
558
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
559
|
-
console.warn(`Warning: server-side DELETE failed (${msg}). Local state will be cleared anyway.`);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
else {
|
|
664
|
+
const outcome = await (0, agent_auth_js_1.revokeAgentDynamicClient)(persisted);
|
|
665
|
+
if (outcome.status === "skipped") {
|
|
564
666
|
console.warn("Warning: no registration_access_token was persisted, so we cannot DELETE the server-side client. Clearing local state only.");
|
|
565
667
|
}
|
|
668
|
+
else if (outcome.status === "failed") {
|
|
669
|
+
const detail = typeof outcome.httpStatus === "number"
|
|
670
|
+
? `returned HTTP ${outcome.httpStatus}`
|
|
671
|
+
: `failed (${outcome.message})`;
|
|
672
|
+
console.warn(`Warning: server-side DELETE ${detail}. Local state will be cleared anyway.`);
|
|
673
|
+
}
|
|
566
674
|
(0, agent_auth_js_1.clearAgentDynamicCredentials)();
|
|
567
675
|
console.log(`Unregistered agent client ${persisted.clientId}.`);
|
|
568
676
|
return 0;
|
package/dist/client.d.ts
CHANGED
|
@@ -13,6 +13,13 @@ export interface OryAgentConfig {
|
|
|
13
13
|
logFile?: string;
|
|
14
14
|
/** Optional NDJSON trace file path for structured span output */
|
|
15
15
|
traceFile?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Permission-check subject namespace for the human user. When set, the
|
|
18
|
+
* user is addressed as a SubjectSet `<namespace>:<subject>` (matching how
|
|
19
|
+
* the tuples were written in Keto) rather than a direct SubjectID. Read by
|
|
20
|
+
* {@link resolveUserSubject}; `ORY_USER_SUBJECT_NAMESPACE` overrides it.
|
|
21
|
+
*/
|
|
22
|
+
userSubjectNamespace?: string;
|
|
16
23
|
/**
|
|
17
24
|
* Session cache TTL in milliseconds.
|
|
18
25
|
* Set to 0 to disable caching. Default: 60_000 (1 minute).
|
|
@@ -58,6 +65,13 @@ export declare class OryAgentClient {
|
|
|
58
65
|
get userPrincipal(): PrincipalIdentity;
|
|
59
66
|
/** Snapshot of the current agent principal. */
|
|
60
67
|
get agentPrincipal(): PrincipalIdentity;
|
|
68
|
+
/**
|
|
69
|
+
* Configured user-subject namespace (from config, resolved at construction).
|
|
70
|
+
* `resolveUserSubject` uses this as the SubjectSet namespace when the
|
|
71
|
+
* `ORY_USER_SUBJECT_NAMESPACE` env var isn't set. Undefined ⇒ direct
|
|
72
|
+
* SubjectID resolution.
|
|
73
|
+
*/
|
|
74
|
+
get userSubjectNamespace(): string | undefined;
|
|
61
75
|
/**
|
|
62
76
|
* Set or update the human user principal. The user is the subject of
|
|
63
77
|
* permission checks but does not authenticate outgoing API calls.
|
|
@@ -151,6 +165,19 @@ export declare class OryAgentClient {
|
|
|
151
165
|
*/
|
|
152
166
|
static fromEnv(harness: string): OryAgentClient;
|
|
153
167
|
}
|
|
168
|
+
/** Default debug-log path under the shared per-harness data dir. */
|
|
169
|
+
export declare const DEFAULT_DEBUG_LOG_FILENAME = "ory-agent-debug.log";
|
|
170
|
+
/** Default trace (NDJSON) path under the shared per-harness data dir. */
|
|
171
|
+
export declare const DEFAULT_TRACE_FILENAME = "ory-agent-trace.ndjson";
|
|
172
|
+
/**
|
|
173
|
+
* Debug log path. Only written when `ORY_AGENT_DEBUG=true` (the logger gates
|
|
174
|
+
* on that); defaulting the path just means an enabled debug session lands in a
|
|
175
|
+
* file automatically — important for subprocess-hook harnesses whose stderr
|
|
176
|
+
* the harness may swallow.
|
|
177
|
+
*/
|
|
178
|
+
export declare function resolveDebugLogPath(harness: string): string | undefined;
|
|
179
|
+
/** Trace (NDJSON) path. Written on every recorded span when set. */
|
|
180
|
+
export declare function resolveTraceFilePath(harness: string): string | undefined;
|
|
154
181
|
/**
|
|
155
182
|
* Pull the Ory backend request ID from a response headers bag (axios returns
|
|
156
183
|
* lowercase header names). Returns undefined when not present.
|
package/dist/client.js
CHANGED
|
@@ -1,8 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OryAgentClient = void 0;
|
|
36
|
+
exports.DEFAULT_TRACE_FILENAME = exports.DEFAULT_DEBUG_LOG_FILENAME = exports.OryAgentClient = void 0;
|
|
37
|
+
exports.resolveDebugLogPath = resolveDebugLogPath;
|
|
38
|
+
exports.resolveTraceFilePath = resolveTraceFilePath;
|
|
4
39
|
exports.extractOryRequestId = extractOryRequestId;
|
|
5
40
|
const client_1 = require("@ory/client");
|
|
41
|
+
const path = __importStar(require("node:path"));
|
|
6
42
|
const logger_js_1 = require("./logger.js");
|
|
7
43
|
const tracer_js_1 = require("./tracer.js");
|
|
8
44
|
const config_js_1 = require("./config.js");
|
|
@@ -75,6 +111,15 @@ class OryAgentClient {
|
|
|
75
111
|
get agentPrincipal() {
|
|
76
112
|
return { ...this._agentPrincipal };
|
|
77
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Configured user-subject namespace (from config, resolved at construction).
|
|
116
|
+
* `resolveUserSubject` uses this as the SubjectSet namespace when the
|
|
117
|
+
* `ORY_USER_SUBJECT_NAMESPACE` env var isn't set. Undefined ⇒ direct
|
|
118
|
+
* SubjectID resolution.
|
|
119
|
+
*/
|
|
120
|
+
get userSubjectNamespace() {
|
|
121
|
+
return this.config.userSubjectNamespace;
|
|
122
|
+
}
|
|
78
123
|
/**
|
|
79
124
|
* Set or update the human user principal. The user is the subject of
|
|
80
125
|
* permission checks but does not authenticate outgoing API calls.
|
|
@@ -600,6 +645,8 @@ class OryAgentClient {
|
|
|
600
645
|
static fromEnv(harness) {
|
|
601
646
|
const resolved = (0, config_js_1.resolveConfig)();
|
|
602
647
|
const projectUrl = resolved.projectUrl;
|
|
648
|
+
const logFile = resolveDebugLogPath(harness);
|
|
649
|
+
const traceFile = resolveTraceFilePath(harness);
|
|
603
650
|
if (!projectUrl) {
|
|
604
651
|
// Use a placeholder URL so the client can be constructed.
|
|
605
652
|
// API calls will fail with network_error which is handled as fail-open.
|
|
@@ -607,8 +654,9 @@ class OryAgentClient {
|
|
|
607
654
|
projectUrl: "http://localhost:0",
|
|
608
655
|
apiKey: resolved.apiKey,
|
|
609
656
|
harness,
|
|
610
|
-
logFile
|
|
611
|
-
traceFile
|
|
657
|
+
logFile,
|
|
658
|
+
traceFile,
|
|
659
|
+
userSubjectNamespace: resolved.userSubjectNamespace,
|
|
612
660
|
sessionCacheTtlMs: process.env.ORY_SESSION_CACHE_TTL_MS
|
|
613
661
|
? parseInt(process.env.ORY_SESSION_CACHE_TTL_MS, 10)
|
|
614
662
|
: undefined,
|
|
@@ -625,8 +673,9 @@ class OryAgentClient {
|
|
|
625
673
|
projectUrl,
|
|
626
674
|
apiKey: resolved.apiKey,
|
|
627
675
|
harness,
|
|
628
|
-
logFile
|
|
629
|
-
traceFile
|
|
676
|
+
logFile,
|
|
677
|
+
traceFile,
|
|
678
|
+
userSubjectNamespace: resolved.userSubjectNamespace,
|
|
630
679
|
sessionCacheTtlMs: process.env.ORY_SESSION_CACHE_TTL_MS
|
|
631
680
|
? parseInt(process.env.ORY_SESSION_CACHE_TTL_MS, 10)
|
|
632
681
|
: undefined,
|
|
@@ -640,6 +689,37 @@ class OryAgentClient {
|
|
|
640
689
|
}
|
|
641
690
|
}
|
|
642
691
|
exports.OryAgentClient = OryAgentClient;
|
|
692
|
+
/** Default debug-log path under the shared per-harness data dir. */
|
|
693
|
+
exports.DEFAULT_DEBUG_LOG_FILENAME = "ory-agent-debug.log";
|
|
694
|
+
/** Default trace (NDJSON) path under the shared per-harness data dir. */
|
|
695
|
+
exports.DEFAULT_TRACE_FILENAME = "ory-agent-trace.ndjson";
|
|
696
|
+
/**
|
|
697
|
+
* Resolve a file path from an env var with a sensible default under the
|
|
698
|
+
* per-harness data dir. Semantics:
|
|
699
|
+
* - unset → the default path (so post-install runs are observable
|
|
700
|
+
* without hand-setting env vars),
|
|
701
|
+
* - set to a path → that path (operator / dev-launcher override),
|
|
702
|
+
* - set but empty → `undefined` (explicit opt-out, e.g. `ORY_AGENT_TRACE_FILE=`).
|
|
703
|
+
*/
|
|
704
|
+
function resolveFilePath(envValue, defaultPath) {
|
|
705
|
+
if (envValue === undefined)
|
|
706
|
+
return defaultPath;
|
|
707
|
+
const trimmed = envValue.trim();
|
|
708
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Debug log path. Only written when `ORY_AGENT_DEBUG=true` (the logger gates
|
|
712
|
+
* on that); defaulting the path just means an enabled debug session lands in a
|
|
713
|
+
* file automatically — important for subprocess-hook harnesses whose stderr
|
|
714
|
+
* the harness may swallow.
|
|
715
|
+
*/
|
|
716
|
+
function resolveDebugLogPath(harness) {
|
|
717
|
+
return resolveFilePath(process.env.ORY_AGENT_LOG_FILE, path.join((0, config_js_1.getHarnessDataDir)(harness), exports.DEFAULT_DEBUG_LOG_FILENAME));
|
|
718
|
+
}
|
|
719
|
+
/** Trace (NDJSON) path. Written on every recorded span when set. */
|
|
720
|
+
function resolveTraceFilePath(harness) {
|
|
721
|
+
return resolveFilePath(process.env.ORY_AGENT_TRACE_FILE, path.join((0, config_js_1.getHarnessDataDir)(harness), exports.DEFAULT_TRACE_FILENAME));
|
|
722
|
+
}
|
|
643
723
|
function attachOtlpExporterFromEnv(client, harness) {
|
|
644
724
|
const meta = client.tracer.processMetadata;
|
|
645
725
|
const exporter = (0, otlp_js_1.otlpExporterFromEnv)({
|