ECOM-4904 Move the program editor backbone app to Studio (#12962)
This commit is contained in:
89
cms/static/js/programs/utils/auth_utils.js
Normal file
89
cms/static/js/programs/utils/auth_utils.js
Normal file
@@ -0,0 +1,89 @@
|
||||
define([
|
||||
'jquery',
|
||||
'underscore',
|
||||
'js/programs/utils/api_config'
|
||||
],
|
||||
function( $, _, apiConfig ) {
|
||||
'use strict';
|
||||
|
||||
var auth = {
|
||||
autoSync: {
|
||||
/**
|
||||
* Override Backbone.sync to seamlessly attempt (re-)authentication when necessary.
|
||||
*
|
||||
* If a 401 error response is encountered while making a request to the Programs,
|
||||
* API, this wrapper will attempt to request an id token from a custom endpoint
|
||||
* via AJAX. Then the original request will be retried once more.
|
||||
*
|
||||
* Any other response than 401 on the original API request, or any error occurring
|
||||
* on the retried API request (including 401), will be handled by the base sync
|
||||
* implementation.
|
||||
*
|
||||
*/
|
||||
sync: function( method, model, options ) {
|
||||
|
||||
var oldError = options.error;
|
||||
|
||||
this._setHeaders( options );
|
||||
|
||||
options.notifyOnError = false; // suppress Studio error pop-up that will happen if we get a 401
|
||||
|
||||
options.error = function(xhr, textStatus, errorThrown) {
|
||||
if (xhr && xhr.status === 401) {
|
||||
// attempt auth and retry
|
||||
this._updateToken(function() {
|
||||
// restore the original error handler
|
||||
options.error = oldError;
|
||||
options.notifyOnError = true; // if it fails again, let Studio notify.
|
||||
delete options.xhr; // remove the failed (401) xhr from the last try.
|
||||
|
||||
// update authorization header
|
||||
this._setHeaders( options );
|
||||
|
||||
Backbone.sync.call(this, method, model, options);
|
||||
}.bind(this));
|
||||
} else if (oldError) {
|
||||
// fall back to the original error handler
|
||||
oldError.call(this, xhr, textStatus, errorThrown);
|
||||
}
|
||||
}.bind(this);
|
||||
return Backbone.sync.call(this, method, model, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* Fix up headers on an imminent AJAX sync, ensuring that the JWT token is enclosed
|
||||
* and that credentials are included when the request is being made cross-domain.
|
||||
*/
|
||||
_setHeaders: function( ajaxOptions ) {
|
||||
ajaxOptions.headers = _.extend ( ajaxOptions.headers || {}, {
|
||||
Authorization: 'JWT ' + apiConfig.get( 'idToken' )
|
||||
});
|
||||
ajaxOptions.xhrFields = _.extend( ajaxOptions.xhrFields || {}, {
|
||||
withCredentials: true
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch a new id token from the configured endpoint, update the api config,
|
||||
* and invoke the specified callback.
|
||||
*/
|
||||
_updateToken: function( success ) {
|
||||
|
||||
$.ajax({
|
||||
url: apiConfig.get('authUrl'),
|
||||
xhrFields: {
|
||||
// See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials
|
||||
withCredentials: true
|
||||
},
|
||||
crossDomain: true
|
||||
}).done(function ( data ) {
|
||||
// save the newly-retrieved id token
|
||||
apiConfig.set( 'idToken', data.id_token );
|
||||
}).done( success );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return auth;
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user