Skip to content

Commit

Permalink
fix: send oauth error to browser
Browse files Browse the repository at this point in the history
  • Loading branch information
amphro committed Jan 26, 2021
1 parent f04e66e commit 5fd027a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
3 changes: 2 additions & 1 deletion messages/auth.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"PortInUseAction": "Kill the process running on port %s or use a custom connected app and update OauthLocalPort in the sfdx-project.json file.",
"invalidRequestMethod": "Invalid request method: %s",
"invalidRequestUri": "Invalid request uri: %s",
"pollingTimeout": "The device authorization request timed out. After executing force:auth:device:login, you must approve access to the device within 10 minutes. This can happen if the URL wasn’t copied into the browser, login was not attempted, or the 2FA process was not completed within 10 minutes. Request authorization again."
"pollingTimeout": "The device authorization request timed out. After executing force:auth:device:login, you must approve access to the device within 10 minutes. This can happen if the URL wasn’t copied into the browser, login was not attempted, or the 2FA process was not completed within 10 minutes. Request authorization again.",
"ServerErrorHTMLResponse": "<h1>%s</h1><br />This is most likely <b>not</b> an error with the Salesforce CLI. Please ensure all information is accurate and try again."
}
14 changes: 14 additions & 0 deletions src/webOAuthServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export class WebOAuthServer extends AsyncCreatable<WebOAuthServer.Options> {
response.end();
resolve(authInfo);
} catch (err) {
this.webServer.reportError(err, response);
reject(err);
}
})
Expand Down Expand Up @@ -316,6 +317,19 @@ export class WebServer extends AsyncCreatable<WebServer.Options> {
response.end(body);
}

/**
* sends a response to the browser reporting an error.
*
* @param error the error
* @param response the response to write the redirect to.
*/
public reportError(error: Error, response: http.ServerResponse): void {
response.setHeader('Content-Type', 'text/html');
const body = messages.getMessage('ServerErrorHTMLResponse', [error.message]);
response.setHeader('Content-Length', Buffer.byteLength(body));
response.end(body);
}

protected async init(): Promise<void> {
this.logger = await Logger.child(this.constructor.name);
}
Expand Down
19 changes: 18 additions & 1 deletion test/unit/webOauthServerTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import * as http from 'http';
import { expect } from 'chai';

import { assert } from '@salesforce/ts-types';
import { StubbedType, stubInterface, stubMethod } from '@salesforce/ts-sinon';
import { Env } from '@salesforce/kit';
import { testSetup, MockTestOrgData } from '../../src/testSetup';
Expand Down Expand Up @@ -47,6 +48,7 @@ describe('WebOauthServer', () => {
let authInfoStub: StubbedType<AuthInfo>;
let serverResponseStub: StubbedType<http.ServerResponse>;
let redirectStub: sinon.SinonStub;
let authStub: sinon.SinonStub;

beforeEach(async () => {
authFields = await testData.getConfig();
Expand All @@ -57,7 +59,7 @@ describe('WebOauthServer', () => {
serverResponseStub = stubInterface<http.ServerResponse>($$.SANDBOX, {});

stubMethod($$.SANDBOX, WebOAuthServer.prototype, 'executeOauthRequest').callsFake(async () => serverResponseStub);
stubMethod($$.SANDBOX, AuthInfo, 'create').callsFake(async () => authInfoStub);
authStub = stubMethod($$.SANDBOX, AuthInfo, 'create').callsFake(async () => authInfoStub);
redirectStub = stubMethod($$.SANDBOX, WebServer.prototype, 'doRedirect').callsFake(async () => {});
});

Expand All @@ -76,6 +78,21 @@ describe('WebOauthServer', () => {
expect(redirectStub.callCount).to.equal(1);
expect(redirectStub.args).to.deep.equal([[303, frontDoorUrl, serverResponseStub]]);
});

it('should report error', async () => {
const reportErrorStub = stubMethod($$.SANDBOX, WebServer.prototype, 'reportError').callsFake(async () => {});
authStub.rejects(new Error('BAD ERROR'));
const oauthServer = await WebOAuthServer.create({ oauthConfig: {} });
await oauthServer.start();
try {
await oauthServer.authorizeAndSave();
assert(false, 'authorizeAndSave should fail');
} catch (e) {
expect(e.message, 'BAD ERROR');
}
expect(authStub.callCount).to.equal(1);
expect(reportErrorStub.args[0][0].message).to.equal('BAD ERROR');
});
});

describe('parseAuthCodeFromRequest', () => {
Expand Down

0 comments on commit 5fd027a

Please sign in to comment.