mirror of https://github.com/apache/nifi.git
parent
06cb7cfc10
commit
749f4e9be1
|
@ -28,6 +28,7 @@
|
|||
<link rel="stylesheet" href="js/jquery/qtip2/jquery.qtip.min.css?" type="text/css" />
|
||||
<link rel="stylesheet" href="js/jquery/ui-smoothness/jquery-ui-1.10.4.min.css" type="text/css" />
|
||||
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
|
||||
<script type="text/javascript" src="js/jquery/modal/jquery.modal.js?${project.version}"></script>
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
<script type="text/javascript" src="js/codemirror/lib/codemirror-compressed.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/ui-smoothness/jquery-ui-1.10.4.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.ellipsis.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.each.js"></script>
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick.grid.css" type="text/css" />
|
||||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick-default-theme.css" type="text/css" />
|
||||
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
|
||||
<script type="text/javascript" src="js/jquery/modal/jquery.modal.js?${project.version}"></script>
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick.grid.css" type="text/css" />
|
||||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick-default-theme.css" type="text/css" />
|
||||
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
|
||||
<script type="text/javascript" src="js/jquery/modal/jquery.modal.js?${project.version}"></script>
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick.grid.css" type="text/css" />
|
||||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick-default-theme.css" type="text/css" />
|
||||
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/modal/jquery.modal.js?${project.version}"></script>
|
||||
<script type="text/javascript" src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick.grid.css" type="text/css" />
|
||||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick-default-theme.css" type="text/css" />
|
||||
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/modal/jquery.modal.js?${project.version}"></script>
|
||||
<script type="text/javascript" src="js/jquery/tabbs/jquery.tabbs.js?${project.version}"></script>
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
<script type="text/javascript" src="js/codemirror/lib/codemirror-compressed.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/ui-smoothness/jquery-ui-1.10.4.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/tabbs/jquery.tabbs.js?${project.version}"></script>
|
||||
<script type="text/javascript" src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick.grid.css" type="text/css" />
|
||||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick-default-theme.css" type="text/css" />
|
||||
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.form.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick.grid.css" type="text/css" />
|
||||
<link rel="stylesheet" href="js/jquery/slickgrid/css/slick-default-theme.css" type="text/css" />
|
||||
<script type="text/javascript" src="js/jquery/jquery-2.1.1.min.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.base64.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/jquery.center.js"></script>
|
||||
<script type="text/javascript" src="js/jquery/tabbs/jquery.tabbs.js?${project.version}"></script>
|
||||
<script type="text/javascript" src="js/jquery/combo/jquery.combo.js?${project.version}"></script>
|
||||
|
|
|
@ -98,7 +98,7 @@ nf.Login = (function () {
|
|||
}
|
||||
}).done(function (jwt) {
|
||||
// store the jwt and reload the page
|
||||
nf.Storage.setItem('jwt', jwt);
|
||||
nf.Storage.setItem('jwt', jwt, nf.Common.getJwtExpiration(jwt));
|
||||
|
||||
// check to see if they actually have access now
|
||||
$.ajax({
|
||||
|
@ -109,15 +109,18 @@ nf.Login = (function () {
|
|||
if (response.identity === 'anonymous') {
|
||||
showLogoutLink();
|
||||
|
||||
// schedule automatic token refresh
|
||||
nf.Common.scheduleTokenRefresh();
|
||||
|
||||
// show the user
|
||||
var user = getJwtSubject(jwt);
|
||||
var user = nf.Common.getJwtSubject(jwt);
|
||||
$('#nifi-user-submit-justification').text(user);
|
||||
|
||||
// show the registration form
|
||||
initializeNiFiRegistration();
|
||||
showNiFiRegistration();
|
||||
} else {
|
||||
// reload as appropriate
|
||||
// reload as appropriate - no need to schedule token refresh as the page is reloading
|
||||
if (top !== window) {
|
||||
parent.window.location = '/nifi';
|
||||
} else {
|
||||
|
@ -127,8 +130,11 @@ nf.Login = (function () {
|
|||
}).fail(function (xhr, status, error) {
|
||||
showLogoutLink();
|
||||
|
||||
// schedule automatic token refresh
|
||||
nf.Common.scheduleTokenRefresh();
|
||||
|
||||
// show the user
|
||||
var user = getJwtSubject(jwt);
|
||||
var user = nf.Common.getJwtSubject(jwt);
|
||||
$('#nifi-user-submit-justification').text(user);
|
||||
|
||||
if (xhr.status === 401) {
|
||||
|
@ -189,33 +195,6 @@ nf.Login = (function () {
|
|||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Extracts the subject from the specified jwt. If the jwt is not as expected
|
||||
* an empty string is returned.
|
||||
*
|
||||
* @param {string} jwt
|
||||
* @returns {string}
|
||||
*/
|
||||
var getJwtSubject = function (jwt) {
|
||||
if (nf.Common.isDefinedAndNotNull(jwt)) {
|
||||
var segments = jwt.split(/\./);
|
||||
if (segments.length !== 3) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var rawPayload = $.base64.atob(segments[1]);
|
||||
var payload = JSON.parse(rawPayload);
|
||||
|
||||
if (nf.Common.isDefinedAndNotNull(payload['preferred_username'])) {
|
||||
return payload['preferred_username'];
|
||||
} else {
|
||||
'';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
};
|
||||
|
||||
var logout = function () {
|
||||
nf.Storage.removeItem('jwt');
|
||||
};
|
||||
|
@ -272,7 +251,7 @@ nf.Login = (function () {
|
|||
$('#login-message').text('Your account is active and you are already logged in.');
|
||||
}).fail(function (xhr, status, error) {
|
||||
if (xhr.status === 401) {
|
||||
var user = getJwtSubject(jwt);
|
||||
var user = nf.Common.getJwtSubject(jwt);
|
||||
|
||||
// show the user
|
||||
$('#nifi-user-submit-justification').text(user);
|
||||
|
@ -316,7 +295,7 @@ nf.Login = (function () {
|
|||
if (xhr.status === 401) {
|
||||
// attempt to get a token for the current user without passing login credentials
|
||||
token.done(function (jwt) {
|
||||
var user = getJwtSubject(jwt);
|
||||
var user = nf.Common.getJwtSubject(jwt);
|
||||
|
||||
// show the user
|
||||
$('#nifi-user-submit-justification').text(user);
|
||||
|
|
|
@ -74,10 +74,19 @@ $(document).ready(function () {
|
|||
nf.Storage.removeItem('jwt');
|
||||
window.location = '/nifi/login';
|
||||
});
|
||||
|
||||
// schedule token refresh when a token is present
|
||||
if (nf.Storage.getItem('jwt') !== null) {
|
||||
nf.Common.scheduleTokenRefresh();
|
||||
}
|
||||
});
|
||||
|
||||
// Define a common utility class used across the entire application.
|
||||
nf.Common = {
|
||||
nf.Common = (function () {
|
||||
// interval for cancelling token refresh when necessary
|
||||
var tokenRefreshInterval = null;
|
||||
|
||||
return {
|
||||
config: {
|
||||
sensitiveText: 'Sensitive value set',
|
||||
tooltipConfig: {
|
||||
|
@ -95,6 +104,9 @@ nf.Common = {
|
|||
at: 'top right',
|
||||
my: 'bottom left'
|
||||
}
|
||||
},
|
||||
urls: {
|
||||
token: '../nifi-api/token'
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -130,6 +142,106 @@ nf.Common = {
|
|||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Automatically refresh tokens by checking once an hour if its going to expire soon.
|
||||
*/
|
||||
scheduleTokenRefresh: function () {
|
||||
// if we are currently polling for token refresh, cancel it
|
||||
if (tokenRefreshInterval !== null) {
|
||||
clearInterval(tokenRefreshInterval);
|
||||
}
|
||||
|
||||
// set the interval to one hour
|
||||
var interval = nf.Common.MILLIS_PER_HOUR;
|
||||
|
||||
var checkExpiration = function () {
|
||||
var expiration = nf.Storage.getItemExpiration('jwt');
|
||||
|
||||
// ensure there is an expiration and token present
|
||||
if (expiration !== null) {
|
||||
var expirationDate = new Date(expiration);
|
||||
var now = new Date();
|
||||
|
||||
// get the time remainging plus a little bonus time to reload the token
|
||||
var timeRemaining = expirationDate.valueOf() - now.valueOf() - nf.Common.MILLIS_PER_MINUTE;
|
||||
if (timeRemaining < interval) {
|
||||
// if the token will expire before the next interval minus some bonus time, refresh now
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: nf.Common.config.urls.token
|
||||
}).done(function (jwt) {
|
||||
nf.Storage.setItem('jwt', jwt, nf.Common.getJwtExpiration(jwt));
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// perform initial check
|
||||
checkExpiration();
|
||||
|
||||
// schedule subsequent checks
|
||||
tokenRefreshInterval = setInterval(checkExpiration, interval);
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts the subject from the specified jwt. If the jwt is not as expected
|
||||
* an empty string is returned.
|
||||
*
|
||||
* @param {string} jwt
|
||||
* @returns {string}
|
||||
*/
|
||||
getJwtSubject: function (jwt) {
|
||||
if (nf.Common.isDefinedAndNotNull(jwt)) {
|
||||
var segments = jwt.split(/\./);
|
||||
if (segments.length !== 3) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var rawPayload = $.base64.atob(segments[1]);
|
||||
var payload = JSON.parse(rawPayload);
|
||||
|
||||
if (nf.Common.isDefinedAndNotNull(payload['preferred_username'])) {
|
||||
return payload['preferred_username'];
|
||||
} else {
|
||||
'';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts the expiration from the specified jwt. If the jwt is not as expected
|
||||
* a null value is returned.
|
||||
*
|
||||
* @param {string} jwt
|
||||
* @returns {integer}
|
||||
*/
|
||||
getJwtExpiration: function (jwt) {
|
||||
if (nf.Common.isDefinedAndNotNull(jwt)) {
|
||||
var segments = jwt.split(/\./);
|
||||
if (segments.length !== 3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var rawPayload = $.base64.atob(segments[1]);
|
||||
var payload = JSON.parse(rawPayload);
|
||||
|
||||
if (nf.Common.isDefinedAndNotNull(payload['exp'])) {
|
||||
try {
|
||||
// jwt exp is in seconds
|
||||
return parseInt(payload['exp'], 10) * nf.Common.MILLIS_PER_SECOND;
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether the current user can access provenance.
|
||||
*
|
||||
|
@ -205,16 +317,6 @@ nf.Common = {
|
|||
* @argument {string} error The error
|
||||
*/
|
||||
handleAjaxError: function (xhr, status, error) {
|
||||
// show the account registration page if necessary
|
||||
// if (xhr.status === 401 && $('#registration-pane').length) {
|
||||
// // show the registration pane
|
||||
// $('#registration-pane').show();
|
||||
//
|
||||
// // close the canvas
|
||||
// nf.Common.closeCanvas();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if an error occurs while the splash screen is visible close the canvas show the error message
|
||||
if ($('#splash').is(':visible')) {
|
||||
if (xhr.status === 401) {
|
||||
|
@ -1022,4 +1124,5 @@ nf.Common = {
|
|||
});
|
||||
return formattedBulletins;
|
||||
}
|
||||
};
|
||||
};
|
||||
}());
|
||||
|
|
|
@ -20,7 +20,61 @@
|
|||
nf.Storage = (function () {
|
||||
|
||||
// Store items for two days before being eligible for removal.
|
||||
var TWO_DAYS = 86400000 * 2;
|
||||
var TWO_DAYS = nf.Common.MILLIS_PER_DAY * 2;
|
||||
|
||||
/**
|
||||
* Checks the expiration for the specified entry.
|
||||
*
|
||||
* @param {object} entry
|
||||
* @returns {boolean}
|
||||
*/
|
||||
var checkExpiration = function (entry) {
|
||||
if (nf.Common.isDefinedAndNotNull(entry.expires)) {
|
||||
// get the expiration
|
||||
var expires = new Date(entry.expires);
|
||||
var now = new Date();
|
||||
|
||||
// return whether the expiration date has passed
|
||||
return expires.valueOf() < now.valueOf();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* If the item at key is not expired, the value of field is returned. Otherwise, null.
|
||||
*
|
||||
* @param {string} key
|
||||
* @param {string} field
|
||||
* @return {object} the value
|
||||
*/
|
||||
var getEntryField = function (key, field) {
|
||||
try {
|
||||
// parse the entry
|
||||
var entry = JSON.parse(localStorage.getItem(key));
|
||||
|
||||
// ensure the entry and item are present
|
||||
if (nf.Common.isDefinedAndNotNull(entry)) {
|
||||
|
||||
// if the entry is expired, drop it and return null
|
||||
if (checkExpiration(entry)) {
|
||||
nf.Storage.removeItem(key);
|
||||
return null;
|
||||
}
|
||||
|
||||
// if the entry has the specified field return its value
|
||||
if (nf.Common.isDefinedAndNotNull(entry[field])) {
|
||||
return entry[field];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
/**
|
||||
|
@ -34,16 +88,10 @@ nf.Storage = (function () {
|
|||
var key = localStorage.key(i);
|
||||
var entry = JSON.parse(localStorage.getItem(key));
|
||||
|
||||
// get the expiration
|
||||
var expires = new Date(entry.expires);
|
||||
var now = new Date();
|
||||
|
||||
// if the expiration date has passed, remove it
|
||||
if (expires.valueOf() < now.valueOf()) {
|
||||
localStorage.removeItem(key);
|
||||
if (checkExpiration(entry)) {
|
||||
nf.Storage.removeItem(key);
|
||||
}
|
||||
} catch (e) {
|
||||
// likely unable to parse the item
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -51,12 +99,13 @@ nf.Storage = (function () {
|
|||
/**
|
||||
* Stores the specified item.
|
||||
*
|
||||
* @param {type} key
|
||||
* @param {type} item
|
||||
* @param {string} key
|
||||
* @param {object} item
|
||||
* @param {integer} expires
|
||||
*/
|
||||
setItem: function (key, item) {
|
||||
setItem: function (key, item, expires) {
|
||||
// calculate the expiration
|
||||
var expires = new Date().valueOf() + TWO_DAYS;
|
||||
expires = nf.Common.isDefinedAndNotNull(expires) ? expires : new Date().valueOf() + TWO_DAYS;
|
||||
|
||||
// create the entry
|
||||
var entry = {
|
||||
|
@ -76,19 +125,18 @@ nf.Storage = (function () {
|
|||
* @param {type} key
|
||||
*/
|
||||
getItem: function (key) {
|
||||
try {
|
||||
// parse the entry
|
||||
var entry = JSON.parse(localStorage.getItem(key));
|
||||
return getEntryField(key, 'item');
|
||||
},
|
||||
|
||||
// ensure the entry and item are present
|
||||
if (nf.Common.isDefinedAndNotNull(entry) && nf.Common.isDefinedAndNotNull(entry.item)) {
|
||||
return entry.item;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Gets the expiration for the specified item. If the item does not exists our could
|
||||
* not be parsed, returns null.
|
||||
*
|
||||
* @param {string} key
|
||||
* @returns {integer}
|
||||
*/
|
||||
getItemExpiration: function (key) {
|
||||
return getEntryField(key, 'expires');
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue