Skip to content
This repository was archived by the owner on Oct 7, 2022. It is now read-only.

Commit e3558a5

Browse files
committed
fix oauth1 request signing
1 parent f528fc1 commit e3558a5

File tree

3 files changed

+92
-71
lines changed

3 files changed

+92
-71
lines changed

dist/axios.js

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,62 @@
11
"use strict";
22
Object.defineProperty(exports, "__esModule", { value: true });
33
const axios_1 = require("axios");
4+
const buildURL_1 = require("axios/lib/helpers/buildURL");
45
const utils_1 = require("./utils");
5-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
6-
// see non-escaped chars
7-
// this handles not encoding [!'()*]
8-
function encodeReservedChars(str) {
9-
return str.replace(/[!'()*]/g, function (c) {
10-
return '%' + c.charCodeAt(0).toString(16);
11-
});
6+
function cleanObject(o) {
7+
for (const k in o || {}) {
8+
if (typeof o[k] === "undefined") {
9+
delete o[k];
10+
}
11+
}
12+
}
13+
// remove query params from url and put into config.params
14+
function removeSearchFromUrl(config) {
15+
if (!config.url)
16+
return;
17+
const url = new URL(config.url);
18+
const queryString = url.search.substr(1);
19+
if (queryString) {
20+
// https://stackoverflow.com/a/8649003/387413
21+
const urlParams = JSON.parse('{"' + queryString.replace(/&/g, '","').replace(/=/g, '":"') + '"}', function (key, value) {
22+
return key === "" ? value : decodeURIComponent(value);
23+
});
24+
for (const k in urlParams) {
25+
if (!config.params)
26+
config.params = {};
27+
if (k in config.params)
28+
continue; // params object > url query params
29+
config.params[k] = urlParams[k];
30+
}
31+
url.search = "";
32+
config.url = url.toString(); // if ends with ? should be okay, but could be cleaner
33+
}
1234
}
35+
// XXX warn about mutating config object... or clone?
1336
async function default_1(step, config, signConfig) {
14-
// XXX warn about mutating config object... or clone?
37+
cleanObject(config.headers);
38+
cleanObject(config.params);
39+
if (typeof config.data === "object") {
40+
cleanObject(config.data);
41+
}
42+
removeSearchFromUrl(config);
1543
// OAuth1 request
1644
if (signConfig) {
1745
const { oauthSignerUri, token } = signConfig;
18-
if (config.url) {
19-
// this handles encoding query string to make sure we match what we sign
20-
const url = new URL(config.url);
21-
url.search = encodeReservedChars(url.search.substr(1));
22-
config.url = url.toString();
23-
}
46+
const requestData = {
47+
method: config.method || "get",
48+
url: buildURL_1.default(config.url, config.params),
49+
data: config.data,
50+
};
2451
const payload = {
25-
requestData: config,
52+
requestData,
2653
token,
2754
};
2855
const oauthSignature = (await axios_1.default.post(oauthSignerUri, payload)).data;
2956
if (!config.headers)
3057
config.headers = {};
3158
config.headers.Authorization = oauthSignature;
3259
}
33-
for (const k in config.headers || {}) {
34-
if (typeof config.headers[k] === "undefined") {
35-
delete config.headers[k];
36-
}
37-
}
3860
try {
3961
return (await axios_1.default(config)).data;
4062
}

lib/axios.ts

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,60 @@
11
import axios from "axios"
22
import { AxiosRequestConfig } from "axios"
3+
import buildURL from "axios/lib/helpers/buildURL"
34
import { cloneSafe } from "./utils"
45

5-
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
6-
// see non-escaped chars
7-
// this handles not encoding [!'()*]
8-
function encodeReservedChars(str: String) {
9-
return str.replace(/[!'()*]/g, function(c) {
10-
return '%' + c.charCodeAt(0).toString(16)
11-
})
6+
function cleanObject(o: {string: any}) {
7+
for (const k in o || {}) {
8+
if (typeof o[k] === "undefined") {
9+
delete o[k]
10+
}
11+
}
12+
}
13+
14+
// remove query params from url and put into config.params
15+
function removeSearchFromUrl(config: AxiosRequestConfig) {
16+
if (!config.url) return
17+
const url = new URL(config.url)
18+
const queryString = url.search.substr(1)
19+
if (queryString) {
20+
// https://stackoverflow.com/a/8649003/387413
21+
const urlParams = JSON.parse('{"' + queryString.replace(/&/g, '","').replace(/=/g,'":"') + '"}', function(key, value) {
22+
return key === "" ? value : decodeURIComponent(value)
23+
})
24+
for (const k in urlParams) {
25+
if (!config.params) config.params = {}
26+
if (k in config.params) continue // params object > url query params
27+
config.params[k] = urlParams[k]
28+
}
29+
url.search = ""
30+
config.url = url.toString() // if ends with ? should be okay, but could be cleaner
31+
}
1232
}
1333

34+
// XXX warn about mutating config object... or clone?
1435
export default async function(step: any, config: AxiosRequestConfig, signConfig?: any) {
15-
// XXX warn about mutating config object... or clone?
36+
cleanObject(config.headers)
37+
cleanObject(config.params)
38+
if (typeof config.data === "object") {
39+
cleanObject(config.data)
40+
}
41+
removeSearchFromUrl(config)
1642
// OAuth1 request
1743
if (signConfig) {
1844
const {oauthSignerUri, token} = signConfig
19-
20-
if (config.url) {
21-
// this handles encoding query string to make sure we match what we sign
22-
const url = new URL(config.url)
23-
url.search = encodeReservedChars(url.search.substr(1))
24-
config.url = url.toString()
45+
const requestData = {
46+
method: config.method || "get",
47+
url: buildURL(config.url, config.params), // build url as axios will
48+
data: config.data,
2549
}
26-
2750
const payload = {
28-
requestData: config,
51+
requestData,
2952
token,
3053
}
3154
const oauthSignature = (await axios.post(oauthSignerUri, payload)).data
3255
if (!config.headers) config.headers = {}
3356
config.headers.Authorization = oauthSignature
3457
}
35-
for (const k in config.headers || {}) {
36-
if (typeof config.headers[k] === "undefined") {
37-
delete config.headers[k]
38-
}
39-
}
4058
try {
4159
return (await axios(config)).data
4260
} catch (err) {

package-lock.json

Lines changed: 11 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)