Skip to content

Commit c6f41f6

Browse files
committedMar 14, 2022
feat: always parse username passed via URI
BREAKING CHANGE: `allowUsernameInURI` is removed and ioredis will always use the username passed via URI. Previously, the `username` part in `new Redis("redis://username:authpassword@127.0.0.1:6380/4")` was ignored unless `allowUsernameInURI` is specified: `new Redis("redis://username:authpassword@127.0.0.1:6380/4?allowUsernameInURI=true")`. Now, if you don't want to send username to Redis, just leave the username part empty: `new Redis("redis://:authpassword@127.0.0.1:6380/4")`
1 parent 04e68ac commit c6f41f6

File tree

3 files changed

+30
-120
lines changed

3 files changed

+30
-120
lines changed
 

‎README.md

+26-61
Original file line numberDiff line numberDiff line change
@@ -104,78 +104,45 @@ $ npm install ioredis
104104
## Basic Usage
105105

106106
```javascript
107+
// Import ioredis.
108+
// You can also use `import Redis from "ioredis"`
109+
// if your project is an ESM module or a TypeScript project.
107110
const Redis = require("ioredis");
108111

109-
// First, you need to create a Redis instance.
110-
// We are going to cover how to specify host, port, and other connection
111-
// options soon.
112+
// Create a Redis instance.
113+
// By default, it will connect to localhost:6379.
114+
// We are going to cover how to specify connection options soon.
112115
const redis = new Redis();
113116

114-
// Invoke the SET command. This is equivalent to the cli `redis> SET name Bob`:
115-
redis.set("name", "Bob"); // Returns a Promise
117+
redis.set("mykey", "value"); // Returns a promise which resolves to "OK" when the command succeeds.
116118

117-
// ioredis provides two kind of APIs, Node.js callback and Promise.
118-
// 1. You can pass a callback as the last parameter. It will be called when
119-
// we get a response from the Redis server:
120-
redis.get("name", (err, value) => {
119+
// ioredis supports the node.js callback style
120+
redis.get("mykey", (err, result) => {
121121
if (err) {
122122
console.error(err);
123123
} else {
124-
console.log(value); // "Bob"
124+
console.log(result); // Prints "value"
125125
}
126126
});
127127

128-
// 2. Additionally, every command method returns a Promise
129-
// representing the server response:
130-
redis.get("name").then(
131-
(value) => {
132-
console.log(value);
133-
},
134-
(err) => {
135-
console.error(err);
136-
}
137-
);
138-
139-
//
140-
141-
// Every
142-
143-
async function main() {
144-
await redis.set("mykey", "Hello, World!");
145-
const value = await redis.get("mykey"); // value === "Hello, World!"
146-
}
147-
148-
main();
149-
```
150-
151-
// ioredis supports all Redis commands:
152-
redis.set("foo", "bar"); // returns promise which resolves to string, "OK"
153-
154-
// the format is: redis[REDIS_COMMAND_NAME_IN_LOWERCASE](ARGUMENTS_ARE_JOINED_INTO_COMMAND_STRING)
155-
// the js: `redis.set("mykey", "Hello")` is equivalent to the cli: ` redis> SET mykey "Hello"`
156-
157-
// ioredis supports the Node.js callback style
158-
redis.get("foo", (err, result) => {
159-
if (err) {
160-
console.error(err);
161-
} else {
162-
console.log(result); // Promise resolves to "bar"
163-
}
164-
});
165-
166128
// Or ioredis returns a promise if the last argument isn't a function
167-
redis.get("foo").then((result) => {
168-
console.log(result); // Prints "bar"
129+
redis.get("mykey").then((result) => {
130+
console.log(result); // Prints "value"
169131
});
170132

171-
// Most responses are strings, or arrays of strings
172133
redis.zadd("sortedSet", 1, "one", 2, "dos", 4, "quatro", 3, "three");
173-
redis.zrange("sortedSet", 0, 2, "WITHSCORES").then((res) => console.log(res)); // Promise resolves to ["one", "1", "dos", "2", "three", "3"] as if the command was `redis> ZRANGE sortedSet 0 2 WITHSCORES`
134+
redis.zrange("sortedSet", 0, 2, "WITHSCORES").then((elements) => {
135+
// ["one", "1", "dos", "2", "three", "3"] as if the command was `redis> ZRANGE sortedSet 0 2 WITHSCORES`
136+
console.log(elements);
137+
});
174138

175-
// All arguments are passed directly to the redis server:
176-
redis.set("key", 100, "EX", 10);
139+
// All arguments are passed directly to the redis server,
140+
// so technically ioredis supports all Redis commands.
141+
// The format is: redis[SOME_REDIS_COMMAND_IN_LOWERCASE](ARGUMENTS_ARE_JOINED_INTO_COMMAND_STRING)
142+
// so the following statement is equivalent to the CLI: `redis> SET mykey hello EX 10`
143+
redis.set("mykey", "hello", "EX", 10);
144+
```
177145

178-
````
179146

180147
See the `examples/` folder for more examples.
181148

@@ -193,9 +160,9 @@ new Redis("/tmp/redis.sock");
193160
new Redis({
194161
port: 6379, // Redis port
195162
host: "127.0.0.1", // Redis host
196-
family: 4, // 4 (IPv4) or 6 (IPv6)
197-
password: "auth",
198-
db: 0,
163+
username: "default", // needs Redis >= 6
164+
password: "my-top-secret",
165+
db: 0, // Defaults to 0
199166
});
200167
````
201168

@@ -206,10 +173,8 @@ You can also specify connection options as a [`redis://` URL](http://www.iana.or
206173
new Redis("redis://:authpassword@127.0.0.1:6380/4");
207174
208175
// Username can also be passed via URI.
209-
// It's worth to noticing that for compatibility reasons `allowUsernameInURI`
210-
// need to be provided, otherwise the username part will be ignored.
211176
new Redis(
212-
"redis://username:authpassword@127.0.0.1:6380/4?allowUsernameInURI=true"
177+
"redis://username:authpassword@127.0.0.1:6380/4"
213178
);
214179
```
215180

‎lib/utils/index.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -214,17 +214,11 @@ export function parseURL(url: string): Record<string, unknown> {
214214
}
215215

216216
const options = parsed.query || {};
217-
const allowUsernameInURI =
218-
options.allowUsernameInURI && options.allowUsernameInURI !== "false";
219-
delete options.allowUsernameInURI;
220217

221218
const result: any = {};
222219
if (parsed.auth) {
223220
const index = parsed.auth.indexOf(":");
224-
if (allowUsernameInURI) {
225-
result.username =
226-
index === -1 ? parsed.auth : parsed.auth.slice(0, index);
227-
}
221+
result.username = index === -1 ? parsed.auth : parsed.auth.slice(0, index);
228222
result.password = index === -1 ? "" : parsed.auth.slice(index + 1);
229223
}
230224
if (parsed.pathname) {

‎test/unit/utils.ts

+3-52
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ describe("utils", () => {
160160
host: "127.0.0.1",
161161
port: "6380",
162162
db: "4",
163+
username: "user",
163164
password: "pass",
164165
key: "value",
165166
});
@@ -169,13 +170,15 @@ describe("utils", () => {
169170
host: "127.0.0.1",
170171
port: "6380",
171172
db: "4",
173+
username: "user",
172174
password: "pass:word",
173175
key: "value",
174176
});
175177
expect(utils.parseURL("redis://user@127.0.0.1:6380/4?key=value")).to.eql({
176178
host: "127.0.0.1",
177179
port: "6380",
178180
db: "4",
181+
username: "user",
179182
password: "",
180183
key: "value",
181184
});
@@ -184,66 +187,14 @@ describe("utils", () => {
184187
});
185188
expect(
186189
utils.parseURL("rediss://user:pass@127.0.0.1:6380/4?key=value")
187-
).to.eql({
188-
host: "127.0.0.1",
189-
port: "6380",
190-
db: "4",
191-
password: "pass",
192-
key: "value",
193-
});
194-
});
195-
196-
it("supports allowUsernameInURI", () => {
197-
expect(
198-
utils.parseURL(
199-
"redis://user:pass@127.0.0.1:6380/4?allowUsernameInURI=true"
200-
)
201190
).to.eql({
202191
host: "127.0.0.1",
203192
port: "6380",
204193
db: "4",
205194
username: "user",
206195
password: "pass",
207-
});
208-
expect(
209-
utils.parseURL(
210-
"redis://user:pass@127.0.0.1:6380/4?allowUsernameInURI=false"
211-
)
212-
).to.eql({
213-
host: "127.0.0.1",
214-
port: "6380",
215-
db: "4",
216-
password: "pass",
217-
});
218-
expect(
219-
utils.parseURL(
220-
"redis://user:pass:word@127.0.0.1:6380/4?key=value&allowUsernameInURI=true"
221-
)
222-
).to.eql({
223-
host: "127.0.0.1",
224-
port: "6380",
225-
db: "4",
226-
username: "user",
227-
password: "pass:word",
228-
key: "value",
229-
});
230-
expect(
231-
utils.parseURL(
232-
"redis://user@127.0.0.1:6380/4?key=value&allowUsernameInURI=true"
233-
)
234-
).to.eql({
235-
host: "127.0.0.1",
236-
port: "6380",
237-
db: "4",
238-
username: "user",
239-
password: "",
240196
key: "value",
241197
});
242-
expect(
243-
utils.parseURL("redis://127.0.0.1/?allowUsernameInURI=true")
244-
).to.eql({
245-
host: "127.0.0.1",
246-
});
247198
});
248199
});
249200

0 commit comments

Comments
 (0)
Please sign in to comment.