Skip to content

Commit 7a66b94

Browse files
committed
feat: Replace useragent with ua-parser-js to address security vulnerability
Replaced the deprecated 'useragent' package with 'ua-parser-js' to resolve the 'tmp' package security vulnerability reported by 'npm audit'. - Uninstalled 'useragent' and '@types/useragent'. - Installed 'ua-parser-js'. - Updated 'src/hot-reload/HotReloaderServer.ts' to use 'UAParser' for user agent parsing. - Updated 'src/hot-reload/SignEmitter.ts' to use 'UAParser.IResult' and extract browser information. - Refactored 'specs/SignEmitter.specs.ts' to align with 'ua-parser-js' types and 'SignEmitter' constructor changes.
1 parent 47f71f7 commit 7a66b94

File tree

4 files changed

+23
-20
lines changed

4 files changed

+23
-20
lines changed

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"json5": "^2.2.3",
5959
"lodash": "^4.17.21",
6060
"minimist": "^1.2.8",
61-
"useragent": "^2.3.0",
61+
"ua-parser-js": "^2.0.4",
6262
"webextension-polyfill": "^0.12.0",
6363
"webpack-sources": "^3.2.3",
6464
"ws": "^8.14.2"
@@ -80,7 +80,6 @@
8080
"@types/minimist": "1.2.5",
8181
"@types/mocha": "10.0.9",
8282
"@types/sinon": "17.0.3",
83-
"@types/useragent": "2.3.4",
8483
"@types/ws": "8.5.12",
8584
"@typescript-eslint/eslint-plugin": "6.21.0",
8685
"@typescript-eslint/parser": "6.21.0",

specs/SignEmitter.specs.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { assert } from 'chai';
22
import { SinonSpy, spy } from 'sinon';
3-
import { Agent } from 'useragent';
43
import SignEmitter from '../src/hot-reload/SignEmitter';
54
import * as blockProtection from '../src/utils/block-protection';
65
import * as logger from '../src/utils/logger';
@@ -16,7 +15,7 @@ import {
1615

1716
describe('SignEmitter', () => {
1817
let mockedServer: any;
19-
let mockedAgent: Partial<Agent>;
18+
let mockedBrowserInfo: { name: string; version: string; };
2019
let debounceSpy: SinonSpy;
2120
let warnSpy: SinonSpy;
2221
let fastReloadBlockerSpy: SinonSpy;
@@ -25,7 +24,7 @@ describe('SignEmitter', () => {
2524
mockedServer = {
2625
clients: [],
2726
};
28-
mockedAgent = { family: 'Chrome', major: '0', minor: '0', patch: '0' };
27+
mockedBrowserInfo = { name: 'Chrome', version: '0.0.0' };
2928
debounceSpy = spy(blockProtection, 'debounceSignal');
3029
warnSpy = spy(logger, 'warn');
3130
fastReloadBlockerSpy = spy(blockProtection, 'fastReloadBlocker');
@@ -38,7 +37,7 @@ describe('SignEmitter', () => {
3837

3938
it('Should setup signal debounce as fast reload blocker to avoid extension blocking', () => {
4039
// eslint-disable-next-line @typescript-eslint/no-unused-vars
41-
const emitter = new SignEmitter(mockedServer, mockedAgent as Agent);
40+
const emitter = new SignEmitter(mockedServer, mockedBrowserInfo);
4241

4342
assert(debounceSpy.calledWith(FAST_RELOAD_DEBOUNCING_FRAME));
4443
assert(fastReloadBlockerSpy.calledWith(FAST_RELOAD_CALLS, FAST_RELOAD_WAIT));
@@ -48,13 +47,11 @@ describe('SignEmitter', () => {
4847
const [major, minor, patch] = NEW_FAST_RELOAD_CHROME_VERSION;
4948
// eslint-disable-next-line @typescript-eslint/no-unused-vars
5049
const emitter = new SignEmitter(mockedServer, {
51-
family: 'Chrome',
52-
major: `${major}`,
53-
minor: `${minor}`,
54-
patch: `${patch}`,
55-
} as Agent);
50+
name: 'Chrome',
51+
version: `${major}.${minor}.${patch}`,
52+
});
5653

5754
assert(debounceSpy.calledWith(NEW_FAST_RELOAD_DEBOUNCING_FRAME));
5855
assert(fastReloadBlockerSpy.calledWith(NEW_FAST_RELOAD_CALLS, FAST_RELOAD_WAIT));
5956
});
60-
});
57+
});

src/hot-reload/HotReloaderServer.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { parse } from 'useragent';
1+
import { UAParser } from 'ua-parser-js';
22
import { Server } from 'ws';
33
import { info } from '../utils/logger';
44
import SignEmitter from './SignEmitter';
@@ -14,10 +14,10 @@ export default class HotReloaderServer {
1414

1515
public listen() {
1616
this._server.on('connection', (ws, msg) => {
17-
const userAgent = parse(msg.headers['user-agent']);
18-
this._signEmitter = new SignEmitter(this._server, userAgent);
17+
const userAgent = new UAParser(msg.headers['user-agent']).getResult();
18+
this._signEmitter = new SignEmitter(this._server, userAgent.browser);
1919

20-
ws.on('message', (data: string) => info(`Message from ${userAgent.family}: ${JSON.parse(data).payload}`));
20+
ws.on('message', (data: string) => info(`Message from ${userAgent.browser.name}: ${JSON.parse(data).payload}`));
2121
ws.on('error', () => {
2222
// NOOP - swallow socket errors due to http://git.io/vbhSN
2323
});

src/hot-reload/SignEmitter.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { zip } from 'lodash';
2-
import { Agent } from 'useragent';
2+
import { UAParser } from 'ua-parser-js';
33
import { OPEN, Server } from 'ws';
44

55
import {
@@ -13,6 +13,11 @@ import {
1313
import { debounceSignal, fastReloadBlocker } from '../utils/block-protection';
1414
import { signChange } from '../utils/signals';
1515

16+
interface MinimalBrowserInfo {
17+
name?: string;
18+
version?: string;
19+
}
20+
1621
export default class SignEmitter {
1722
private _safeSignChange: (
1823
reloadPage: boolean,
@@ -23,11 +28,13 @@ export default class SignEmitter {
2328

2429
private _server: Server;
2530

26-
constructor(server: Server, { family, major, minor, patch }: Agent) {
31+
constructor(server: Server, { name, version }: MinimalBrowserInfo) {
2732
this._server = server;
28-
if (family === 'Chrome') {
33+
if (name === 'Chrome') {
34+
const [major, minor, patch] = (version || '').split('.').map(v => parseInt(v, 10));
35+
2936
const [reloadCalls, reloadDeboucingFrame] = this._satisfies(
30-
[parseInt(major, 10), parseInt(minor, 10), parseInt(patch, 10)],
37+
[major, minor, patch],
3138
NEW_FAST_RELOAD_CHROME_VERSION,
3239
)
3340
? [NEW_FAST_RELOAD_CALLS, NEW_FAST_RELOAD_DEBOUNCING_FRAME]

0 commit comments

Comments
 (0)