driggsby 0.1.12 → 0.1.13

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.
Files changed (46) hide show
  1. package/.gitignore +2 -0
  2. package/README.md +16 -11
  3. package/binary-install.js +212 -0
  4. package/binary.js +128 -0
  5. package/install.js +4 -0
  6. package/npm-shrinkwrap.json +545 -0
  7. package/package.json +53 -41
  8. package/run-driggsby.js +4 -0
  9. package/dist/auth/browser.js +0 -31
  10. package/dist/auth/config.js +0 -23
  11. package/dist/auth/discovery.js +0 -42
  12. package/dist/auth/dpop.js +0 -44
  13. package/dist/auth/login.js +0 -126
  14. package/dist/auth/loopback.js +0 -157
  15. package/dist/auth/oauth.js +0 -136
  16. package/dist/auth/pkce.js +0 -12
  17. package/dist/auth/url-security.js +0 -16
  18. package/dist/broker/authentication.js +0 -49
  19. package/dist/broker/client.js +0 -148
  20. package/dist/broker/daemon.js +0 -65
  21. package/dist/broker/file-secret-store.js +0 -130
  22. package/dist/broker/installation.js +0 -154
  23. package/dist/broker/ipc.js +0 -12
  24. package/dist/broker/keyring-secret-store.js +0 -42
  25. package/dist/broker/launch.js +0 -35
  26. package/dist/broker/lock.js +0 -84
  27. package/dist/broker/remote-mcp.js +0 -129
  28. package/dist/broker/remote-session.js +0 -173
  29. package/dist/broker/resolve-secret-store.js +0 -52
  30. package/dist/broker/secret-store.js +0 -13
  31. package/dist/broker/server.js +0 -177
  32. package/dist/broker/session.js +0 -31
  33. package/dist/broker/test-support.js +0 -258
  34. package/dist/broker/types.js +0 -1
  35. package/dist/cli/commands/broker-daemon.js +0 -4
  36. package/dist/cli/commands/login.js +0 -35
  37. package/dist/cli/commands/logout.js +0 -20
  38. package/dist/cli/commands/status.js +0 -13
  39. package/dist/cli/format.js +0 -84
  40. package/dist/index.js +0 -39
  41. package/dist/lib/json-file.js +0 -36
  42. package/dist/lib/retry.js +0 -22
  43. package/dist/lib/runtime-paths.js +0 -62
  44. package/dist/lib/user-guidance.js +0 -19
  45. package/dist/shim/server.js +0 -143
  46. package/dist/shim/stdio-transport.js +0 -106
@@ -1,129 +0,0 @@
1
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
3
- import { CallToolResultSchema, ListToolsResultSchema, } from "@modelcontextprotocol/sdk/types.js";
4
- import { createDpopProof } from "../auth/dpop.js";
5
- import { assertBrokerRemoteUrl } from "../auth/url-security.js";
6
- import { buildReauthenticationRequiredMessage } from "../lib/user-guidance.js";
7
- const BROKER_CLIENT_INFO = {
8
- name: "driggsby-local-broker",
9
- version: "0.1.0",
10
- };
11
- export async function listRemoteTools(session, dpopKeyPair) {
12
- return await withRemoteClient(session, dpopKeyPair, async (client) => {
13
- const result = await client.request({
14
- method: "tools/list",
15
- params: {},
16
- }, ListToolsResultSchema);
17
- return result.tools;
18
- });
19
- }
20
- export async function callRemoteTool(session, dpopKeyPair, name, args) {
21
- return await withRemoteClient(session, dpopKeyPair, async (client) => {
22
- return await client.request({
23
- method: "tools/call",
24
- params: args === undefined
25
- ? { name }
26
- : {
27
- arguments: args,
28
- name,
29
- },
30
- }, CallToolResultSchema);
31
- });
32
- }
33
- async function withRemoteClient(session, dpopKeyPair, action) {
34
- assertBrokerRemoteUrl(session.resource, "The Driggsby MCP resource URL");
35
- const transport = new StreamableHTTPClientTransport(new URL(session.resource), {
36
- fetch: createDpopAuthenticatedFetch(session, dpopKeyPair),
37
- });
38
- const client = new Client(BROKER_CLIENT_INFO, {
39
- capabilities: {},
40
- });
41
- try {
42
- await client.connect(toTransport(transport));
43
- return await action(client);
44
- }
45
- catch (error) {
46
- throw mapRemoteMcpError(error);
47
- }
48
- finally {
49
- await closeRemoteTransport(transport);
50
- }
51
- }
52
- function toTransport(transport) {
53
- return transport;
54
- }
55
- function mapRemoteMcpError(error) {
56
- if (!(error instanceof Error)) {
57
- return new Error("Driggsby could not complete that remote MCP request. Try again in a moment.");
58
- }
59
- const message = error.message.toLowerCase();
60
- if (message.includes("tool") && message.includes("not found")) {
61
- return new Error("That Driggsby tool is not available in this session anymore. Start a fresh client session and try again.");
62
- }
63
- if (message.includes("fetch failed") ||
64
- message.includes("failed to open sse stream") ||
65
- message.includes("error posting to endpoint") ||
66
- message.includes("streamable http error") ||
67
- message.includes("sse stream disconnected")) {
68
- return new Error("Driggsby could not reach the remote MCP service right now. Try again in a moment.");
69
- }
70
- return error;
71
- }
72
- async function closeRemoteTransport(transport) {
73
- try {
74
- await transport.terminateSession();
75
- }
76
- catch {
77
- // Best-effort cleanup only.
78
- }
79
- await transport.close();
80
- }
81
- function createDpopAuthenticatedFetch(session, dpopKeyPair) {
82
- return async (input, init) => {
83
- const httpMethod = resolveRequestMethod(input, init);
84
- const headers = new Headers(input instanceof Request ? input.headers : undefined);
85
- if (init?.headers !== undefined) {
86
- new Headers(init.headers).forEach((value, key) => {
87
- headers.set(key, value);
88
- });
89
- }
90
- headers.set("Authorization", `${session.tokenType} ${session.accessToken}`);
91
- headers.set("DPoP", await createDpopProof({
92
- accessToken: session.accessToken,
93
- httpMethod,
94
- privateJwk: dpopKeyPair.privateJwk,
95
- publicJwk: dpopKeyPair.publicJwk,
96
- targetUrl: resolveRequestUrl(input),
97
- }));
98
- return await ensureAuthenticatedRemoteResponse(fetch(input, {
99
- ...init,
100
- headers,
101
- method: httpMethod,
102
- }));
103
- };
104
- }
105
- async function ensureAuthenticatedRemoteResponse(responsePromise) {
106
- const response = await responsePromise;
107
- if (response.status === 401 || response.status === 403) {
108
- throw new Error(buildReauthenticationRequiredMessage("Authentication has expired or the saved broker session is no longer authorized for Driggsby"));
109
- }
110
- return response;
111
- }
112
- function resolveRequestMethod(input, init) {
113
- if (init?.method !== undefined) {
114
- return init.method;
115
- }
116
- if (input instanceof Request) {
117
- return input.method;
118
- }
119
- return "GET";
120
- }
121
- function resolveRequestUrl(input) {
122
- if (typeof input === "string") {
123
- return input;
124
- }
125
- if (input instanceof URL) {
126
- return input.toString();
127
- }
128
- return input.url;
129
- }
@@ -1,173 +0,0 @@
1
- import { fetchAuthorizationServerMetadata, } from "../auth/discovery.js";
2
- import { createDpopProof } from "../auth/dpop.js";
3
- import { refreshAccessToken } from "../auth/oauth.js";
4
- import { assertBrokerRemoteUrl } from "../auth/url-security.js";
5
- import { retryOperation } from "../lib/retry.js";
6
- import { buildReauthenticationRequiredMessage, DRIGGSBY_LOGIN_COMMAND, DRIGGSBY_STATUS_COMMAND, errorMessageIncludesReauthenticationCommand, } from "../lib/user-guidance.js";
7
- import { readBrokerDpopKeyPair } from "./installation.js";
8
- import { readBrokerRemoteSession, summarizeBrokerRemoteSession, writeBrokerRemoteSession, } from "./session.js";
9
- const ACCESS_TOKEN_REFRESH_SKEW_MS = 60_000;
10
- const STATUS_REFRESH_RETRY_DELAYS_MS = [0, 250, 500];
11
- export class BrokerRemoteSessionManager {
12
- brokerId;
13
- fetchImpl;
14
- runtimePaths;
15
- secretStore;
16
- refreshInFlight = null;
17
- constructor(options) {
18
- this.brokerId = options.brokerId;
19
- this.fetchImpl = options.fetchImpl ?? fetch;
20
- this.runtimePaths = options.runtimePaths;
21
- this.secretStore = options.secretStore;
22
- }
23
- async ensureFreshSession() {
24
- const session = await readBrokerRemoteSession(this.secretStore, this.brokerId);
25
- if (session === null) {
26
- throw new Error(buildReauthenticationRequiredMessage("The local Driggsby broker is not connected"));
27
- }
28
- if (!sessionNeedsRefresh(session)) {
29
- return session;
30
- }
31
- this.refreshInFlight ??= refreshRemoteSession(this.runtimePaths, this.secretStore, this.brokerId, session, this.fetchImpl).finally(() => {
32
- this.refreshInFlight = null;
33
- });
34
- return await this.refreshInFlight;
35
- }
36
- }
37
- export async function ensureFreshRemoteSession(options) {
38
- const manager = new BrokerRemoteSessionManager(options);
39
- return await manager.ensureFreshSession();
40
- }
41
- export async function inspectRemoteSessionReadiness(options) {
42
- const session = await readBrokerRemoteSession(options.secretStore, options.brokerId);
43
- if (session === null) {
44
- return buildNotConnectedReadiness();
45
- }
46
- if (options.refreshIfNeeded && sessionNeedsRefresh(session)) {
47
- try {
48
- const refreshedSession = await retryOperation(async () => await ensureFreshRemoteSession(options), {
49
- delaysMs: STATUS_REFRESH_RETRY_DELAYS_MS,
50
- shouldRetry: shouldRetryStatusRefresh,
51
- });
52
- return buildReadyReadiness(refreshedSession);
53
- }
54
- catch (error) {
55
- return buildFailedRefreshReadiness(error, session);
56
- }
57
- }
58
- if (sessionNeedsRefresh(session)) {
59
- return {
60
- connected: true,
61
- detail: "The saved remote session needs a token refresh before remote MCP forwarding can run.",
62
- nextStepCommand: DRIGGSBY_STATUS_COMMAND,
63
- ready: false,
64
- reauthenticationRequired: false,
65
- session: summarizeBrokerRemoteSession(session),
66
- state: "temporarily_unavailable",
67
- };
68
- }
69
- return buildReadyReadiness(session);
70
- }
71
- export function sessionNeedsRefresh(session, nowMs = Date.now()) {
72
- const expiresAtMs = Date.parse(session.accessTokenExpiresAt);
73
- if (!Number.isFinite(expiresAtMs)) {
74
- return true;
75
- }
76
- return expiresAtMs - nowMs <= ACCESS_TOKEN_REFRESH_SKEW_MS;
77
- }
78
- async function refreshRemoteSession(runtimePaths, secretStore, brokerId, session, fetchImpl) {
79
- assertBrokerRemoteUrl(session.issuer, "The Driggsby issuer URL");
80
- let authorizationServerMetadata;
81
- try {
82
- authorizationServerMetadata = await fetchAuthorizationServerMetadata(session.issuer, fetchImpl);
83
- }
84
- catch {
85
- throw new Error("Driggsby could not refresh the local broker session right now because it could not reach the authorization server. Wait a moment and try again.");
86
- }
87
- let refreshedTokens;
88
- try {
89
- refreshedTokens = await refreshAccessToken({
90
- clientId: session.clientId,
91
- dpopProof: await refreshTokenDpopProof(runtimePaths, secretStore, brokerId, authorizationServerMetadata.token_endpoint),
92
- metadata: authorizationServerMetadata,
93
- refreshToken: session.refreshToken,
94
- resource: session.resource,
95
- }, fetchImpl);
96
- }
97
- catch (error) {
98
- throwRefreshSessionError(error);
99
- }
100
- const refreshedSession = {
101
- ...session,
102
- accessToken: refreshedTokens.accessToken,
103
- accessTokenExpiresAt: refreshedTokens.accessTokenExpiresAt,
104
- refreshToken: refreshedTokens.refreshToken,
105
- scope: refreshedTokens.scope,
106
- tokenType: refreshedTokens.tokenType,
107
- };
108
- await writeBrokerRemoteSession(secretStore, brokerId, refreshedSession);
109
- return refreshedSession;
110
- }
111
- async function refreshTokenDpopProof(runtimePaths, secretStore, brokerId, tokenEndpoint) {
112
- const dpopKeyPair = await readBrokerDpopKeyPair(runtimePaths, secretStore, brokerId);
113
- if (dpopKeyPair === null) {
114
- throw new Error(buildReauthenticationRequiredMessage("The local Driggsby broker key is missing"));
115
- }
116
- return await createDpopProof({
117
- httpMethod: "POST",
118
- privateJwk: dpopKeyPair.privateJwk,
119
- publicJwk: dpopKeyPair.publicJwk,
120
- targetUrl: tokenEndpoint,
121
- });
122
- }
123
- function throwRefreshSessionError(error) {
124
- if (errorMessageIncludesReauthenticationCommand(error)) {
125
- throw error;
126
- }
127
- throw new Error("Driggsby could not refresh the local broker session right now. Wait a moment and try again.");
128
- }
129
- function shouldRetryStatusRefresh(error) {
130
- return !errorMessageIncludesReauthenticationCommand(error);
131
- }
132
- function buildFailedRefreshReadiness(error, session) {
133
- if (errorMessageIncludesReauthenticationCommand(error)) {
134
- return {
135
- connected: true,
136
- detail: "The saved remote session is no longer authorized. Remote MCP forwarding will stay blocked until Driggsby signs in again.",
137
- nextStepCommand: DRIGGSBY_LOGIN_COMMAND,
138
- ready: false,
139
- reauthenticationRequired: true,
140
- session: summarizeBrokerRemoteSession(session),
141
- state: "reauth_required",
142
- };
143
- }
144
- return {
145
- connected: true,
146
- detail: "Driggsby could not refresh remote MCP access right now. Remote MCP forwarding is blocked until the refresh succeeds.",
147
- nextStepCommand: DRIGGSBY_STATUS_COMMAND,
148
- ready: false,
149
- reauthenticationRequired: false,
150
- session: summarizeBrokerRemoteSession(session),
151
- state: "temporarily_unavailable",
152
- };
153
- }
154
- export function buildNotConnectedReadiness() {
155
- return {
156
- connected: false,
157
- detail: "Driggsby does not have a saved remote session yet.",
158
- nextStepCommand: DRIGGSBY_LOGIN_COMMAND,
159
- ready: false,
160
- reauthenticationRequired: false,
161
- state: "not_connected",
162
- };
163
- }
164
- function buildReadyReadiness(session) {
165
- return {
166
- connected: true,
167
- detail: "Remote MCP forwarding is ready to use.",
168
- ready: true,
169
- reauthenticationRequired: false,
170
- session: summarizeBrokerRemoteSession(session),
171
- state: "ready",
172
- };
173
- }
@@ -1,52 +0,0 @@
1
- import { readBrokerMetadata } from "./installation.js";
2
- import { FileSecretStore } from "./file-secret-store.js";
3
- import { KeyringSecretStore } from "./keyring-secret-store.js";
4
- const KEYRING_UNAVAILABLE_WITH_EXISTING_INSTALL_MESSAGE = "This Driggsby broker install already depends on platform secure storage, but that storage is unavailable in this shell. Reopen the original desktop session or restore keyring access before using this install.";
5
- const LOGOUT_FALLBACK_NOTICE = "Platform secure storage is unavailable here, so logout will clear local broker files only. Any unreachable platform-keyring entries will remain until you return to the original session.";
6
- export class ExistingInstallRequiresKeyringError extends Error {
7
- constructor() {
8
- super(KEYRING_UNAVAILABLE_WITH_EXISTING_INSTALL_MESSAGE);
9
- this.name = "ExistingInstallRequiresKeyringError";
10
- }
11
- }
12
- export async function resolveSecretStore(runtimePaths, options = {}) {
13
- const fileStore = options.fileStore ?? new FileSecretStore(runtimePaths);
14
- if (await fileStore.hasStoredSecrets()) {
15
- return {
16
- backend: "file",
17
- notice: null,
18
- store: fileStore,
19
- };
20
- }
21
- const keyringStore = options.keyringStore ?? new KeyringSecretStore();
22
- if (await keyringStore.isAvailable()) {
23
- return {
24
- backend: "keyring",
25
- notice: null,
26
- store: keyringStore,
27
- };
28
- }
29
- if ((await readBrokerMetadata(runtimePaths)) !== null) {
30
- throw new ExistingInstallRequiresKeyringError();
31
- }
32
- return {
33
- backend: "file",
34
- notice: `Platform secure storage is unavailable here. Driggsby will use an owner-only file-backed secret store under ${runtimePaths.configDir}.`,
35
- store: fileStore,
36
- };
37
- }
38
- export async function resolveSecretStoreForLogout(runtimePaths, options = {}) {
39
- try {
40
- return await resolveSecretStore(runtimePaths, options);
41
- }
42
- catch (error) {
43
- if (!(error instanceof ExistingInstallRequiresKeyringError)) {
44
- throw error;
45
- }
46
- return {
47
- backend: "file",
48
- notice: LOGOUT_FALLBACK_NOTICE,
49
- store: options.fileStore ?? new FileSecretStore(runtimePaths),
50
- };
51
- }
52
- }
@@ -1,13 +0,0 @@
1
- export class MemorySecretStore {
2
- secrets = new Map();
3
- setSecret(account, secret) {
4
- this.secrets.set(account, secret);
5
- return Promise.resolve();
6
- }
7
- getSecret(account) {
8
- return Promise.resolve(this.secrets.get(account) ?? null);
9
- }
10
- deleteSecret(account) {
11
- return Promise.resolve(this.secrets.delete(account));
12
- }
13
- }
@@ -1,177 +0,0 @@
1
- import { promises as fs } from "node:fs";
2
- import net from "node:net";
3
- import { ensureRuntimeDirectories } from "../lib/runtime-paths.js";
4
- import { acquireBrokerLock } from "./lock.js";
5
- import { decodeRequest, encodeResponse } from "./ipc.js";
6
- import { hashBrokerPayload, signBrokerProof } from "./authentication.js";
7
- export class LocalBrokerServer {
8
- brokerId;
9
- localAuthToken;
10
- privateJwk;
11
- runtimePaths;
12
- statusProvider;
13
- listToolsProvider;
14
- callToolProvider;
15
- lockLease = null;
16
- server = null;
17
- constructor(options) {
18
- this.brokerId = options.brokerId;
19
- this.localAuthToken = options.localAuthToken;
20
- this.privateJwk = options.privateJwk;
21
- this.runtimePaths = options.runtimePaths;
22
- this.statusProvider = options.statusProvider;
23
- this.listToolsProvider = options.listTools;
24
- this.callToolProvider = options.callTool;
25
- }
26
- async listen() {
27
- if (this.server !== null) {
28
- return;
29
- }
30
- await ensureRuntimeDirectories(this.runtimePaths);
31
- const lockLease = await acquireBrokerLock(this.runtimePaths.lockPath);
32
- if (lockLease === null) {
33
- throw new Error("The local Driggsby broker is already running.");
34
- }
35
- this.lockLease = lockLease;
36
- if (process.platform !== "win32") {
37
- await removeSocketIfPresent(this.runtimePaths.socketPath);
38
- }
39
- this.server = net.createServer((socket) => {
40
- socket.setEncoding("utf8");
41
- let buffer = "";
42
- socket.on("data", (chunk) => {
43
- buffer += chunk;
44
- const newlineIndex = buffer.indexOf("\n");
45
- if (newlineIndex < 0) {
46
- return;
47
- }
48
- const payload = buffer.slice(0, newlineIndex);
49
- void this.handleRequest(payload, socket);
50
- });
51
- });
52
- try {
53
- await new Promise((resolve, reject) => {
54
- this.server?.once("error", reject);
55
- this.server?.listen(this.runtimePaths.socketPath, resolve);
56
- });
57
- }
58
- catch (error) {
59
- await this.releaseLock();
60
- throw error;
61
- }
62
- if (process.platform !== "win32") {
63
- await fs.chmod(this.runtimePaths.socketPath, 0o600);
64
- }
65
- }
66
- async close() {
67
- if (this.server !== null) {
68
- const server = this.server;
69
- this.server = null;
70
- await new Promise((resolve, reject) => {
71
- server.close((error) => {
72
- if (error) {
73
- reject(error);
74
- return;
75
- }
76
- resolve();
77
- });
78
- });
79
- }
80
- if (process.platform !== "win32") {
81
- await removeSocketIfPresent(this.runtimePaths.socketPath);
82
- }
83
- await this.releaseLock();
84
- }
85
- async handleRequest(payload, socket) {
86
- let response;
87
- try {
88
- const request = decodeRequest(payload);
89
- response = await this.dispatchRequest(request);
90
- }
91
- catch (error) {
92
- response = await this.buildErrorResponse("unknown", "unknown", "unknown", error instanceof Error ? error.message : "Broker request failed.");
93
- }
94
- socket.end(encodeResponse(response));
95
- }
96
- async dispatchRequest(request) {
97
- if (request.authToken !== this.localAuthToken) {
98
- return await this.buildErrorResponse(request.id, request.method, request.challenge, "Broker authentication failed.");
99
- }
100
- switch (request.method) {
101
- case "ping": {
102
- const status = await this.statusProvider();
103
- return await this.buildSuccessResponse(request, {
104
- ok: true,
105
- brokerId: status.brokerId ?? "unknown",
106
- });
107
- }
108
- case "get_status":
109
- return await this.buildSuccessResponse(request, {
110
- status: await this.statusProvider(),
111
- });
112
- case "shutdown":
113
- setImmediate(() => {
114
- void this.close();
115
- });
116
- return await this.buildSuccessResponse(request, {
117
- stopped: true,
118
- });
119
- case "list_tools":
120
- return await this.buildSuccessResponse(request, await this.listToolsProvider());
121
- case "call_tool":
122
- return await this.buildSuccessResponse(request, await this.callToolProvider(request.toolName, request.args));
123
- }
124
- }
125
- async buildSuccessResponse(request, result) {
126
- const payload = { ok: true, result };
127
- return {
128
- brokerProof: await signBrokerProof({
129
- aud: "driggsby-local-shim",
130
- challenge: request.challenge,
131
- payloadSha256: hashBrokerPayload(payload),
132
- requestId: request.id,
133
- requestMethod: request.method,
134
- sub: this.brokerId,
135
- }, this.privateJwk),
136
- id: request.id,
137
- ok: true,
138
- result,
139
- };
140
- }
141
- async buildErrorResponse(requestId, requestMethod, challenge, error) {
142
- const payload = { ok: false, error };
143
- return {
144
- brokerProof: await signBrokerProof({
145
- aud: "driggsby-local-shim",
146
- challenge,
147
- payloadSha256: hashBrokerPayload(payload),
148
- requestId,
149
- requestMethod: requestMethod === "unknown" ? "ping" : requestMethod,
150
- sub: this.brokerId,
151
- }, this.privateJwk),
152
- id: requestId,
153
- ok: false,
154
- error,
155
- };
156
- }
157
- async releaseLock() {
158
- if (this.lockLease === null) {
159
- return;
160
- }
161
- const lease = this.lockLease;
162
- this.lockLease = null;
163
- await lease.release();
164
- }
165
- }
166
- async function removeSocketIfPresent(socketPath) {
167
- try {
168
- await fs.rm(socketPath);
169
- }
170
- catch (error) {
171
- if (!(error instanceof Error) ||
172
- !("code" in error) ||
173
- error.code !== "ENOENT") {
174
- throw error;
175
- }
176
- }
177
- }
@@ -1,31 +0,0 @@
1
- const REMOTE_SESSION_ACCOUNT_SUFFIX = "remote-session";
2
- export async function readBrokerRemoteSession(secretStore, brokerId) {
3
- const raw = await secretStore.getSecret(remoteSessionAccountName(brokerId));
4
- if (raw === null) {
5
- return null;
6
- }
7
- const parsed = JSON.parse(raw);
8
- return {
9
- ...parsed,
10
- tokenType: parsed.tokenType ?? "Bearer",
11
- };
12
- }
13
- export async function writeBrokerRemoteSession(secretStore, brokerId, session) {
14
- await secretStore.setSecret(remoteSessionAccountName(brokerId), JSON.stringify(session));
15
- }
16
- export async function clearBrokerRemoteSession(secretStore, brokerId) {
17
- await secretStore.deleteSecret(remoteSessionAccountName(brokerId));
18
- }
19
- export function summarizeBrokerRemoteSession(session) {
20
- return {
21
- accessTokenExpiresAt: session.accessTokenExpiresAt,
22
- authenticatedAt: session.authenticatedAt,
23
- clientId: session.clientId,
24
- issuer: session.issuer,
25
- resource: session.resource,
26
- scope: session.scope,
27
- };
28
- }
29
- function remoteSessionAccountName(brokerId) {
30
- return `${brokerId}:${REMOTE_SESSION_ACCOUNT_SUFFIX}`;
31
- }