Skip to content

Commit 5abcce8

Browse files
vicancyCopilot
andauthored
Fix Dependabot security alerts across JavaScript samples (#365)
Resolve all open Dependabot vulnerability alerts across four JavaScript sample projects (npm audit now reports 0 vulnerabilities in each): - EventGridIntegration/javascript: migrate from the deprecated azure-storage package (which depends on the unpatchable `request` SSRF, GHSA-p8p7-x288-28g6) to @azure/data-tables. Rewrites the OnConnection table logic; behavior and the optimistic-concurrency retry loop are preserved. - QuickStartServerless/javascript/v4-programming-model: drop the azurite devDependency (a local-only emulator that pulls a large, perpetually vulnerable transitive tree) and run it on demand via npx; bump azure-functions-core-tools to ^4.12.0. - ServerlessChatWithAuth/v4-model: bump azure-functions-core-tools to ^4.12.0 (older builds shipped vulnerable minimatch/debug/brace-expansion). - Whiteboard/MCPServer: refresh lockfile (npm audit fix), bumping @modelcontextprotocol/sdk, hono, fast-uri, qs and ws to patched versions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 562e24e commit 5abcce8

9 files changed

Lines changed: 854 additions & 4877 deletions

File tree

samples/EventGridIntegration/javascript/OnConnection/index.js

Lines changed: 26 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,26 @@
1-
const azure = require('azure-storage');
1+
const { TableClient } = require('@azure/data-tables');
22

3-
const tableService = azure.createTableService();
43
const tableName = 'connection';
4+
const tableClient = TableClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING, tableName);
55

6-
tableService.createTableIfNotExists(tableName, function(error, result, response){
7-
if(result.created){
8-
context.log(`Table ${tableName} created`);
6+
// Create the table once per process. createTable does not throw if it already exists.
7+
let ensureTablePromise;
8+
const ensureTable = () => {
9+
if (!ensureTablePromise) {
10+
ensureTablePromise = tableClient.createTable().catch((error) => {
11+
ensureTablePromise = undefined;
12+
throw error;
13+
});
914
}
10-
});
15+
return ensureTablePromise;
16+
};
1117

1218
module.exports = async function (context, eventGridEvent) {
1319
context.log(typeof eventGridEvent);
1420
context.log(eventGridEvent);
1521

22+
await ensureTable();
23+
1624
// Use resource name and hub as partition key and row key separately
1725
let partitionKey = getLastPart(eventGridEvent.topic);
1826
let rowKey = eventGridEvent.data.hubName;
@@ -24,27 +32,28 @@ module.exports = async function (context, eventGridEvent) {
2432
try {
2533
let entity;
2634
try {
27-
entity = await getEntry(partitionKey, rowKey);
35+
entity = await tableClient.getEntity(partitionKey, rowKey);
2836
operation = 'replace';
2937
} catch (error) {
3038
context.log(error);
3139
operation = 'insert';
3240
}
3341

3442
if (operation === 'replace') {
35-
newConnectionCount = parseInt(entity.Count._) + (eventGridEvent.eventType == 'Microsoft.SignalRService.ClientConnectionConnected' ? 1 : -1);
36-
entity.Count._ = newConnectionCount;
37-
await replaceEntity(entity);
43+
newConnectionCount = parseInt(entity.Count, 10) + (eventGridEvent.eventType == 'Microsoft.SignalRService.ClientConnectionConnected' ? 1 : -1);
44+
await tableClient.updateEntity({
45+
partitionKey: partitionKey,
46+
rowKey: rowKey,
47+
Count: newConnectionCount,
48+
}, 'Replace', { etag: entity.etag });
3849
token = false;
3950
} else if (operation === 'insert') {
4051
newConnectionCount = eventGridEvent.eventType == 'Microsoft.SignalRService.ClientConnectionConnected' ? 1 : 0;
41-
let entryGen = azure.TableUtilities.entityGenerator;
42-
entity = {
43-
PartitionKey: entryGen.String(partitionKey),
44-
RowKey: entryGen.String(rowKey),
45-
Count: entryGen.Int32(newConnectionCount),
46-
};
47-
await insertEntity(entity);
52+
await tableClient.createEntity({
53+
partitionKey: partitionKey,
54+
rowKey: rowKey,
55+
Count: newConnectionCount,
56+
});
4857
token = false;
4958
}
5059
} catch (error) {
@@ -69,36 +78,6 @@ module.exports = async function (context, eventGridEvent) {
6978
}];
7079
};
7180

72-
const getEntry = (partitionKey, rowKey) => new Promise((resolve, reject) => {
73-
tableService.retrieveEntity(tableName, partitionKey, rowKey, (error, result, response) => {
74-
if (error) {
75-
reject(error);
76-
} else {
77-
resolve(result);
78-
}
79-
});
80-
});
81-
82-
const replaceEntity = (entry) => new Promise((resolve, reject) => {
83-
tableService.replaceEntity(tableName, entry, (error, result, response) => {
84-
if (error) {
85-
reject(error);
86-
} else {
87-
resolve(result);
88-
}
89-
});
90-
});
91-
92-
const insertEntity = (entry) => new Promise((resolve, reject) => {
93-
tableService.insertEntity(tableName, entry, (error, result, response) => {
94-
if (error) {
95-
reject(error);
96-
} else {
97-
resolve(result);
98-
}
99-
});
100-
});
101-
10281
const getLastPart = (data) => {
10382
let n = data.lastIndexOf('/');
10483
if (n == -1) {

0 commit comments

Comments
 (0)