Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow username and password in clientURL #3452

Merged
merged 8 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 30 additions & 0 deletions bin/cli-flags.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,36 @@ module.exports = {
multiple: false,
simpleType: 'string',
},
'client-web-socket-url-username': {
configs: [
{
type: 'string',
multiple: false,
description:
'Tells clients connected to devServer to use the provided username to authenticate.',
path: 'client.webSocketURL.username',
},
],
description:
'Tells clients connected to devServer to use the provided username to authenticate.',
simpleType: 'string',
multiple: false,
},
'client-web-socket-url-password': {
configs: [
{
type: 'string',
multiple: false,
description:
'Tells clients connected to devServer to use the provided password to authenticate.',
path: 'client.webSocketURL.password',
},
],
description:
'Tells clients connected to devServer to use the provided password to authenticate.',
simpleType: 'string',
multiple: false,
},
'web-socket-server': {
configs: [
{
Expand Down
8 changes: 8 additions & 0 deletions lib/options.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@
"description": "Tells clients connected to devServer to use the provided path to connect.",
"type": "string"
},
"password": {
"description": "Tells clients connected to devServer to use the provided password to authenticate.",
"type": "string"
},
"port": {
"description": "Tells clients connected to devServer to use the provided port.",
"anyOf": [
Expand All @@ -177,6 +181,10 @@
"minLength": 1
}
]
},
"username": {
"description": "Tells clients connected to devServer to use the provided username to authenticate.",
"type": "string"
}
}
}
Expand Down
34 changes: 23 additions & 11 deletions lib/utils/DevServerPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class DevServerPlugin {
if (typeof options.client.webSocketURL.path !== 'undefined') {
path = options.client.webSocketURL.path;
}

// Web socket server works on custom `path`
else if (
typeof options.webSocketServer.options.prefix !== 'undefined' ||
Expand All @@ -103,24 +104,35 @@ class DevServerPlugin {
options.webSocketServer.options.path;
}

/** @type {Record<string, any>} */
const searchParams = {};
/** @type {string} */
let username = '';

if (typeof options.client.webSocketURL.username !== 'undefined') {
username = options.client.webSocketURL.username;
}

/** @type {string} */
let password = '';

if (typeof options.client.webSocketURL.password !== 'undefined') {
password = options.client.webSocketURL.password;
}

const searchParams = new URLSearchParams();

if (typeof options.client.logging !== 'undefined') {
searchParams.logging = options.client.logging;
searchParams.set('logging', options.client.logging);
}

const searchParamsString = searchParams.toString();

return encodeURIComponent(
new URL(
`${protocol}//${ipaddr.IPv6.isIPv6(host) ? `[${host}]` : host}${
`${protocol}//${username}${password ? `:${password}` : ''}${
username || password ? `@` : ''
}${ipaddr.IPv6.isIPv6(host) ? `[${host}]` : host}${
port ? `:${port}` : ''
}${path || '/'}${
Object.keys(searchParams).length > 0
? `?${Object.entries(searchParams)
.map(([key, value]) => `${key}=${value}`)
.join('&')}`
: ''
}`
}${path || '/'}${searchParamsString ? `?${searchParamsString}` : ''}`
).toString()
).replace(
/[!'()*]/g,
Expand Down
2 changes: 2 additions & 0 deletions lib/utils/normalizeOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ function normalizeOptions(compiler, options, logger) {
host: parsedURL.hostname,
port: parsedURL.port.length > 0 ? Number(parsedURL.port) : '',
path: parsedURL.pathname,
username: parsedURL.username,
password: parsedURL.password,
};
} else if (typeof options.client.webSocketURL.port === 'string') {
options.client.webSocketURL.port = Number(options.client.webSocketURL.port);
Expand Down
14 changes: 13 additions & 1 deletion test/__snapshots__/validate-options.test.js.snap.webpack4
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ exports[`options validate should throw an error on the "client" option with '{"w
exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client.webSocketURL should be one of these:
non-empty string | object { host?, path?, port?, protocol? }
non-empty string | object { host?, path?, password?, port?, protocol?, username? }
-> Allows to specify URL to web socket server (useful when you're proxying dev server and client script does not always know where to connect to).
Details:
* options.client.webSocketURL.port should be one of these:
Expand All @@ -183,6 +183,18 @@ exports[`options validate should throw an error on the "client" option with '{"w
* options.client.webSocketURL.port should be a non-empty string."
`;

exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"username":123,"password":976}}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client.webSocketURL should be one of these:
non-empty string | object { host?, path?, password?, port?, protocol?, username? }
-> Allows to specify URL to web socket server (useful when you're proxying dev server and client script does not always know where to connect to).
Details:
* options.client.webSocketURL.password should be a string.
-> Tells clients connected to devServer to use the provided password to authenticate.
* options.client.webSocketURL.username should be a string.
-> Tells clients connected to devServer to use the provided username to authenticate."
`;

exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be an object:
Expand Down
14 changes: 13 additions & 1 deletion test/__snapshots__/validate-options.test.js.snap.webpack5
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ exports[`options validate should throw an error on the "client" option with '{"w
exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"port":true}}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client.webSocketURL should be one of these:
non-empty string | object { host?, path?, port?, protocol? }
non-empty string | object { host?, path?, password?, port?, protocol?, username? }
-> Allows to specify URL to web socket server (useful when you're proxying dev server and client script does not always know where to connect to).
Details:
* options.client.webSocketURL.port should be one of these:
Expand All @@ -183,6 +183,18 @@ exports[`options validate should throw an error on the "client" option with '{"w
* options.client.webSocketURL.port should be a non-empty string."
`;

exports[`options validate should throw an error on the "client" option with '{"webSocketURL":{"username":123,"password":976}}' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client.webSocketURL should be one of these:
non-empty string | object { host?, path?, password?, port?, protocol?, username? }
-> Allows to specify URL to web socket server (useful when you're proxying dev server and client script does not always know where to connect to).
Details:
* options.client.webSocketURL.password should be a string.
-> Tells clients connected to devServer to use the provided password to authenticate.
* options.client.webSocketURL.username should be a string.
-> Tells clients connected to devServer to use the provided username to authenticate."
`;

exports[`options validate should throw an error on the "client" option with 'whoops!' value 1`] = `
"ValidationError: Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.
- options.client should be an object:
Expand Down
2 changes: 2 additions & 0 deletions test/cli/__snapshots__/cli.test.js.snap.webpack4
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ Options:
--client-web-socket-url-port <value> Tells clients connected to devServer to use the provided port.
--client-web-socket-url-path <value> Tells clients connected to devServer to use the provided path to connect.
--client-web-socket-url-protocol <value> Tells clients connected to devServer to use the provided protocol.
--client-web-socket-url-username <value> Tells clients connected to devServer to use the provided username to authenticate.
--client-web-socket-url-password <value> Tells clients connected to devServer to use the provided password to authenticate.
--web-socket-server <value> Allows to set web socket server and options (by default 'ws'). https://webpack.js.org/configuration/dev-server/#devserverwebsocketserver
--compress Enables gzip compression for everything served. https://webpack.js.org/configuration/dev-server/#devservercompress
--no-compress Disables gzip compression for everything served.
Expand Down
2 changes: 2 additions & 0 deletions test/cli/__snapshots__/cli.test.js.snap.webpack5
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,10 @@ Options:
--client-web-socket-url <value> Allows to specify URL to web socket server (useful when you're proxying dev server and client script does not always know where to connect to).
--client-web-socket-url-host <value> Tells clients connected to devServer to use the provided host.
--client-web-socket-url-path <value> Tells clients connected to devServer to use the provided path to connect.
--client-web-socket-url-password <value> Tells clients connected to devServer to use the provided password to authenticate.
--client-web-socket-url-port <value> Tells clients connected to devServer to use the provided port.
--client-web-socket-url-protocol <value> Tells clients connected to devServer to use the provided protocol.
--client-web-socket-url-username <value> Tells clients connected to devServer to use the provided username to authenticate.
--compress Enables gzip compression for everything served. https://webpack.js.org/configuration/dev-server/#devservercompress
--no-compress Negative 'compress' option.
--history-api-fallback Allows to proxy requests through a specified index page (by default 'index.html'), useful for Single Page Applications that utilise the HTML5 History API. https://webpack.js.org/configuration/dev-server/#devserverhistoryapifallback
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,28 @@ Array [

exports[`web socket server URL should work with the "client.webSocketURL.host" option using "0.0.0.0" value ("ws"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.password" option ("sockjs"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.password" option ("sockjs"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.password" option ("ws"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.password" option ("ws"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.path" option ("sockjs"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
Expand Down Expand Up @@ -436,3 +458,47 @@ Array [
`;

exports[`web socket server URL should work with the "client.webSocketURL.protocol" option using "http:" value and covert to "ws:" ("ws"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.username" and "client.webSocketURL.password" option ("sockjs"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.username" and "client.webSocketURL.password" option ("sockjs"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.username" and "client.webSocketURL.password" option ("ws"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.username" and "client.webSocketURL.password" option ("ws"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.username" option ("sockjs"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.username" option ("sockjs"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.username" option ("ws"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.username" option ("ws"): page errors 1`] = `Array []`;
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,28 @@ Array [

exports[`web socket server URL should work with the "client.webSocketURL.host" option using "0.0.0.0" value ("ws"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.password" option ("sockjs"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.password" option ("sockjs"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.password" option ("ws"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.password" option ("ws"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.path" option ("sockjs"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
Expand Down Expand Up @@ -436,3 +458,47 @@ Array [
`;

exports[`web socket server URL should work with the "client.webSocketURL.protocol" option using "http:" value and covert to "ws:" ("ws"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.username" and "client.webSocketURL.password" option ("sockjs"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.username" and "client.webSocketURL.password" option ("sockjs"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.username" and "client.webSocketURL.password" option ("ws"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.username" and "client.webSocketURL.password" option ("ws"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.username" option ("sockjs"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.username" option ("sockjs"): page errors 1`] = `Array []`;

exports[`web socket server URL should work with the "client.webSocketURL.username" option ("ws"): console messages 1`] = `
Array [
"[HMR] Waiting for update signal from WDS...",
"Hey.",
"[webpack-dev-server] Hot Module Replacement enabled.",
"[webpack-dev-server] Live Reloading enabled.",
]
`;

exports[`web socket server URL should work with the "client.webSocketURL.username" option ("ws"): page errors 1`] = `Array []`;