callkaro-cli-unofficial 0.6.0 → 0.6.1
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/commands/admin.js
CHANGED
|
@@ -161,7 +161,7 @@ async function adminImpersonateCommand(clientId, opts) {
|
|
|
161
161
|
if (existing.token && !(await (0, ui_1.confirm)(`${clientEmail} already has a stored login. Replace it with the impersonated token?`, opts.yes))) {
|
|
162
162
|
return;
|
|
163
163
|
}
|
|
164
|
-
const { token, email: adminEmail } = await (0, adminAuth_1.impersonateClient)(clientId, { adminEmail: (await (0, adminAuth_1.requireAdmin)()).email });
|
|
164
|
+
const { token, email: adminEmail, dashboard } = await (0, adminAuth_1.impersonateClient)(clientId, { adminEmail: (await (0, adminAuth_1.requireAdmin)()).email });
|
|
165
165
|
// activate: false — the admin's own account stays the default.
|
|
166
166
|
(0, config_1.saveAccount)(clientEmail, {
|
|
167
167
|
token,
|
|
@@ -169,11 +169,13 @@ async function adminImpersonateCommand(clientId, opts) {
|
|
|
169
169
|
monitoring: { id: clientId, name: client.name, email: clientEmail },
|
|
170
170
|
impersonated: { adminEmail, clientId },
|
|
171
171
|
}, { activate: false });
|
|
172
|
+
(0, config_1.saveDashboardSession)(clientEmail, { email: clientEmail, ...dashboard, savedAt: new Date().toISOString() });
|
|
172
173
|
(0, ui_1.success)(`Impersonating ${client.name || clientEmail} (${clientEmail}).`);
|
|
173
174
|
(0, ui_1.info)(' minted a ck_ token through the admin console and stored it, scoped to that client account.');
|
|
174
175
|
(0, ui_1.info)(` Use it: cku accounts use ${clientEmail}`);
|
|
175
176
|
(0, ui_1.info)(` Or pin a folder: cku accounts bind ${clientEmail}`);
|
|
176
|
-
(0, ui_1.info)('
|
|
177
|
+
(0, ui_1.info)(' Also stored a dashboard session for it, so `cku dashboard api` reaches /v2/agents/.');
|
|
178
|
+
(0, ui_1.info)(' Both renew themselves by impersonating again.');
|
|
177
179
|
}
|
|
178
180
|
catch (err) {
|
|
179
181
|
(0, ui_1.handleError)(err);
|
package/dist/lib/adminAuth.js
CHANGED
|
@@ -304,7 +304,14 @@ async function impersonateClient(clientId, opts = {}) {
|
|
|
304
304
|
if (polled.status !== 'approved' || !polled.token) {
|
|
305
305
|
throw new Error(`The approval session ended with status "${polled.status}" instead of an approved token.`);
|
|
306
306
|
}
|
|
307
|
-
|
|
307
|
+
// Hop 2 also produced a dashboard session for the client: the body JWT is the
|
|
308
|
+
// `/v2/agents/` bearer and the `access_token` cookie serves the rest. Kept,
|
|
309
|
+
// because function code only saves through `PUT /v2/agents/:id?version=`.
|
|
310
|
+
return {
|
|
311
|
+
token: polled.token,
|
|
312
|
+
email: adminEmail,
|
|
313
|
+
dashboard: { token: impersonationToken, sessionToken: sessionJar.get('access_token') },
|
|
314
|
+
};
|
|
308
315
|
}
|
|
309
316
|
/**
|
|
310
317
|
* Re-mint an impersonated token. Used by the renewal path: an impersonated
|
package/dist/lib/dashboardApi.js
CHANGED
|
@@ -250,7 +250,11 @@ function dashboardApi() {
|
|
|
250
250
|
* accept either token everywhere, and guessing produces an unexplained 401.
|
|
251
251
|
*/
|
|
252
252
|
function usesCookieAuth(path) {
|
|
253
|
-
|
|
253
|
+
// Only the list route takes the bearer. `/v2/agents/:id…` — including the
|
|
254
|
+
// version save `PUT /v2/agents/:id?version=` — takes the cookie and answers
|
|
255
|
+
// the bearer with 401 (probed 21 October 2026 with getAgentVersions).
|
|
256
|
+
const route = path.split('?')[0];
|
|
257
|
+
return route !== '/v2/agents/' && route !== '/v2/agents';
|
|
254
258
|
}
|
|
255
259
|
/** `?a=1&b=2`, skipping undefined and empty. Mirrors the one in api.ts. */
|
|
256
260
|
function qs(params) {
|
|
@@ -153,7 +153,24 @@ async function requireDashboard() {
|
|
|
153
153
|
// With a stored password, renew a minute early so the token cannot lapse
|
|
154
154
|
// mid-request; without one a token that still has time left is still valid.
|
|
155
155
|
const left = session.sessionToken ? msUntilExpiry(session.sessionToken) : 0;
|
|
156
|
-
|
|
156
|
+
const impersonated = slug ? (0, config_1.loadAccount)(slug).impersonated : undefined;
|
|
157
|
+
if (left !== undefined && left <= (session.password || impersonated ? 60_000 : 0)) {
|
|
158
|
+
// A session minted by `cku admin impersonate` has no password; it renews by
|
|
159
|
+
// impersonating again, which also re-issues the account's ck_ token.
|
|
160
|
+
if (impersonated) {
|
|
161
|
+
try {
|
|
162
|
+
const { impersonateClient } = require('./adminAuth');
|
|
163
|
+
const fresh = await impersonateClient(impersonated.clientId, { adminEmail: impersonated.adminEmail });
|
|
164
|
+
const renewed = { email: session.email, ...fresh.dashboard, savedAt: new Date().toISOString() };
|
|
165
|
+
saveDashboard(email, renewed);
|
|
166
|
+
return { token: renewed.token, sessionToken: renewed.sessionToken, email: renewed.email };
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
throw new Error(`Dashboard session for ${email} expired and re-impersonating failed: ${err.message}
|
|
170
|
+
` +
|
|
171
|
+
' Run: cku admin login, then cku admin impersonate ' + impersonated.clientId);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
157
174
|
if (!session.password) {
|
|
158
175
|
const why = session.sessionToken
|
|
159
176
|
? `Dashboard session for ${email} expired ${new Date(Date.now() + left).toLocaleString('en-US')}.\n` +
|