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

Merging main from origin #9

Merged
merged 3 commits into from
Mar 12, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions __tests__/getAuthorizationHeader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const imgur = require('../lib/imgur.js');

afterEach(imgur.clearAllCredentials);

test('returns provided access code in bearer header', async () => {
const accessToken = 'abc123';
const imgur = require('../lib/imgur.js');
imgur.setAccessToken(accessToken);
const authorizationHeader = await imgur._getAuthorizationHeader();
expect(authorizationHeader).toBe(`Bearer ${accessToken}`);
});

test('returns provided client id in client id header', async () => {
const clientId = 'abc123';
imgur.setClientId(clientId);
const authorizationHeader = await imgur._getAuthorizationHeader();
expect(authorizationHeader).toBe(`Client-ID ${clientId}`);
});

test.only('retrieves access token from imgur via provided username/password/clientid', async () => {
imgur.setCredentials('fakeusername', 'fakepassword', 'fakeclientd');
const authorizationHeader = await imgur._getAuthorizationHeader();
expect(authorizationHeader).toMatchInlineSnapshot(
`"Bearer 123accesstoken456"`
);
});
34 changes: 23 additions & 11 deletions lib/imgur.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const VERSION = require('../package.json').version;
// registered 'node-imgur' app and is available
// here for public, anonymous usage via this node
// module only.
let imgurClientId = process.env.IMGUR_CLIENT_ID || 'f0ea04148a54268';
const defaultClientId = 'f0ea04148a54268';
let imgurClientId = process.env.IMGUR_CLIENT_ID || defaultClientId;
let imgurApiUrl = process.env.IMGUR_API_URL || 'https://api.imgur.com/3/';
let imgurMashapeKey = process.env.IMGUR_MASHAPE_KEY;
let imgurUsername = null;
Expand Down Expand Up @@ -111,13 +112,14 @@ imgur._imgurRequest = async (operation, payload, extraFormParams) => {
}

response = await imgur._request(options);
if (response && !response.success) {
const { statusCode: status, statusMessage: message } = response;
if (status !== 200) {
throw new Error({
status: response.status,
message: response.data ? response.error : 'No body data response',
status,
message,
});
} else {
return response.data;
return JSON.parse(response.body).data;
}
};

Expand All @@ -127,7 +129,7 @@ imgur._imgurRequest = async (operation, payload, extraFormParams) => {
* @param {object} options
* @returns {promise}
*/
imgur._request = async (options) => await got(options).json();
imgur._request = async (options) => await got(options);

/**
* Get imgur access token using credentials
Expand All @@ -144,7 +146,7 @@ imgur._getAuthorizationHeader = async () => {
}

const options = {
uri: 'https://api.imgur.com/oauth2/authorize',
url: 'https://api.imgur.com/oauth2/authorize',
method: 'GET',
encoding: 'utf8',
searchParams: {
Expand All @@ -156,18 +158,21 @@ imgur._getAuthorizationHeader = async () => {
let response;

response = await imgur._request(options);
const authorize_token = response.headers['set-cookie'][0].match(
'(^|;)[s]*authorize_token=([^;]*)'
)[2];

const cookies = Array.isArray(response.headers['set-cookie'])
? response.headers['set-cookie'][0]
: response.headers['set-cookie'];
const authorize_token = cookies.match('(^|;)[s]*authorize_token=([^;]*)')[2];

options.method = 'POST';
options.form = {
username: imgurUsername,
password: imgurPassword,
allow: authorize_token,
};
options.followRedirect = false;
options.headers = {
Cookie: 'authorize_token=' + authorize_token,
cookie: 'authorize_token=' + authorize_token,
};

response = await imgur._request(options);
Expand Down Expand Up @@ -571,3 +576,10 @@ imgur.uploadImages = async (images, uploadType, albumId) => {
imgur.getCredits = async () => {
return await imgur._imgurRequest('credits');
};

imgur.clearAllCredentials = () => {
imgurAccessToken = null;
imgurUsername = null;
imgurPassword = null;
imgurClientId = defaultClientId;
};
89 changes: 89 additions & 0 deletions lib/mocks/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,95 @@ const handlers = [
};
return res(ctx.json(response));
}),

rest.get('https://api.imgur.com/oauth2/authorize', (req, res, ctx) => {
const clientId = req.url.searchParams.get('client_id');
const responseType = req.url.searchParams.get('response_type');

if (!(clientId && responseType)) {
return res(
ctx.status(400),
ctx.json({
data: {
error: 'client_id and response_type are required',
request: '/oauth/authorize',
method: 'GET',
},
success: false,
status: 400,
})
);
}

const mockAuthorizeToken = 'abcxyz';
const html = `
<html>
<form method="post" action="">
<input type="text" name="username" id="username">
<input type="password" name="password" id="password">
<button type="submit" name="allow" value="${mockAuthorizeToken}"></button>
</form>
</html>
`;
return res(
ctx.cookie('authorize_token', mockAuthorizeToken, {
path: '/oauth2',
domain: '.api.imgur.com',
secure: true,
httpOnly: true,
}),
ctx.status(200),
ctx.body(html)
);
}),

rest.post('https://api.imgur.com/oauth2/authorize', (req, res, ctx) => {
const clientId = req.url.searchParams.get('client_id');
const responseType = req.url.searchParams.get('response_type');

if (!(clientId && responseType)) {
return res(
ctx.status(400),
ctx.json({
data: {
error: 'client_id and response_type are required',
request: '/oauth/authorize',
method: 'POST',
},
success: false,
status: 400,
})
);
}

const { username, password, allow } = Object.fromEntries(
new URLSearchParams(req.body)
);

if (!(username && password && allow)) {
return res(
ctx.status(403),
ctx.json({
data: {
error: 'Unauthorized',
request: '/oauth2/authorize',
method: 'POST',
},
success: false,
status: 403,
})
);
}

return res(
ctx.status(302),
ctx.set(
'Location',
`https://somedomain.com#access_token=123accesstoken456&expires_in=315360000&token_type=bearer&refresh_token=123refrestoken456&account_username=${username}&account_id=123456`
),
ctx.cookie('authorize_token', allow)
);
}),
];

module.exports = {
Expand Down