Skip to content

Commit e6afdfb

Browse files
committed
feat: Allow usage without client_secret for services that only rely on PKCE
1 parent bcb4360 commit e6afdfb

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

src/Service.js

-1
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,6 @@ Service_.prototype.handleCallback = function(callbackRequest) {
448448
}
449449
validate_({
450450
'Client ID': this.clientId_,
451-
'Client Secret': this.clientSecret_,
452451
'Token URL': this.tokenUrl_
453452
});
454453
var payload = {

test/test.js

+41-11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ var MockCache = require('./mocks/cache');
2222
var MockLock = require('./mocks/lock');
2323
var MockScriptApp = require('./mocks/script');
2424
var MockUtilities = require('./mocks/utilities');
25+
2526
var mocks = {
2627
ScriptApp: new MockScriptApp(),
2728
UrlFetchApp: new MockUrlFetchApp(),
@@ -514,6 +515,27 @@ describe('Service', () => {
514515
assert.include(authorizationUrl, 'code_challenge');
515516
assert.include(authorizationUrl, 'code_challenge_method=S256');
516517
});
518+
519+
520+
it('should use supply verifier when exchanging code', () => {
521+
var service = OAuth2.createService('test')
522+
.setAuthorizationBaseUrl('http://www.example.com')
523+
.setTokenUrl('http://www.example.com/token')
524+
.setClientId('abc')
525+
.setCallbackFunction('authCallback')
526+
.generateCodeVerifier();
527+
var authorizationUrl = service.getAuthorizationUrl({});
528+
var state = extractStateTokenFromUrl(authorizationUrl);
529+
mocks.UrlFetchApp.resultFunction = (url, opts) => {
530+
assert.isNotNull(opts.payload.code_verifier, 'Code verifier not present');
531+
return `{ "access_token": "123" }`;
532+
};
533+
service.handleCallback({
534+
parameter: Object.assign({
535+
code: 'test',
536+
}, state.arguments)
537+
});
538+
});
517539
});
518540

519541
describe('#getAuthorizationUrl()', () => {
@@ -527,17 +549,7 @@ describe('Service', () => {
527549
foo: 'bar'
528550
});
529551

530-
// Extract the state token from the URL and parse it. For example, the
531-
// URL http://www.example.com?state=%7B%22a%22%3A1%7D would produce
532-
// {a: 1}.
533-
var querystring = authorizationUrl.split('?')[1];
534-
var params = querystring.split('&').reduce((result, pair) => {
535-
var parts = pair.split('=').map(decodeURIComponent);
536-
result[parts[0]] = parts[1];
537-
return result;
538-
}, {});
539-
var state = JSON.parse(params.state);
540-
552+
var state = extractStateTokenFromUrl(authorizationUrl);
541553
assert.equal(state.arguments.foo, 'bar');
542554
});
543555
});
@@ -858,3 +870,21 @@ describe('Utilities', () => {
858870
});
859871
});
860872
});
873+
874+
875+
/*
876+
*Extract the state token from the URL and parse it. For example, the
877+
* URL http://www.example.com?state=%7B%22a%22%3A1%7D would produce
878+
* {a: 1}.
879+
*/
880+
function extractStateTokenFromUrl(authorizationUrl) {
881+
var querystring = authorizationUrl.split('?')[1];
882+
var params = querystring.split('&').reduce((result, pair) => {
883+
var parts = pair.split('=').map(decodeURIComponent);
884+
result[parts[0]] = parts[1];
885+
return result;
886+
}, {});
887+
var state = JSON.parse(params.state);
888+
return state;
889+
}
890+

0 commit comments

Comments
 (0)