@hahnfeld/msrelay-provider 0.1.4 → 0.1.5
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/plugin.js +60 -72
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
package/dist/plugin.js
CHANGED
|
@@ -85,7 +85,7 @@ export function createRelayPlugin() {
|
|
|
85
85
|
let provider = null;
|
|
86
86
|
return {
|
|
87
87
|
name: "@hahnfeld/msrelay-provider",
|
|
88
|
-
version: "0.1.
|
|
88
|
+
version: "0.1.5",
|
|
89
89
|
description: "Azure Relay Hybrid Connections tunnel provider — private HTTP tunneling via Azure backbone",
|
|
90
90
|
essential: false,
|
|
91
91
|
permissions: [
|
|
@@ -100,52 +100,40 @@ export function createRelayPlugin() {
|
|
|
100
100
|
const { terminal, settings } = ctx;
|
|
101
101
|
// Load existing config for pre-filling on reinstall
|
|
102
102
|
const existing = await settings.getAll();
|
|
103
|
-
terminal.note("
|
|
104
|
-
"
|
|
105
|
-
"
|
|
103
|
+
terminal.note("Azure Relay Hybrid Connections exposes a local port via a stable\n" +
|
|
104
|
+
"HTTPS endpoint on Azure's private backbone — no public internet\n" +
|
|
105
|
+
"exposure, no inbound ports required.\n" +
|
|
106
106
|
"\n" +
|
|
107
|
-
"
|
|
108
|
-
"to run.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
107
|
+
"This wizard collects a few names, then gives you the exact Azure\n" +
|
|
108
|
+
"CLI commands to run. You'll need the az CLI installed.", "Azure Relay Setup");
|
|
109
|
+
// ── Step 1: Collect names ──
|
|
110
|
+
const resourceGroup = await terminal.text({
|
|
111
|
+
message: "Azure resource group:",
|
|
112
|
+
defaultValue: existing.resourceGroup ?? undefined,
|
|
113
|
+
validate: (v) => {
|
|
114
|
+
if (!v.trim())
|
|
115
|
+
return "Resource group is required";
|
|
116
|
+
return undefined;
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
const rg = resourceGroup.trim();
|
|
119
120
|
const namespaceInput = await terminal.text({
|
|
120
|
-
message: "
|
|
121
|
-
defaultValue: existing.relayNamespace ?? undefined,
|
|
121
|
+
message: "Relay namespace name (becomes <name>.servicebus.windows.net):",
|
|
122
|
+
defaultValue: existing.relayNamespace?.replace(".servicebus.windows.net", "") ?? undefined,
|
|
122
123
|
validate: (v) => {
|
|
123
124
|
if (!v.trim())
|
|
124
125
|
return "Namespace is required";
|
|
125
126
|
return undefined;
|
|
126
127
|
},
|
|
127
128
|
});
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
: `${namespaceInput.trim()}.servicebus.windows.net`;
|
|
129
|
+
const nsName = namespaceInput.trim().replace(".servicebus.windows.net", "");
|
|
130
|
+
const ns = `${nsName}.servicebus.windows.net`;
|
|
131
131
|
if (!isValidNamespace(ns)) {
|
|
132
132
|
terminal.log.warning(`"${ns}" doesn't look like a valid namespace — continuing anyway`);
|
|
133
133
|
}
|
|
134
|
-
const nsName = ns.replace(".servicebus.windows.net", "");
|
|
135
|
-
// ── Step 2: Hybrid Connection ──
|
|
136
|
-
terminal.note("Create a Hybrid Connection with client authorization disabled:\n" +
|
|
137
|
-
"\n" +
|
|
138
|
-
` az relay hyco create \\\n` +
|
|
139
|
-
` --resource-group <resource-group> \\\n` +
|
|
140
|
-
` --namespace-name ${nsName} \\\n` +
|
|
141
|
-
` --name <choose-a-name> \\\n` +
|
|
142
|
-
` --requires-client-authorization false\n` +
|
|
143
|
-
"\n" +
|
|
144
|
-
"IMPORTANT: --requires-client-authorization cannot be changed after\n" +
|
|
145
|
-
"creation. If you need to change it, delete and recreate the connection.", "Step 2: Create Hybrid Connection");
|
|
146
134
|
const connectionName = await terminal.text({
|
|
147
|
-
message: "Hybrid Connection name
|
|
148
|
-
defaultValue: existing.hybridConnectionName ??
|
|
135
|
+
message: "Hybrid Connection name:",
|
|
136
|
+
defaultValue: existing.hybridConnectionName ?? "bot-endpoint",
|
|
149
137
|
validate: (v) => {
|
|
150
138
|
const trimmed = v.trim();
|
|
151
139
|
if (!trimmed)
|
|
@@ -156,19 +144,8 @@ export function createRelayPlugin() {
|
|
|
156
144
|
},
|
|
157
145
|
});
|
|
158
146
|
const hc = connectionName.trim();
|
|
159
|
-
// ── Step 3: SAS Policy ──
|
|
160
|
-
terminal.note("Create a listen-only SAS authorization rule:\n" +
|
|
161
|
-
"\n" +
|
|
162
|
-
` az relay hyco authorization-rule create \\\n` +
|
|
163
|
-
` --resource-group <resource-group> \\\n` +
|
|
164
|
-
` --namespace-name ${nsName} \\\n` +
|
|
165
|
-
` --hybrid-connection-name ${hc} \\\n` +
|
|
166
|
-
` --name ListenOnly --rights Listen\n` +
|
|
167
|
-
"\n" +
|
|
168
|
-
"Use a listen-only policy — this plugin only needs Listen permission.\n" +
|
|
169
|
-
"Do not use RootManageSharedAccessKey.", "Step 3: Create SAS Policy");
|
|
170
147
|
const keyName = await terminal.text({
|
|
171
|
-
message: "SAS policy name:",
|
|
148
|
+
message: "SAS policy name (listen-only auth rule):",
|
|
172
149
|
defaultValue: existing.sasKeyName ?? "ListenOnly",
|
|
173
150
|
validate: (v) => {
|
|
174
151
|
if (!v.trim())
|
|
@@ -177,17 +154,35 @@ export function createRelayPlugin() {
|
|
|
177
154
|
},
|
|
178
155
|
});
|
|
179
156
|
const sasName = keyName.trim();
|
|
180
|
-
// ── Step
|
|
181
|
-
terminal.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
157
|
+
// ── Step 2: Show the public URL and exact az commands ──
|
|
158
|
+
terminal.log.step("Your public endpoint will be:");
|
|
159
|
+
terminal.log.info(` https://${ns}/${hc}/api/messages`);
|
|
160
|
+
terminal.log.info("");
|
|
161
|
+
terminal.log.step("Run these commands to create the Azure resources:");
|
|
162
|
+
terminal.log.info("");
|
|
163
|
+
terminal.log.info(`az relay namespace create \\`);
|
|
164
|
+
terminal.log.info(` --resource-group ${rg} --name ${nsName} --location westus2`);
|
|
165
|
+
terminal.log.info("");
|
|
166
|
+
terminal.log.info(`az relay hyco create \\`);
|
|
167
|
+
terminal.log.info(` --resource-group ${rg} --namespace-name ${nsName} \\`);
|
|
168
|
+
terminal.log.info(` --name ${hc} --requires-client-authorization false`);
|
|
169
|
+
terminal.log.info("");
|
|
170
|
+
terminal.log.info(`az relay hyco authorization-rule create \\`);
|
|
171
|
+
terminal.log.info(` --resource-group ${rg} --namespace-name ${nsName} \\`);
|
|
172
|
+
terminal.log.info(` --hybrid-connection-name ${hc} \\`);
|
|
173
|
+
terminal.log.info(` --name ${sasName} --rights Listen`);
|
|
174
|
+
terminal.log.info("");
|
|
175
|
+
terminal.log.warning("--requires-client-authorization cannot be changed after creation.");
|
|
176
|
+
terminal.log.warning("If you need to change it, delete and recreate the connection.");
|
|
177
|
+
terminal.log.info("");
|
|
178
|
+
// ── Step 3: SAS Key ──
|
|
179
|
+
terminal.log.step("Retrieve the SAS key:");
|
|
180
|
+
terminal.log.info("");
|
|
181
|
+
terminal.log.info(`az relay hyco authorization-rule keys list \\`);
|
|
182
|
+
terminal.log.info(` --resource-group ${rg} --namespace-name ${nsName} \\`);
|
|
183
|
+
terminal.log.info(` --hybrid-connection-name ${hc} --name ${sasName} \\`);
|
|
184
|
+
terminal.log.info(` --query primaryKey -o tsv`);
|
|
185
|
+
terminal.log.info("");
|
|
191
186
|
const hasExistingKey = !!(existing.sasKeyValue);
|
|
192
187
|
let keyValue = await terminal.password({
|
|
193
188
|
message: hasExistingKey
|
|
@@ -202,18 +197,11 @@ export function createRelayPlugin() {
|
|
|
202
197
|
if (!(keyValue ?? "").trim() && hasExistingKey) {
|
|
203
198
|
keyValue = existing.sasKeyValue;
|
|
204
199
|
}
|
|
205
|
-
// ── Step
|
|
206
|
-
terminal.note("This tunnel can point to any local port. Common choices:\n" +
|
|
207
|
-
"\n" +
|
|
208
|
-
" 3978 — Teams adapter (Microsoft Bot Framework default)\n" +
|
|
209
|
-
" 21420 — OpenACP API server\n" +
|
|
210
|
-
"\n" +
|
|
211
|
-
"You can change this later with:\n" +
|
|
212
|
-
" openacp plugin configure @hahnfeld/msrelay-provider", "Step 5: Port Selection");
|
|
200
|
+
// ── Step 4: Port ──
|
|
213
201
|
const existingPort = existing.port;
|
|
214
202
|
const envPort = process.env.PORT ? Number(process.env.PORT) : null;
|
|
215
203
|
const portChoice = await terminal.select({
|
|
216
|
-
message: "Which port should the tunnel
|
|
204
|
+
message: "Which local port should the tunnel forward to?",
|
|
217
205
|
options: [
|
|
218
206
|
...(existingPort && existingPort !== 3978 && existingPort !== 21420
|
|
219
207
|
? [{ value: String(existingPort), label: `${existingPort} (current config)`, hint: "Previously configured" }]
|
|
@@ -246,7 +234,7 @@ export function createRelayPlugin() {
|
|
|
246
234
|
else {
|
|
247
235
|
port = Number(portChoice);
|
|
248
236
|
}
|
|
249
|
-
// ── Step
|
|
237
|
+
// ── Step 5: Connectivity Test ──
|
|
250
238
|
const wantTest = await terminal.confirm({
|
|
251
239
|
message: "Test connectivity now? (connects to Azure Relay for up to 10s)",
|
|
252
240
|
initialValue: true,
|
|
@@ -263,10 +251,11 @@ export function createRelayPlugin() {
|
|
|
263
251
|
terminal.log.warning("Installation will continue — you can test connectivity later with /relay auth");
|
|
264
252
|
}
|
|
265
253
|
}
|
|
266
|
-
// ── Step
|
|
254
|
+
// ── Step 6: Save ──
|
|
267
255
|
await settings.setAll({
|
|
268
256
|
enabled: true,
|
|
269
257
|
port,
|
|
258
|
+
resourceGroup: rg,
|
|
270
259
|
relayNamespace: ns,
|
|
271
260
|
hybridConnectionName: hc,
|
|
272
261
|
sasKeyName: sasName,
|
|
@@ -278,10 +267,9 @@ export function createRelayPlugin() {
|
|
|
278
267
|
`Connection: ${hc}\n` +
|
|
279
268
|
`SAS policy: ${sasName}\n` +
|
|
280
269
|
`Port: ${port}\n` +
|
|
281
|
-
`Public URL: https://${ns}/${hc}\n` +
|
|
282
270
|
"\n" +
|
|
283
|
-
"
|
|
284
|
-
|
|
271
|
+
"Set your Bot Framework messaging endpoint to:\n" +
|
|
272
|
+
` https://${ns}/${hc}/api/messages`, "Configuration Summary");
|
|
285
273
|
},
|
|
286
274
|
// ─── Configure (post-install changes) ────────────────────────────────
|
|
287
275
|
async configure(ctx) {
|
package/dist/types.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export interface AzureRelayConfig {
|
|
|
4
4
|
enabled: boolean;
|
|
5
5
|
/** Local port to forward requests to. Default: PORT env var or 3978. */
|
|
6
6
|
port: number | null;
|
|
7
|
+
/** Azure resource group (saved for wizard pre-fill, not used at runtime). */
|
|
8
|
+
resourceGroup?: string;
|
|
7
9
|
/** Azure Relay namespace (e.g., "myrelay.servicebus.windows.net"). */
|
|
8
10
|
relayNamespace: string;
|
|
9
11
|
/** Hybrid Connection name (e.g., "bot-endpoint"). */
|