@hahnfeld/msrelay-provider 0.1.4 → 0.1.6
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 +52 -73
- 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.6",
|
|
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 ?? `${nsName}-hybrid`,
|
|
149
137
|
validate: (v) => {
|
|
150
138
|
const trimmed = v.trim();
|
|
151
139
|
if (!trimmed)
|
|
@@ -156,20 +144,9 @@ 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:",
|
|
172
|
-
defaultValue: existing.sasKeyName ??
|
|
148
|
+
message: "SAS policy name (listen-only auth rule):",
|
|
149
|
+
defaultValue: existing.sasKeyName ?? `${nsName}-hybrid-policy`,
|
|
173
150
|
validate: (v) => {
|
|
174
151
|
if (!v.trim())
|
|
175
152
|
return "Policy name is required";
|
|
@@ -177,17 +154,26 @@ 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 --resource-group ${rg} --name ${nsName} --location westus2`);
|
|
164
|
+
terminal.log.info("");
|
|
165
|
+
terminal.log.info(`az relay hyco create --resource-group ${rg} --namespace-name ${nsName} --name ${hc} --requires-client-authorization false`);
|
|
166
|
+
terminal.log.info("");
|
|
167
|
+
terminal.log.info(`az relay hyco authorization-rule create --resource-group ${rg} --namespace-name ${nsName} --hybrid-connection-name ${hc} --name ${sasName} --rights Listen`);
|
|
168
|
+
terminal.log.info("");
|
|
169
|
+
terminal.log.warning("--requires-client-authorization cannot be changed after creation.");
|
|
170
|
+
terminal.log.warning("If you need to change it, delete and recreate the connection.");
|
|
171
|
+
terminal.log.info("");
|
|
172
|
+
// ── Step 3: SAS Key ──
|
|
173
|
+
terminal.log.step("Retrieve the SAS key:");
|
|
174
|
+
terminal.log.info("");
|
|
175
|
+
terminal.log.info(`az relay hyco authorization-rule keys list --resource-group ${rg} --namespace-name ${nsName} --hybrid-connection-name ${hc} --name ${sasName} --query primaryKey -o tsv`);
|
|
176
|
+
terminal.log.info("");
|
|
191
177
|
const hasExistingKey = !!(existing.sasKeyValue);
|
|
192
178
|
let keyValue = await terminal.password({
|
|
193
179
|
message: hasExistingKey
|
|
@@ -202,18 +188,11 @@ export function createRelayPlugin() {
|
|
|
202
188
|
if (!(keyValue ?? "").trim() && hasExistingKey) {
|
|
203
189
|
keyValue = existing.sasKeyValue;
|
|
204
190
|
}
|
|
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");
|
|
191
|
+
// ── Step 4: Port ──
|
|
213
192
|
const existingPort = existing.port;
|
|
214
193
|
const envPort = process.env.PORT ? Number(process.env.PORT) : null;
|
|
215
194
|
const portChoice = await terminal.select({
|
|
216
|
-
message: "Which port should the tunnel
|
|
195
|
+
message: "Which local port should the tunnel forward to?",
|
|
217
196
|
options: [
|
|
218
197
|
...(existingPort && existingPort !== 3978 && existingPort !== 21420
|
|
219
198
|
? [{ value: String(existingPort), label: `${existingPort} (current config)`, hint: "Previously configured" }]
|
|
@@ -246,7 +225,7 @@ export function createRelayPlugin() {
|
|
|
246
225
|
else {
|
|
247
226
|
port = Number(portChoice);
|
|
248
227
|
}
|
|
249
|
-
// ── Step
|
|
228
|
+
// ── Step 5: Connectivity Test ──
|
|
250
229
|
const wantTest = await terminal.confirm({
|
|
251
230
|
message: "Test connectivity now? (connects to Azure Relay for up to 10s)",
|
|
252
231
|
initialValue: true,
|
|
@@ -263,10 +242,11 @@ export function createRelayPlugin() {
|
|
|
263
242
|
terminal.log.warning("Installation will continue — you can test connectivity later with /relay auth");
|
|
264
243
|
}
|
|
265
244
|
}
|
|
266
|
-
// ── Step
|
|
245
|
+
// ── Step 6: Save ──
|
|
267
246
|
await settings.setAll({
|
|
268
247
|
enabled: true,
|
|
269
248
|
port,
|
|
249
|
+
resourceGroup: rg,
|
|
270
250
|
relayNamespace: ns,
|
|
271
251
|
hybridConnectionName: hc,
|
|
272
252
|
sasKeyName: sasName,
|
|
@@ -278,10 +258,9 @@ export function createRelayPlugin() {
|
|
|
278
258
|
`Connection: ${hc}\n` +
|
|
279
259
|
`SAS policy: ${sasName}\n` +
|
|
280
260
|
`Port: ${port}\n` +
|
|
281
|
-
`Public URL: https://${ns}/${hc}\n` +
|
|
282
261
|
"\n" +
|
|
283
|
-
"
|
|
284
|
-
|
|
262
|
+
"Set your Bot Framework messaging endpoint to:\n" +
|
|
263
|
+
` https://${ns}/${hc}/api/messages`, "Configuration Summary");
|
|
285
264
|
},
|
|
286
265
|
// ─── Configure (post-install changes) ────────────────────────────────
|
|
287
266
|
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"). */
|