Skip to content

Commit 5abe7f8

Browse files
committed
Only set client config after correct instance has been loaded
Related to: #231
1 parent b2e1d32 commit 5abe7f8

File tree

2 files changed

+117
-85
lines changed

2 files changed

+117
-85
lines changed

app/lib/auth/controller.js

+114-58
Original file line numberDiff line numberDiff line change
@@ -91,21 +91,26 @@ module.exports = function(env, clientConfig) {
9191
}
9292

9393
function _doBasicAuth(username, password) {
94-
clientConfig.set('authMethod', 'basic');
95-
clientConfig.set('username', username);
96-
9794
return new Promise(function(resolve, reject){
98-
clientConfig.storeSecret('password', password).then(() => {
99-
verifyAuthentication().then(resolve).catch((error) => {
100-
logger.error('failed signin via basic auth', {
95+
var config = {
96+
authMethod: 'basic',
97+
username,
98+
password
99+
};
100+
101+
verifyAuthentication(config).then(() => {
102+
clientConfig.set('authMethod', 'basic');
103+
104+
clientConfig.storeSecret('password', password).then(resolve).catch((error) => {
105+
logger.error('failed store secret in keystore', {
101106
category: 'auth',
102107
error: error
103108
});
104109

105110
reject(error);
106111
});
107112
}).catch((error) => {
108-
logger.error('failed store secret in keystore', {
113+
logger.error('failed signin via basic auth', {
109114
category: 'auth',
110115
error: error
111116
});
@@ -116,9 +121,6 @@ module.exports = function(env, clientConfig) {
116121
}
117122

118123
function _doTokenAuth(username, password, code) {
119-
clientConfig.set('authMethod', 'token');
120-
clientConfig.set('username', username);
121-
122124
return new Promise(function(resolve, reject){
123125
var apiUrl = clientConfig.get('apiUrl').replace('/v1', '/v2');
124126

@@ -156,18 +158,23 @@ module.exports = function(env, clientConfig) {
156158

157159
switch(response.statusCode) {
158160
case 200:
159-
_storeAuthTokens(body)
160-
.then(() => {
161-
verifyAuthentication().then(resolve).catch((error) => {
162-
logger.error('failed signin via token auth', {
163-
category: 'auth',
164-
error: error
165-
});
161+
var config = {
162+
authMethod: 'token',
163+
accessToken: body.access_token
164+
};
166165

167-
reject(error);
168-
});
169-
})
170-
.catch(reject);
166+
verifyAuthentication(config).then(() => {
167+
clientConfig.set('authMethod', 'token');
168+
169+
_storeAuthTokens(body).then(resolve).catch(reject);
170+
}).catch((error) => {
171+
logger.error('failed signin via token auth', {
172+
category: 'auth',
173+
error: error
174+
});
175+
176+
reject(error);
177+
});
171178
break;
172179
case 403:
173180
if(body.error === 'Balloon\\App\\Idp\\Exception\\MultiFactorAuthenticationRequired') {
@@ -187,6 +194,31 @@ module.exports = function(env, clientConfig) {
187194
});
188195
}
189196

197+
function _storeOidcAuthTokens(response) {
198+
return new Promise((resolve, reject) => {
199+
if(!response.accessToken) {
200+
logger.error('access token not set in oidc response', {category: 'auth'});
201+
return reject(new Error('Response does not contain accessToken'));
202+
}
203+
204+
var promises = [];
205+
206+
promises.push(clientConfig.storeSecret('accessToken', response.accessToken));
207+
208+
if(response.refreshToken) {
209+
promises.push(clientConfig.storeSecret('refreshToken', response.refreshToken))
210+
}
211+
212+
Promise.all(promises).then(() => {
213+
logger.debug('Stored oidc tokens', {category: 'auth'});
214+
resolve();
215+
}).catch((err) => {
216+
logger.error('Could not store oidc tokens', {category: 'auth', err});
217+
reject(err);
218+
});
219+
});
220+
}
221+
190222
function _storeAuthTokens(body) {
191223
return new Promise(function(resolve, reject) {
192224
if(!body.access_token) {
@@ -238,12 +270,20 @@ module.exports = function(env, clientConfig) {
238270
var idpConfig = getIdPByProviderUrl(oidcProvider);
239271
}
240272

241-
oidc.refreshAccessToken(idpConfig).then(() => {
242-
verifyAuthentication().then(resolve).catch((error) => {
243-
logger.error('failed refresh access_token', {
244-
category: 'auth',
245-
error: error
246-
});
273+
oidc.refreshAccessToken(idpConfig).then(response => {
274+
var config = {
275+
authMethod: 'oidc',
276+
accessToken: response.accessToken
277+
};
278+
279+
verifyAuthentication(config).then(() => {
280+
clientConfig.set('authMethod', 'oidc');
281+
clientConfig.set('oidcProvider', idpConfig.providerUrl);
282+
clientConfig.set('accessTokenExpires', response.issuedAt + response.expiresIn);
283+
284+
_storeOidcAuthTokens(response).then(resolve).catch(reject);
285+
}).catch((error) => {
286+
logger.error('failed refresh access_token', { category: 'auth', error: error});
247287

248288
reject(error);
249289
});
@@ -285,21 +325,26 @@ module.exports = function(env, clientConfig) {
285325

286326
switch(response.statusCode) {
287327
case 200:
288-
_storeAuthTokens(body)
289-
.then(() => {
290-
verifyAuthentication().then(resolve).catch((error) => {
291-
logger.error('verify auth after refresh access token failed', {
292-
category: 'auth',
293-
error: error
294-
});
295-
296-
reject(error);
297-
});
298-
})
299-
.catch(reject);
328+
var config = {
329+
authMethod: 'token',
330+
accessToken: body.access_token
331+
};
332+
333+
verifyAuthentication(config).then(() => {
334+
clientConfig.set('authMethod', 'token');
335+
_storeAuthTokens(body).then(resolve).catch(reject);
336+
}).catch((error) => {
337+
logger.error('verify auth after refresh access token failed', {
338+
category: 'auth',
339+
error: error
340+
});
341+
342+
reject(error);
343+
});
300344
break;
301345
case 400:
302346
default:
347+
logger.info('refresh token failed', {category: 'auth', body});
303348
reject(new Error(body.error_description));
304349
break;
305350
}
@@ -315,9 +360,19 @@ module.exports = function(env, clientConfig) {
315360
//TODO pixtron - we can remove these? clientConfig.set('oidcProvider', undefined);
316361
function oidcAuth(idpConfig) {
317362
return new Promise(function(resolve, reject) {
318-
oidc.signin(idpConfig).then(() => {
319-
verifyAuthentication().then(resolve).catch((error) => {
320-
clientConfig.set('oidcProvider', undefined);
363+
oidc.signin(idpConfig).then((result) => {
364+
var config = {
365+
authMethod: 'oidc',
366+
accessToken: result.accessToken
367+
};
368+
369+
verifyAuthentication(config).then(() => {
370+
clientConfig.set('authMethod', 'oidc');
371+
clientConfig.set('oidcProvider', idpConfig.providerUrl);
372+
clientConfig.set('accessTokenExpires', result.issuedAt + result.expiresIn);
373+
374+
_storeOidcAuthTokens(result).then(resolve).catch(reject);
375+
}).catch((error) => {
321376
logger.error('failed to authorize via oidc', {category: 'auth', error});
322377

323378
reject(error)
@@ -351,18 +406,24 @@ module.exports = function(env, clientConfig) {
351406
logger.info('login initialized', {category: 'auth'});
352407

353408
return new Promise(function (resolve, reject) {
354-
verifyAuthentication().then(resolve).catch((err) => {
355-
logger.info('login failed', {
356-
category: 'auth',
357-
error: err
358-
});
409+
var authMethod = clientConfig.get('authMethod');
410+
var config = { authMethod };
411+
412+
if(authMethod === 'basic') {
413+
config.username = clientConfig.get('username');
414+
config.password = clientConfig.getSecret();
415+
} else {
416+
config.accessToken = clientConfig.getSecret();
417+
}
418+
419+
verifyAuthentication(config).then(resolve).catch((err) => {
420+
logger.info('login failed', { category: 'auth', error: err, authMethod});
359421

360422
if(err.code && ['E_BLN_API_REQUEST_UNAUTHORIZED', 'E_BLN_API_REQUEST_MFA_REQUIRED'].includes(err.code) === false) {
361423
// assume there is a network problem, should retry later
362424
return reject(err);
363425
}
364426

365-
var authMethod = clientConfig.get('authMethod');
366427
switch(authMethod) {
367428
case 'oidc':
368429
case 'token':
@@ -398,19 +459,17 @@ module.exports = function(env, clientConfig) {
398459
return undefined;
399460
}
400461

401-
function verifyAuthentication() {
462+
function verifyAuthentication(config) {
402463
//resolves with boolean true if a new instance was created (aka never seen user)
403464
return new Promise(function(resolve, reject) {
404-
var config = clientConfig.getAll(true);
405-
406-
if((['oidc', 'token'].includes(config.authMethod) && !config.accessToken) || (config.authMethod === 'basic' && !config.password)) {
465+
if((['oidc', 'token'].includes(config.authMethod) && !config.accessToken) || (config.authMethod === 'basic' && (!config.password || !config.username))) {
407466
logger.error('can not verify credentials, no secret available', {category: 'auth'});
408467
reject(new Error('Secret not set'));
409468
}
410469

411470
logger.info('verifying new user credentials with whoami call', {category: 'auth', authMethod: config.authMethod, username: config.username});
412471

413-
whoami().then(username => {
472+
whoami(config).then(username => {
414473
var url = clientConfig.get('blnUrl');
415474
var context = clientConfig.get('context');
416475

@@ -427,19 +486,17 @@ module.exports = function(env, clientConfig) {
427486
});
428487
}
429488

430-
function whoami() {
489+
function whoami(config) {
431490
return new Promise((resolve, reject) => {
432-
var config = clientConfig.getAll(true);
433491
config.version = globalConfig.get('version');
492+
config.apiUrl = clientConfig.get('apiUrl');
434493

435494
var sync = fullSyncFactory(config, logger);
436495

437496
sync.blnApi.whoami(function(error, username) {
438497
if(error) {
439498
logger.info('whoami failed', {category: 'auth', error, username});
440499

441-
clientConfig.set('loggedin', false);
442-
443500
if(error.code && isNetworkError(error)) {
444501
error = new AuthError(error.message, 'E_BLN_AUTH_NETWORK');
445502
} else if(error.code && error.code !== 'E_BLN_API_REQUEST_UNAUTHORIZED') {
@@ -450,7 +507,6 @@ module.exports = function(env, clientConfig) {
450507
} else {
451508
logger.info('whoami successfull', {category: 'auth', username});
452509

453-
clientConfig.set('loggedin', true);
454510
resolve(username);
455511
}
456512
});

app/lib/oidc/controller.js

+3-27
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,8 @@ module.exports = function (env, clientConfig) {
9696

9797
if(response) {
9898
makeRefreshTokenRequest(configuration, response.code, codeVerifier)
99-
.then((result) => {
100-
clientConfig.set('authMethod', 'oidc');
101-
102-
_storeSecrets(result).then(() => {
103-
logger.debug('Stored tokens', {category: 'openid-connect'});
104-
105-
clientConfig.set('oidcProvider', idpConfig.providerUrl);
106-
clientConfig.set('accessTokenExpires', result.issuedAt + result.expiresIn);
107-
108-
resolve();
109-
}).catch((err) => { //catch Promise.all
110-
clientConfig.set('authMethod', undefined);
111-
logger.error('Could not store tokens', {category: 'openid-connect', err})
112-
reject(err);
113-
});
114-
}).catch(reject); //catch makeRefreshTokenRequest
99+
.then(resolve)
100+
.catch(reject);
115101
} else {
116102
reject(error);
117103
}
@@ -208,17 +194,7 @@ module.exports = function (env, clientConfig) {
208194
category: 'openid-connect'
209195
});
210196

211-
makeAccessTokenRequest(configuration, secret).then((response) => {
212-
_storeSecrets(response)
213-
.then(() => {
214-
clientConfig.set('accessTokenExpires', response.issuedAt + response.expiresIn);
215-
resolve();
216-
})
217-
.catch(err => {
218-
logger.error('Could not store accessToken', {catgory: 'openid-connect', err});
219-
reject(err);
220-
});
221-
}).catch((error) => {
197+
makeAccessTokenRequest(configuration, secret).then(resolve).catch((error) => {
222198
logger.info('failed to refresh accessToken', {category: 'openid-connect', error});
223199

224200
reject(error);

0 commit comments

Comments
 (0)