You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2019/08/16 14:59:30 UTC

[nifi-registry] branch master updated (e067555 -> ab77e26)

This is an automated email from the ASF dual-hosted git repository.

bbende pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-registry.git.


    from e067555  NIFIREG-289 - UI - isolate webpack loaders used specifically for code coverage purposes
     new 18ed285  NIFIREG-295 Add support for proxying via Apache Knox - Changed absolute path to relative path - Use relative path to call NiFi Registry APIs - Set base href dynamically to support deep links - Fixed broken tests. - Revert changes to template.dev.html. - Fixed link from help icon.
     new a110588  NIFIREG-295 - use hash for routing
     new ab77e26  NIFIREG-295 - change canActivate guards to use promises

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../administration/nf-registry-administration.js   |   2 +-
 .../users/nf-registry-users-administration.js      |   8 +-
 .../manage-group/nf-registry-manage-group.js       |   6 +-
 .../manage-group/nf-registry-manage-group.spec.js  |   6 +-
 .../sidenav/manage-user/nf-registry-manage-user.js |   6 +-
 .../manage-user/nf-registry-manage-user.spec.js    |   6 +-
 .../manage-bucket/nf-registry-manage-bucket.js     |   4 +-
 .../nf-registry-manage-bucket.spec.js              |   4 +-
 .../nf-registry-bucket-grid-list-viewer.js         |   8 +-
 .../nf-registry-bucket-grid-list-viewer.spec.js    |   2 +-
 .../nf-registry-droplet-grid-list-viewer.js        |   6 +-
 .../nf-registry-droplet-grid-list-viewer.spec.js   |   2 +-
 .../src/main/webapp/nf-registry-bootstrap.js       |   2 +-
 .../src/main/webapp/nf-registry.html               |  18 +-
 .../src/main/webapp/nf-registry.js                 |   4 +-
 .../src/main/webapp/nf-registry.routes.js          |  16 +-
 .../src/main/webapp/services/nf-registry.api.js    |  56 ++--
 .../main/webapp/services/nf-registry.api.spec.js   | 246 +++++++--------
 .../services/nf-registry.auth-guard.service.js     | 334 ++++++++++++---------
 .../nf-registry.auth-guard.service.spec.js         | 320 +++++++++++---------
 .../main/webapp/services/nf-registry.service.js    |  10 +-
 .../webapp/services/nf-registry.service.spec.js    |   6 +-
 .../src/main/webapp/template.dev.html              |   1 -
 .../src/main/webapp/template.html                  |   1 -
 .../main/webapp/theming/_structureElements.scss    |   6 +-
 .../src/main/webpack.common.js                     |   3 +-
 .../nifi-registry-web-ui/src/main/webpack.dev.js   |   3 -
 27 files changed, 576 insertions(+), 510 deletions(-)


[nifi-registry] 03/03: NIFIREG-295 - change canActivate guards to use promises

Posted by bb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bbende pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-registry.git

commit ab77e2644570075b78063a6d6999ee59adcc7a2f
Author: Rob Fellows <ro...@gmail.com>
AuthorDate: Thu Aug 15 14:54:58 2019 -0400

    NIFIREG-295 - change canActivate guards to use promises
    
    This closes #211.
    
    Signed-off-by: Bryan Bende <bb...@apache.org>
---
 .../services/nf-registry.auth-guard.service.js     | 328 ++++++++++++---------
 .../nf-registry.auth-guard.service.spec.js         | 320 +++++++++++---------
 2 files changed, 360 insertions(+), 288 deletions(-)

diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
index ca3c1d0..e04bf4e 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
@@ -54,40 +54,72 @@ NfRegistryUsersAdministrationAuthGuard.prototype = {
 
     checkLogin: function (url) {
         var self = this;
-        if (this.nfRegistryService.currentUser.resourcePermissions.tenants.canRead) { return true; }
-
-        // Store the attempted URL for redirecting
-        this.nfRegistryService.redirectUrl = url;
-
-        // attempt kerberos authentication
-        this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
-            self.nfRegistryApi.loadCurrentUser().subscribe(function (currentUser) {
-                // there is no anonymous access and we don't know this user - open the login page which handles login/registration/etc
-                if (currentUser.error) {
-                    if (currentUser.error.status === 401) {
-                        self.nfStorage.removeItem('jwt');
-                        self.router.navigateByUrl('login');
-                    }
-                } else {
-                    self.nfRegistryService.currentUser = currentUser;
-                    if (currentUser.anonymous === false) {
-                        // render the logout button if there is a token locally
-                        if (self.nfStorage.getItem('jwt') !== null) {
-                            self.nfRegistryService.currentUser.canLogout = true;
+        return new Promise((resolve) => {
+            if (this.nfRegistryService.currentUser.resourcePermissions.tenants.canRead) {
+                resolve(true);
+                return true;
+            }
+
+            // Store the attempted URL for redirecting
+            this.nfRegistryService.redirectUrl = url;
+
+            // attempt kerberos authentication
+            this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
+                self.nfRegistryApi.loadCurrentUser().subscribe(function (currentUser) {
+                    // there is no anonymous access and we don't know this user - open the login page which handles login/registration/etc
+                    if (currentUser.error) {
+                        if (currentUser.error.status === 401) {
+                            self.nfStorage.removeItem('jwt');
+                            self.router.navigateByUrl('login');
+                            resolve(false);
                         }
-
-                        // redirect to explorer perspective if not admin
-                        if (!currentUser.resourcePermissions.anyTopLevelResource.canRead) {
+                    } else {
+                        self.nfRegistryService.currentUser = currentUser;
+                        if (currentUser.anonymous === false) {
+                            // render the logout button if there is a token locally
+                            if (self.nfStorage.getItem('jwt') !== null) {
+                                self.nfRegistryService.currentUser.canLogout = true;
+                            }
+
+                            // redirect to explorer perspective if not admin
+                            if (!currentUser.resourcePermissions.anyTopLevelResource.canRead) {
+                                self.dialogService.openConfirm({
+                                    title: 'Access denied',
+                                    message: 'Please contact your system administrator.',
+                                    acceptButton: 'Ok',
+                                    acceptButtonColor: 'fds-warn'
+                                });
+                                self.router.navigateByUrl('explorer');
+                                resolve(false);
+                            } else if (currentUser.resourcePermissions.tenants.canRead) {
+                                resolve(true);
+                            } else {
+                                self.dialogService.openConfirm({
+                                    title: 'Access denied',
+                                    message: 'Please contact your system administrator.',
+                                    acceptButton: 'Ok',
+                                    acceptButtonColor: 'fds-warn'
+                                });
+                                self.router.navigateByUrl('explorer');
+                                resolve(false);
+                            }
+                        } else if (location.protocol === 'http:') {
+                            // user is anonymous and we are NOT secure, redirect to workflow perspective
                             self.dialogService.openConfirm({
-                                title: 'Access denied',
-                                message: 'Please contact your system administrator.',
+                                title: 'Not Applicable',
+                                message: 'User administration is not configured for this registry.',
                                 acceptButton: 'Ok',
                                 acceptButtonColor: 'fds-warn'
                             });
-                            self.router.navigateByUrl('explorer');
-                        } else if (currentUser.resourcePermissions.tenants.canRead) {
-                            self.router.navigateByUrl(url);
+                            self.router.navigateByUrl('administration/workflow');
+                            resolve(false);
                         } else {
+                            if (self.nfRegistryService.currentUser.resourcePermissions.tenants.canRead) {
+                                resolve(true);
+                                return true;
+                            }
+
+                            // user is anonymous and we are secure so don't allow the url, navigate to the main page
                             self.dialogService.openConfirm({
                                 title: 'Access denied',
                                 message: 'Please contact your system administrator.',
@@ -95,31 +127,12 @@ NfRegistryUsersAdministrationAuthGuard.prototype = {
                                 acceptButtonColor: 'fds-warn'
                             });
                             self.router.navigateByUrl('explorer');
+                            resolve(false);
                         }
-                    } else if (location.protocol === 'http:') {
-                        // user is anonymous and we are NOT secure, redirect to workflow perspective
-                        self.dialogService.openConfirm({
-                            title: 'Not Applicable',
-                            message: 'User administration is not configured for this registry.',
-                            acceptButton: 'Ok',
-                            acceptButtonColor: 'fds-warn'
-                        });
-                        self.router.navigateByUrl('administration/workflow');
-                    } else {
-                        // user is anonymous and we are secure so don't allow the url, navigate to the main page
-                        self.dialogService.openConfirm({
-                            title: 'Access denied',
-                            message: 'Please contact your system administrator.',
-                            acceptButton: 'Ok',
-                            acceptButtonColor: 'fds-warn'
-                        });
-                        self.router.navigateByUrl('explorer');
                     }
-                }
+                });
             });
         });
-
-        return false;
     }
 };
 
@@ -164,30 +177,65 @@ NfRegistryWorkflowsAdministrationAuthGuard.prototype = {
 
     checkLogin: function (url) {
         var self = this;
-        if (this.nfRegistryService.currentUser.resourcePermissions.buckets.canRead) { return true; }
-
-        // Store the attempted URL for redirecting
-        this.nfRegistryService.redirectUrl = url;
-
-        // attempt kerberos authentication
-        this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
-            self.nfRegistryApi.loadCurrentUser().subscribe(function (currentUser) {
-                // there is no anonymous access and we don't know this user - open the login page which handles login/registration/etc
-                if (currentUser.error) {
-                    if (currentUser.error.status === 401) {
-                        self.nfStorage.removeItem('jwt');
-                        self.router.navigateByUrl('login');
-                    }
-                } else {
-                    self.nfRegistryService.currentUser = currentUser;
-                    if (currentUser.anonymous === false) {
-                        // render the logout button if there is a token locally
-                        if (self.nfStorage.getItem('jwt') !== null) {
-                            self.nfRegistryService.currentUser.canLogout = true;
+        return new Promise((resolve) => {
+            if (this.nfRegistryService.currentUser.resourcePermissions.buckets.canRead) {
+                resolve(true);
+                return;
+            }
+
+            // Store the attempted URL for redirecting
+            this.nfRegistryService.redirectUrl = url;
+
+            // attempt kerberos authentication
+            this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
+                self.nfRegistryApi.loadCurrentUser().subscribe(function (currentUser) {
+                    // there is no anonymous access and we don't know this user - open the login page which handles login/registration/etc
+                    if (currentUser.error) {
+                        if (currentUser.error.status === 401) {
+                            self.nfStorage.removeItem('jwt');
+                            self.router.navigateByUrl('login');
+                            resolve(false);
                         }
+                    } else {
+                        self.nfRegistryService.currentUser = currentUser;
+                        if (currentUser.anonymous === false) {
+                            // render the logout button if there is a token locally
+                            if (self.nfStorage.getItem('jwt') !== null) {
+                                self.nfRegistryService.currentUser.canLogout = true;
+                            }
+
+                            // redirect to explorer perspective if not admin
+                            if (!currentUser.resourcePermissions.anyTopLevelResource.canRead) {
+                                self.dialogService.openConfirm({
+                                    title: 'Access denied',
+                                    message: 'Please contact your system administrator.',
+                                    acceptButton: 'Ok',
+                                    acceptButtonColor: 'fds-warn'
+                                });
+                                self.router.navigateByUrl('explorer');
+                                resolve(false);
+                            } else if (currentUser.resourcePermissions.buckets.canRead) {
+                                resolve(true);
+                            } else {
+                                self.dialogService.openConfirm({
+                                    title: 'Access denied',
+                                    message: 'Please contact your system administrator.',
+                                    acceptButton: 'Ok',
+                                    acceptButtonColor: 'fds-warn'
+                                });
+                                self.router.navigateByUrl('explorer');
+                                resolve(false);
+                            }
+                        } else if (location.protocol === 'http:') {
+                            // user is anonymous and we are NOT secure so allow the url
+                            resolve(true);
+                        } else {
+                            if (self.nfRegistryService.currentUser.resourcePermissions.buckets.canRead) {
+                                resolve(true);
+                                return;
+                            }
 
-                        // redirect to explorer perspective if not admin
-                        if (!currentUser.resourcePermissions.anyTopLevelResource.canRead) {
+                            // user is anonymous and we are secure so don't allow the url, navigate to the main page
                             self.dialogService.openConfirm({
                                 title: 'Access denied',
                                 message: 'Please contact your system administrator.',
@@ -195,35 +243,12 @@ NfRegistryWorkflowsAdministrationAuthGuard.prototype = {
                                 acceptButtonColor: 'fds-warn'
                             });
                             self.router.navigateByUrl('explorer');
-                        } else if (currentUser.resourcePermissions.buckets.canRead) {
-                            self.router.navigateByUrl(url);
-                        } else {
-                            self.dialogService.openConfirm({
-                                title: 'Access denied',
-                                message: 'Please contact your system administrator.',
-                                acceptButton: 'Ok',
-                                acceptButtonColor: 'fds-warn'
-                            });
-                            self.router.navigateByUrl('administration/users');
+                            resolve(false);
                         }
-                    } else if (location.protocol === 'http:') {
-                        // user is anonymous and we are NOT secure so allow the url
-                        self.router.navigateByUrl(url);
-                    } else {
-                        // user is anonymous and we are secure so don't allow the url, navigate to the main page
-                        self.dialogService.openConfirm({
-                            title: 'Access denied',
-                            message: 'Please contact your system administrator.',
-                            acceptButton: 'Ok',
-                            acceptButtonColor: 'fds-warn'
-                        });
-                        self.router.navigateByUrl('explorer');
                     }
-                }
+                });
             });
         });
-
-        return false;
     }
 };
 
@@ -266,28 +291,33 @@ NfRegistryLoginAuthGuard.prototype = {
 
     checkLogin: function (url) {
         var self = this;
-        if (this.nfRegistryService.currentUser.anonymous) { return true; }
-        // attempt kerberos authentication
-        this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
-            self.nfRegistryApi.loadCurrentUser().subscribe(function (currentUser) {
-                self.nfRegistryService.currentUser = currentUser;
-                if (currentUser.anonymous === false) {
-                    // render the logout button if there is a token locally
-                    if (self.nfStorage.getItem('jwt') !== null) {
-                        self.nfRegistryService.currentUser.canLogout = true;
+        return new Promise((resolve) => {
+            if (this.nfRegistryService.currentUser.anonymous) {
+                resolve(true);
+                return;
+            }
+            // attempt kerberos authentication
+            this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
+                self.nfRegistryApi.loadCurrentUser().subscribe(function (currentUser) {
+                    self.nfRegistryService.currentUser = currentUser;
+                    if (currentUser.anonymous === false) {
+                        // render the logout button if there is a token locally
+                        if (self.nfStorage.getItem('jwt') !== null) {
+                            self.nfRegistryService.currentUser.canLogout = true;
+                        }
+                        self.nfRegistryService.currentUser.canActivateResourcesAuthGuard = true;
+                        resolve(false);
+                        self.router.navigateByUrl(self.nfRegistryService.redirectUrl);
+                    } else if (self.nfRegistryService.currentUser.anonymous && !self.nfRegistryService.currentUser.loginSupported) {
+                        resolve(false);
+                        self.router.navigateByUrl('/nifi-registry');
+                    } else {
+                        self.nfRegistryService.currentUser.anonymous = true;
+                        resolve(true);
                     }
-                    self.nfRegistryService.currentUser.canActivateResourcesAuthGuard = true;
-                    self.router.navigateByUrl(self.nfRegistryService.redirectUrl);
-                } else if (self.nfRegistryService.currentUser.anonymous && !self.nfRegistryService.currentUser.loginSupported) {
-                    self.router.navigateByUrl('/nifi-registry');
-                } else {
-                    self.nfRegistryService.currentUser.anonymous = true;
-                    self.router.navigateByUrl(url);
-                }
+                });
             });
         });
-
-        return false;
     }
 };
 
@@ -323,49 +353,53 @@ NfRegistryResourcesAuthGuard.prototype = {
      */
     canActivate: function (route, state) {
         var url = state.url;
-
         return this.checkLogin(url);
     },
 
     checkLogin: function (url) {
         var self = this;
-        if (this.nfRegistryService.currentUser.canActivateResourcesAuthGuard === true) { return true; }
-
-        // Store the attempted URL for redirecting
-        this.nfRegistryService.redirectUrl = url;
-
-        // attempt kerberos authentication
-        this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
-            self.nfRegistryApi.loadCurrentUser().subscribe(function (currentUser) {
-                // there is no anonymous access and we don't know this user - open the login page which handles login/registration/etc
-                if (currentUser.error) {
-                    if (currentUser.error.status === 401) {
-                        self.nfStorage.removeItem('jwt');
-                        self.router.navigateByUrl('login');
-                    }
-                } else {
-                    self.nfRegistryService.currentUser = currentUser;
-                    if (!currentUser || currentUser.anonymous === false) {
-                        if (self.nfStorage.hasItem('jwt')) {
-                            self.nfRegistryService.currentUser.canLogout = true;
-                            self.nfRegistryService.currentUser.canActivateResourcesAuthGuard = true;
-                            self.router.navigateByUrl(url);
-                        } else {
+        return new Promise((resolve) => {
+            if (this.nfRegistryService.currentUser.canActivateResourcesAuthGuard === true) {
+                resolve(true);
+                return;
+            }
+
+            // Store the attempted URL for redirecting
+            this.nfRegistryService.redirectUrl = url;
+
+            // attempt kerberos authentication
+            this.nfRegistryApi.ticketExchange().subscribe(function (jwt) {
+                self.nfRegistryApi.loadCurrentUser().subscribe(function (currentUser) {
+                    // there is no anonymous access and we don't know this user - open the login page which handles login/registration/etc
+                    if (currentUser.error) {
+                        if (currentUser.error.status === 401) {
+                            self.nfStorage.removeItem('jwt');
                             self.router.navigateByUrl('login');
+                            resolve(false);
                         }
-                    } else if (currentUser.anonymous === true) {
-                        // render the logout button if there is a token locally
-                        if (self.nfStorage.getItem('jwt') !== null) {
-                            self.nfRegistryService.currentUser.canLogout = true;
+                    } else {
+                        self.nfRegistryService.currentUser = currentUser;
+                        if (!currentUser || currentUser.anonymous === false) {
+                            if (self.nfStorage.hasItem('jwt')) {
+                                self.nfRegistryService.currentUser.canLogout = true;
+                                self.nfRegistryService.currentUser.canActivateResourcesAuthGuard = true;
+                                resolve(true);
+                            } else {
+                                self.router.navigateByUrl('login');
+                                resolve(false);
+                            }
+                        } else if (currentUser.anonymous === true) {
+                            // render the logout button if there is a token locally
+                            if (self.nfStorage.getItem('jwt') !== null) {
+                                self.nfRegistryService.currentUser.canLogout = true;
+                            }
+                            self.nfRegistryService.currentUser.canActivateResourcesAuthGuard = true;
+                            resolve(true);
                         }
-                        self.nfRegistryService.currentUser.canActivateResourcesAuthGuard = true;
-                        self.router.navigateByUrl(url);
                     }
-                }
+                });
             });
         });
-
-        return false;
     }
 };
 
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.spec.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.spec.js
index a656518..94fbf7f 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.spec.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.spec.js
@@ -58,7 +58,7 @@ describe('NfRegistry Auth Guard Service NfRegistryResourcesAuthGuard isolated un
         spyOn(dialogService, 'openConfirm');
     });
 
-    it('should navigate to test url (registry security not configured) ', function () {
+    it('should navigate to test url (registry security not configured) ', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: true
@@ -69,17 +69,18 @@ describe('NfRegistry Auth Guard Service NfRegistryResourcesAuthGuard isolated un
         nfRegistryResourcesAuthGuard = new NfRegistryResourcesAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router);
 
         // The function to test
-        nfRegistryResourcesAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.currentUser.canLogout).toBe(true);
-        expect(nfRegistryService.currentUser.canActivateResourcesAuthGuard).toBe(true);
-        expect(nfRegistryService.currentUser.anonymous).toBe(true);
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('test');
+        nfRegistryResourcesAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(nfRegistryService.currentUser.canLogout).toBe(true);
+                expect(nfRegistryService.currentUser.canActivateResourcesAuthGuard).toBe(true);
+                expect(nfRegistryService.currentUser.anonymous).toBe(true);
+                expect(canActivate).toBe(true);
+                done();
+            });
     });
 
-    it('should navigate to test url (registry security configured and we know who you are) ', function () {
+    it('should navigate to test url (registry security configured and we know who you are) ', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: false
@@ -90,16 +91,17 @@ describe('NfRegistry Auth Guard Service NfRegistryResourcesAuthGuard isolated un
         nfRegistryResourcesAuthGuard = new NfRegistryResourcesAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router);
 
         // The function to test
-        nfRegistryResourcesAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.currentUser.canLogout).toBe(true);
-        expect(nfRegistryService.currentUser.canActivateResourcesAuthGuard).toBe(true);
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('test');
+        nfRegistryResourcesAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(nfRegistryService.currentUser.canLogout).toBe(true);
+                expect(nfRegistryService.currentUser.canActivateResourcesAuthGuard).toBe(true);
+                expect(canActivate).toBe(true);
+                done();
+            });
     });
 
-    it('should navigate to login', function () {
+    it('should navigate to login', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: false
@@ -108,31 +110,37 @@ describe('NfRegistry Auth Guard Service NfRegistryResourcesAuthGuard isolated un
         nfRegistryResourcesAuthGuard = new NfRegistryResourcesAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router);
 
         // The function to test
-        nfRegistryResourcesAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('login');
+        nfRegistryResourcesAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('login');
+                done();
+            });
     });
 
-    it('should navigate to login (error loading current user)', function () {
+    it('should navigate to login (error loading current user)', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             error: {
                 status: 401
             }
         }));
-        spyOn(nfStorage, 'removeItem');
+        spyOn(nfStorage, 'removeItem').and.callFake(() => {});
 
         nfRegistryResourcesAuthGuard = new NfRegistryResourcesAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryResourcesAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfStorage.removeItem).toHaveBeenCalled();
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('login');
+        nfRegistryResourcesAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfStorage.removeItem).toHaveBeenCalled();
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('login');
+                done();
+            });
     });
 });
 
@@ -169,7 +177,7 @@ describe('NfRegistry Auth Guard Service NfRegistryLoginAuthGuard isolated unit t
         spyOn(dialogService, 'openConfirm');
     });
 
-    it('should navigate to base nifi-registry url', function () {
+    it('should navigate to base nifi-registry url', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: true
@@ -177,15 +185,18 @@ describe('NfRegistry Auth Guard Service NfRegistryLoginAuthGuard isolated unit t
         nfRegistryLoginAuthGuard = new NfRegistryLoginAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router);
 
         // The function to test
-        nfRegistryLoginAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.currentUser.anonymous).toBe(true);
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry');
+        nfRegistryLoginAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.currentUser.anonymous).toBe(true);
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('/nifi-registry');
+                done();
+            });
     });
 
-    it('should navigate to test url', function () {
+    it('should navigate to test url', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: false
@@ -193,12 +204,15 @@ describe('NfRegistry Auth Guard Service NfRegistryLoginAuthGuard isolated unit t
         nfRegistryLoginAuthGuard = new NfRegistryLoginAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router);
 
         // The function to test
-        nfRegistryLoginAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.currentUser.canActivateResourcesAuthGuard).toBe(true);
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('explorer/grid-list');
+        nfRegistryLoginAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.currentUser.canActivateResourcesAuthGuard).toBe(true);
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('explorer/grid-list');
+                done();
+            });
     });
 });
 
@@ -235,7 +249,7 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         spyOn(dialogService, 'openConfirm');
     });
 
-    it('should navigate to login', function () {
+    it('should navigate to login', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             error: {
@@ -245,15 +259,18 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         nfRegistryUsersAdministrationAuthGuard = new NfRegistryUsersAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('login');
+        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.redirectUrl).toBe('test');
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('login');
+                done();
+            });
     });
 
-    it('should deny access (registry security not configured) and navigate to administration workflow perspective', function () {
+    it('should deny access (registry security not configured) and navigate to administration workflow perspective', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: true
@@ -261,20 +278,23 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         nfRegistryUsersAdministrationAuthGuard = new NfRegistryUsersAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var dialogServiceCall = dialogService.openConfirm.calls.first();
-        expect(dialogServiceCall.args[0].title).toBe('Not Applicable');
-        expect(dialogServiceCall.args[0].message).toBe('User administration is not configured for this registry.');
-        expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
-        expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('administration/workflow');
+        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.redirectUrl).toBe('test');
+                var dialogServiceCall = dialogService.openConfirm.calls.first();
+                expect(dialogServiceCall.args[0].title).toBe('Not Applicable');
+                expect(dialogServiceCall.args[0].message).toBe('User administration is not configured for this registry.');
+                expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
+                expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('administration/workflow');
+                done();
+            });
     });
 
-    it('should deny access (non-admin) and navigate to explorer perspective', function () {
+    it('should deny access (non-admin) and navigate to explorer perspective', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: false,
@@ -309,20 +329,23 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         nfRegistryUsersAdministrationAuthGuard = new NfRegistryUsersAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var dialogServiceCall = dialogService.openConfirm.calls.first();
-        expect(dialogServiceCall.args[0].title).toBe('Access denied');
-        expect(dialogServiceCall.args[0].message).toBe('Please contact your system administrator.');
-        expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
-        expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('explorer');
+        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.redirectUrl).toBe('test');
+                var dialogServiceCall = dialogService.openConfirm.calls.first();
+                expect(dialogServiceCall.args[0].title).toBe('Access denied');
+                expect(dialogServiceCall.args[0].message).toBe('Please contact your system administrator.');
+                expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
+                expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('explorer');
+                done();
+            });
     });
 
-    it('should deny access (no tenants permissions) and navigate to explorer perspective', function () {
+    it('should deny access (no tenants permissions) and navigate to explorer perspective', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: false,
@@ -357,20 +380,23 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         nfRegistryUsersAdministrationAuthGuard = new NfRegistryUsersAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var dialogServiceCall = dialogService.openConfirm.calls.first();
-        expect(dialogServiceCall.args[0].title).toBe('Access denied');
-        expect(dialogServiceCall.args[0].message).toBe('Please contact your system administrator.');
-        expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
-        expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('explorer');
+        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.redirectUrl).toBe('test');
+                var dialogServiceCall = dialogService.openConfirm.calls.first();
+                expect(dialogServiceCall.args[0].title).toBe('Access denied');
+                expect(dialogServiceCall.args[0].message).toBe('Please contact your system administrator.');
+                expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
+                expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('explorer');
+                done();
+            });
     });
 
-    it('should deny access (no tenants permissions) and navigate to test url', function () {
+    it('should deny access (no tenants permissions) and navigate to explorer url', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: false,
@@ -386,7 +412,7 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
                     canDelete: false
                 },
                 tenants: {
-                    canRead: true,
+                    canRead: false,
                     canWrite: false,
                     canDelete: false
                 },
@@ -405,12 +431,15 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         nfRegistryUsersAdministrationAuthGuard = new NfRegistryUsersAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('test');
+        nfRegistryUsersAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.redirectUrl).toBe('test');
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('explorer');
+                done();
+            });
     });
 });
 
@@ -447,7 +476,7 @@ describe('NfRegistry Auth Guard Service NfRegistryWorkflowsAdministrationAuthGua
         spyOn(dialogService, 'openConfirm');
     });
 
-    it('should navigate to login', function () {
+    it('should navigate to login', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             error: {
@@ -457,15 +486,18 @@ describe('NfRegistry Auth Guard Service NfRegistryWorkflowsAdministrationAuthGua
         nfRegistryWorkflowsAdministrationAuthGuard = new NfRegistryWorkflowsAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('login');
+        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.redirectUrl).toBe('test');
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('login');
+                done();
+            });
     });
 
-    it('should (registry security not configured) navigate to test url', function () {
+    it('should (registry security not configured) navigate to test url', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: true
@@ -473,15 +505,15 @@ describe('NfRegistry Auth Guard Service NfRegistryWorkflowsAdministrationAuthGua
         nfRegistryWorkflowsAdministrationAuthGuard = new NfRegistryWorkflowsAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('test');
+        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(true);
+                done();
+            });
     });
 
-    it('should deny access (non-admin) and navigate to explorer perspective', function () {
+    it('should deny access (non-admin) and navigate to explorer perspective', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: false,
@@ -516,20 +548,23 @@ describe('NfRegistry Auth Guard Service NfRegistryWorkflowsAdministrationAuthGua
         nfRegistryWorkflowsAdministrationAuthGuard = new NfRegistryWorkflowsAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var dialogServiceCall = dialogService.openConfirm.calls.first();
-        expect(dialogServiceCall.args[0].title).toBe('Access denied');
-        expect(dialogServiceCall.args[0].message).toBe('Please contact your system administrator.');
-        expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
-        expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('explorer');
+        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.redirectUrl).toBe('test');
+                var dialogServiceCall = dialogService.openConfirm.calls.first();
+                expect(dialogServiceCall.args[0].title).toBe('Access denied');
+                expect(dialogServiceCall.args[0].message).toBe('Please contact your system administrator.');
+                expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
+                expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('explorer');
+                done();
+            });
     });
 
-    it('should deny access (no buckets permissions) and navigate to users administration perspective', function () {
+    it('should deny access (no buckets permissions) and navigate to users administration perspective', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: false,
@@ -564,20 +599,23 @@ describe('NfRegistry Auth Guard Service NfRegistryWorkflowsAdministrationAuthGua
         nfRegistryWorkflowsAdministrationAuthGuard = new NfRegistryWorkflowsAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var dialogServiceCall = dialogService.openConfirm.calls.first();
-        expect(dialogServiceCall.args[0].title).toBe('Access denied');
-        expect(dialogServiceCall.args[0].message).toBe('Please contact your system administrator.');
-        expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
-        expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('administration/users');
+        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(false);
+                expect(nfRegistryService.redirectUrl).toBe('test');
+                var dialogServiceCall = dialogService.openConfirm.calls.first();
+                expect(dialogServiceCall.args[0].title).toBe('Access denied');
+                expect(dialogServiceCall.args[0].message).toBe('Please contact your system administrator.');
+                expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
+                expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
+                var navigateByUrlCall = router.navigateByUrl.calls.first();
+                expect(navigateByUrlCall.args[0]).toBe('explorer');
+                done();
+            });
     });
 
-    it('should deny access (no tenants permissions) and navigate to test url', function () {
+    it('should (no tenants permissions) navigate to test url', function (done) {
         spyOn(nfRegistryApi, 'loadCurrentUser').and.callFake(function () {
         }).and.returnValue(of({
             anonymous: false,
@@ -612,11 +650,11 @@ describe('NfRegistry Auth Guard Service NfRegistryWorkflowsAdministrationAuthGua
         nfRegistryWorkflowsAdministrationAuthGuard = new NfRegistryWorkflowsAdministrationAuthGuard(nfRegistryService, nfRegistryApi, nfStorage, router, dialogService);
 
         // The function to test
-        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'});
-
-        //assertions
-        expect(nfRegistryService.redirectUrl).toBe('test');
-        var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('test');
+        nfRegistryWorkflowsAdministrationAuthGuard.canActivate({}, {url: 'test'})
+            .then((canActivate) => {
+                //assertions
+                expect(canActivate).toBe(true);
+                done();
+            });
     });
 });


[nifi-registry] 01/03: NIFIREG-295 Add support for proxying via Apache Knox - Changed absolute path to relative path - Use relative path to call NiFi Registry APIs - Set base href dynamically to support deep links - Fixed broken tests. - Revert changes to template.dev.html. - Fixed link from help icon.

Posted by bb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bbende pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-registry.git

commit 18ed285b11a35ec3a883e915cb74b963ec06c9a1
Author: Koji Kawamura <ij...@gmail.com>
AuthorDate: Wed Aug 7 14:02:46 2019 +0900

    NIFIREG-295 Add support for proxying via Apache Knox
    - Changed absolute path to relative path
    - Use relative path to call NiFi Registry APIs
    - Set base href dynamically to support deep links
    - Fixed broken tests.
    - Revert changes to template.dev.html.
    - Fixed link from help icon.
    
    Signed-off-by: Bryan Bende <bb...@apache.org>
---
 .../administration/nf-registry-administration.js   |   2 +-
 .../users/nf-registry-users-administration.js      |   8 +-
 .../manage-group/nf-registry-manage-group.js       |   6 +-
 .../manage-group/nf-registry-manage-group.spec.js  |   6 +-
 .../sidenav/manage-user/nf-registry-manage-user.js |   6 +-
 .../manage-user/nf-registry-manage-user.spec.js    |   6 +-
 .../manage-bucket/nf-registry-manage-bucket.js     |   4 +-
 .../nf-registry-manage-bucket.spec.js              |   4 +-
 .../nf-registry-bucket-grid-list-viewer.js         |   8 +-
 .../nf-registry-bucket-grid-list-viewer.spec.js    |   2 +-
 .../nf-registry-droplet-grid-list-viewer.js        |   6 +-
 .../nf-registry-droplet-grid-list-viewer.spec.js   |   2 +-
 .../src/main/webapp/nf-registry-bootstrap.js       |   2 +-
 .../src/main/webapp/nf-registry.html               |  18 +-
 .../src/main/webapp/nf-registry.js                 |   4 +-
 .../src/main/webapp/nf-registry.routes.js          |  14 +-
 .../src/main/webapp/services/nf-registry.api.js    |  56 ++---
 .../main/webapp/services/nf-registry.api.spec.js   | 246 ++++++++++-----------
 .../services/nf-registry.auth-guard.service.js     |  22 +-
 .../nf-registry.auth-guard.service.spec.js         |  20 +-
 .../main/webapp/services/nf-registry.service.js    |  10 +-
 .../webapp/services/nf-registry.service.spec.js    |   6 +-
 .../src/main/webapp/template.html                  |   8 +-
 .../main/webapp/theming/_structureElements.scss    |   6 +-
 .../src/main/webpack.common.js                     |   3 +-
 .../nifi-registry-web-ui/src/main/webpack.dev.js   |   3 -
 26 files changed, 240 insertions(+), 238 deletions(-)

diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/nf-registry-administration.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/nf-registry-administration.js
index 889c871..bce89da 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/nf-registry-administration.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/nf-registry-administration.js
@@ -57,7 +57,7 @@ NfRegistryAdministration.prototype = {
      * @param $event
      */
     navigateToAdminPerspective: function ($event) {
-        this.router.navigateByUrl('nifi-registry/administration/' + $event.value);
+        this.router.navigateByUrl('administration/' + $event.value);
     },
 
     /**
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.js
index 6c001b7..9139004 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/nf-registry-users-administration.js
@@ -75,17 +75,17 @@ NfRegistryUsersAdministration.prototype = {
                     var users = response[0];
                     self.nfRegistryService.users = users;
                 } else if (response[0].status === 404) {
-                    self.router.navigateByUrl('/nifi-registry/administration/users');
+                    self.router.navigateByUrl('administration/users');
                 } else if (response[0].status === 409) {
-                    self.router.navigateByUrl('/nifi-registry/administration/workflow');
+                    self.router.navigateByUrl('administration/workflow');
                 }
                 if (!response[1].status || response[1].status === 200) {
                     var groups = response[1];
                     self.nfRegistryService.groups = groups;
                 } else if (response[1].status === 404) {
-                    self.router.navigateByUrl('/nifi-registry/administration/users');
+                    self.router.navigateByUrl('administration/users');
                 } else if (response[1].status === 409) {
-                    self.router.navigateByUrl('/nifi-registry/administration/workflow');
+                    self.router.navigateByUrl('administration/workflow');
                 }
                 self.nfRegistryService.filterUsersAndGroups();
                 self.nfRegistryService.inProgress = false;
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js
index 4cdc60e..836e186 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.js
@@ -90,9 +90,9 @@ NfRegistryManageGroup.prototype = {
                     self.groupname = response.identity;
                     self.sortUsers(self.usersColumns.find(usersColumn => usersColumn.active === true));
                 } else if (response.status === 404) {
-                    self.router.navigateByUrl('/nifi-registry/administration/users');
+                    self.router.navigateByUrl('administration/users');
                 } else if (response.status === 409) {
-                    self.router.navigateByUrl('/nifi-registry/administration/workflow');
+                    self.router.navigateByUrl('administration/workflow');
                 }
             });
     },
@@ -109,7 +109,7 @@ NfRegistryManageGroup.prototype = {
      * Navigate to administer users for current registry.
      */
     closeSideNav: function () {
-        this.router.navigateByUrl('/nifi-registry/administration/users');
+        this.router.navigateByUrl('administration/users');
     },
 
     /**
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.spec.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.spec.js
index 7427ee4..c1cc807 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.spec.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-group/nf-registry-manage-group.spec.js
@@ -227,7 +227,7 @@ describe('NfRegistryManageGroup Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/administration/users');
+        expect(routerCall.args[0]).toBe('administration/users');
         expect(comp.router.navigateByUrl.calls.count()).toBe(1);
     }));
 
@@ -247,7 +247,7 @@ describe('NfRegistryManageGroup Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/administration/workflow');
+        expect(routerCall.args[0]).toBe('administration/workflow');
         expect(comp.router.navigateByUrl.calls.count()).toBe(1);
     }));
 
@@ -330,7 +330,7 @@ describe('NfRegistryManageGroup Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/administration/users');
+        expect(routerCall.args[0]).toBe('administration/users');
         expect(comp.router.navigateByUrl.calls.count()).toBe(1);
     }));
 
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js
index 4d064b5..ae8b565 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.js
@@ -90,9 +90,9 @@ NfRegistryManageUser.prototype = {
                     self.username = response.identity;
                     self.sortGroups(self.userGroupsColumns.find(userGroupsColumn => userGroupsColumn.active === true));
                 } else if (response.status === 404) {
-                    self.router.navigateByUrl('/nifi-registry/administration/users');
+                    self.router.navigateByUrl('administration/users');
                 } else if (response.status === 409) {
-                    self.router.navigateByUrl('/nifi-registry/administration/workflow');
+                    self.router.navigateByUrl('administration/workflow');
                 }
             });
     },
@@ -109,7 +109,7 @@ NfRegistryManageUser.prototype = {
      * Navigate to administer users for current registry.
      */
     closeSideNav: function () {
-        this.router.navigateByUrl('/nifi-registry/administration/users');
+        this.router.navigateByUrl('administration/users');
     },
 
     /**
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.spec.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.spec.js
index 49b42cc..5201996 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.spec.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/users/sidenav/manage-user/nf-registry-manage-user.spec.js
@@ -165,7 +165,7 @@ describe('NfRegistryManageUser Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/administration/users');
+        expect(routerCall.args[0]).toBe('administration/users');
         expect(comp.router.navigateByUrl.calls.count()).toBe(1);
     }));
 
@@ -185,7 +185,7 @@ describe('NfRegistryManageUser Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/administration/workflow');
+        expect(routerCall.args[0]).toBe('administration/workflow');
         expect(comp.router.navigateByUrl.calls.count()).toBe(1);
     }));
 
@@ -237,7 +237,7 @@ describe('NfRegistryManageUser Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/administration/users');
+        expect(routerCall.args[0]).toBe('administration/users');
         expect(comp.router.navigateByUrl.calls.count()).toBe(1);
     }));
 
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/sidenav/manage-bucket/nf-registry-manage-bucket.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/sidenav/manage-bucket/nf-registry-manage-bucket.js
index c739c67..f4efc49 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/sidenav/manage-bucket/nf-registry-manage-bucket.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/sidenav/manage-bucket/nf-registry-manage-bucket.js
@@ -132,7 +132,7 @@ NfRegistryManageBucket.prototype = {
                         }
                     }
                 } else if (response[0].status === 404) {
-                    self.router.navigateByUrl('/nifi-registry/administration/workflow');
+                    self.router.navigateByUrl('administration/workflow');
                 }
             });
     },
@@ -149,7 +149,7 @@ NfRegistryManageBucket.prototype = {
      * Navigate to administer the buckets of the current registry.
      */
     closeSideNav: function () {
-        this.router.navigateByUrl('/nifi-registry/administration/workflow');
+        this.router.navigateByUrl('administration/workflow');
     },
 
     /**
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/sidenav/manage-bucket/nf-registry-manage-bucket.spec.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/sidenav/manage-bucket/nf-registry-manage-bucket.spec.js
index 1a853f1..191b751 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/sidenav/manage-bucket/nf-registry-manage-bucket.spec.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/administration/workflow/sidenav/manage-bucket/nf-registry-manage-bucket.spec.js
@@ -132,7 +132,7 @@ describe('NfRegistryManageBucket Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/administration/workflow');
+        expect(routerCall.args[0]).toBe('administration/workflow');
         expect(comp.router.navigateByUrl.calls.count()).toBe(1);
     }));
 
@@ -172,7 +172,7 @@ describe('NfRegistryManageBucket Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/administration/workflow');
+        expect(routerCall.args[0]).toBe('administration/workflow');
         expect(comp.router.navigateByUrl.calls.count()).toBe(1);
     }));
 
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
index dd0c9e5..18dffb8 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.js
@@ -72,13 +72,13 @@ NfRegistryBucketGridListViewer.prototype = {
                     var buckets = response[0];
                     self.nfRegistryService.buckets = buckets;
                 } else if (response[0].status === 404) {
-                    self.router.navigateByUrl('/nifi-registry/explorer/grid-list');
+                    self.router.navigateByUrl('explorer/grid-list');
                 }
                 if (!response[2].status || response[2].status === 200) {
                     var bucket = response[2];
                     self.nfRegistryService.bucket = bucket;
                 } else if (response[2].status === 404) {
-                    self.router.navigateByUrl('/nifi-registry/explorer/grid-list');
+                    self.router.navigateByUrl('explorer/grid-list');
                 }
                 if (!response[1].status || response[1].status === 200) {
                     var droplets = response[1];
@@ -86,9 +86,9 @@ NfRegistryBucketGridListViewer.prototype = {
                 } else if (response[1].status === 404) {
                     if (!response[2].status || response[2].status === 200) {
                         var bucket = response[2];
-                        self.router.navigateByUrl('/nifi-registry/explorer/grid-list/buckets/' + bucket);
+                        self.router.navigateByUrl('explorer/grid-list/buckets/' + bucket);
                     } else {
-                        self.router.navigateByUrl('/nifi-registry/explorer/grid-list');
+                        self.router.navigateByUrl('explorer/grid-list');
                     }
                 }
                 self.nfRegistryService.filterDroplets();
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
index 55c7842..21b5553 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-bucket-grid-list-viewer.spec.js
@@ -142,7 +142,7 @@ describe('NfRegistryBucketGridListViewer Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/explorer/grid-list');
+        expect(routerCall.args[0]).toBe('explorer/grid-list');
         expect(comp.router.navigateByUrl.calls.count()).toBe(3);
     }));
 
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
index 1d68fb2..4362022 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.js
@@ -73,16 +73,16 @@ NfRegistryDropletGridListViewer.prototype = {
                     if (!response[1].status || response[1].status === 200) {
                         var bucket = response[1];
                         self.nfRegistryService.bucket = bucket;
-                        self.router.navigateByUrl('/nifi-registry/explorer/grid-list/buckets/' + bucket.identifier);
+                        self.router.navigateByUrl('explorer/grid-list/buckets/' + bucket.identifier);
                     } else if (response[1].status === 404) {
-                        self.router.navigateByUrl('/nifi-registry/explorer/grid-list');
+                        self.router.navigateByUrl('explorer/grid-list');
                     }
                 }
                 if (!response[1].status || response[1].status === 200) {
                     var bucket = response[1];
                     self.nfRegistryService.bucket = bucket;
                 } else if (response[1].status === 404) {
-                    self.router.navigateByUrl('/nifi-registry/explorer/grid-list');
+                    self.router.navigateByUrl('explorer/grid-list');
                 }
                 if (!response[2].status || response[2].status === 200) {
                     var buckets = response[2];
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
index 5d22c9c..40d9293 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-droplet-grid-list-viewer.spec.js
@@ -174,7 +174,7 @@ describe('NfRegistryDropletGridListViewer Component', function () {
 
         //assertions
         const routerCall = comp.router.navigateByUrl.calls.first();
-        expect(routerCall.args[0]).toBe('/nifi-registry/explorer/grid-list');
+        expect(routerCall.args[0]).toBe('explorer/grid-list');
         expect(comp.router.navigateByUrl.calls.count()).toBe(2);
     }));
 
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry-bootstrap.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry-bootstrap.js
index a29ffba..5f456d8 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry-bootstrap.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry-bootstrap.js
@@ -46,7 +46,7 @@ const providers = [];
 if (!locale || locale === 'en-us') {
     bootstrapModule();
 } else { //load the translation providers and bootstrap the module
-    var translationFile = './nifi-registry/assets/locale/messages.' + locale + '.xlf';
+    var translationFile = 'assets/locale/messages.' + locale + '.xlf';
 
     $.ajax({
         url: translationFile
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.html b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.html
index 9cb589c..b7c37e4 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.html
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.html
@@ -22,12 +22,12 @@ limitations under the License.
     </mat-sidenav>
     <div id="nf-registry-app-container">
         <mat-toolbar id="nifi-registry-toolbar">
-            <img id="nifi-registry-logo" src="nifi-registry/assets/images/registry-logo-web-app.svg">
+            <img id="nifi-registry-logo" src="assets/images/registry-logo-web-app.svg">
             <div *ngIf="nfRegistryService.perspective !== 'login' && nfRegistryService.perspective !== 'not-found'" fxFlex="1 1 auto" class="pad-left-xl" [@flyInOut]="nfRegistryService.breadCrumbState">
-                <span class="pointer" routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}">{{nfRegistryService.registry.name}}</span>
+                <span class="pointer" routerLink="explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}">{{nfRegistryService.registry.name}}</span>
                 <mat-menu #availableRegistriesMenu="matMenu" [overlapTrigger]="false">
                     <button mat-menu-item *ngFor="let registry of nfRegistryService.registries"
-                            routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}">
+                            routerLink="explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}">
                         <span>{{registry.name}}</span>
                     </button>
                 </mat-menu>
@@ -40,11 +40,11 @@ limitations under the License.
                                                                           aria-hidden="true"></i></span>
                 <mat-menu #availableBucketsMenu="matMenu" [overlapTrigger]="false">
                     <button mat-menu-item
-                            routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}">
+                            routerLink="explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}">
                         <span>All buckets</span>
                     </button>
                     <button mat-menu-item *ngFor="let bucket of nfRegistryService.buckets"
-                            routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}/buckets/{{bucket.identifier}}">
+                            routerLink="explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}/buckets/{{bucket.identifier}}">
                         <span>{{bucket.name}}</span>
                     </button>
                 </mat-menu>
@@ -56,11 +56,11 @@ limitations under the License.
                         class="fa fa-caret-down pad-left-sm" aria-hidden="true"></i></span>
                 <mat-menu #availableDropletsMenu="matMenu" [overlapTrigger]="false">
                     <button mat-menu-item
-                            routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}/buckets/{{nfRegistryService.bucket.identifier}}">
+                            routerLink="explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}/buckets/{{nfRegistryService.bucket.identifier}}">
                         <span>All resources</span>
                     </button>
                     <button mat-menu-item *ngFor="let droplet of nfRegistryService.droplets"
-                            routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}/{{droplet.link.href}}">
+                            routerLink="explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}/{{droplet.link.href}}">
                         <span>{{droplet.name}}</span>
                     </button>
                 </mat-menu>
@@ -80,11 +80,11 @@ limitations under the License.
                 <a matTooltip="Help" href="{{nfRegistryService.documentation.link}}" target="_blank"><i class="fa fa-question-circle help-icon" aria-hidden="true"></i></a>
             </div>
             <button matTooltip="Settings" mat-ripple *ngIf="nfRegistryService.currentUser.resourcePermissions.anyTopLevelResource.canRead && nfRegistryService.perspective === 'explorer'" mat-icon-button
-                    routerLink="/nifi-registry/administration/workflow">
+                    routerLink="administration/workflow">
                 <i class="fa fa-wrench" aria-hidden="true"></i>
             </button>
             <button color="primary" matTooltip="Close settings" mat-ripple *ngIf="nfRegistryService.perspective === 'administration'" mat-mini-fab
-                    routerLink="/nifi-registry/explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}">
+                    routerLink="explorer/{{(nfRegistryService.explorerViewType) ? nfRegistryService.explorerViewType : 'grid-list'}}">
                 <mat-icon>close</mat-icon>
             </button>
         </mat-toolbar>
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.js
index 24702cf..0ad0434 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.js
@@ -74,14 +74,14 @@ NfRegistry.prototype = {
         delete this.nfRegistryService.currentUser.identity;
         delete this.nfRegistryService.currentUser.anonymous;
         this.nfStorage.removeItem('jwt');
-        this.router.navigateByUrl('/nifi-registry/login');
+        this.router.navigateByUrl('login');
     },
 
     /**
      * Navigate to login route.
      */
     login: function () {
-        this.router.navigateByUrl('/nifi-registry/login');
+        this.router.navigateByUrl('login');
     }
 };
 
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
index 52f3f55..1b1b8d0 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
@@ -37,7 +37,7 @@ import {
 
 // eslint-disable-next-line new-cap
 const NfRegistryRoutes = new RouterModule.forRoot([{
-    path: 'nifi-registry/explorer',
+    path: 'explorer',
     component: NfRegistryExplorer,
     children: [
         {
@@ -61,11 +61,11 @@ const NfRegistryRoutes = new RouterModule.forRoot([{
         }
     ]
 }, {
-    path: 'nifi-registry/login',
+    path: 'login',
     component: NfLoginComponent,
     canActivate: [NfRegistryLoginAuthGuard]
 }, {
-    path: 'nifi-registry/administration',
+    path: 'administration',
     component: NfRegistryAdministration,
     children: [{
         path: '',
@@ -81,15 +81,15 @@ const NfRegistryRoutes = new RouterModule.forRoot([{
         canActivate: [NfRegistryWorkflowsAdministrationAuthGuard]
     }]
 }, {
-    path: 'nifi-registry/explorer/grid-list/buckets',
-    redirectTo: '/nifi-registry/explorer/grid-list',
+    path: 'explorer/grid-list/buckets',
+    redirectTo: '/explorer/grid-list',
     pathMatch: 'full'
 }, {
     path: 'nifi-registry',
-    redirectTo: '/nifi-registry/explorer/grid-list'
+    redirectTo: 'explorer/grid-list'
 }, {
     path: '',
-    redirectTo: '/nifi-registry/explorer/grid-list',
+    redirectTo: 'explorer/grid-list',
     pathMatch: 'full'
 }, {
     path: '**',
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js
index 0c088ea..8ec0c6a 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js
@@ -26,8 +26,8 @@ var headers = new Headers({'Content-Type': 'application/json'});
 
 var config = {
     urls: {
-        currentUser: '/nifi-registry-api/access',
-        kerberos: '/nifi-registry-api/access/token/kerberos'
+        currentUser: '../nifi-registry-api/access',
+        kerberos: '../nifi-registry-api/access/token/kerberos'
     }
 };
 
@@ -56,7 +56,7 @@ NfRegistryApi.prototype = {
      */
     getDropletSnapshotMetadata: function (dropletUri) {
         var self = this;
-        var url = '/nifi-registry-api/' + dropletUri;
+        var url = '../nifi-registry-api/' + dropletUri;
         url += '/versions';
         return this.http.get(url).pipe(
             map(function (response) {
@@ -84,7 +84,7 @@ NfRegistryApi.prototype = {
      */
     getDroplet: function (bucketId, dropletType, dropletId) {
         var self = this;
-        var url = '/nifi-registry-api/buckets/' + bucketId + '/' + dropletType + '/' + dropletId;
+        var url = '../nifi-registry-api/buckets/' + bucketId + '/' + dropletType + '/' + dropletId;
         return this.http.get(url).pipe(
             map(function (response) {
                 return response;
@@ -111,7 +111,7 @@ NfRegistryApi.prototype = {
      * @returns {*}
      */
     getDroplets: function (bucketId) {
-        var url = '/nifi-registry-api/items';
+        var url = '../nifi-registry-api/items';
         if (bucketId) {
             url += '/' + bucketId;
         }
@@ -138,7 +138,7 @@ NfRegistryApi.prototype = {
      */
     deleteDroplet: function (dropletUri) {
         var self = this;
-        return this.http.delete('/nifi-registry-api/' + dropletUri, headers).pipe(
+        return this.http.delete('../nifi-registry-api/' + dropletUri, headers).pipe(
             map(function (response) {
                 return response;
             }),
@@ -162,7 +162,7 @@ NfRegistryApi.prototype = {
      */
     createBucket: function (name, allowPublicRead) {
         var self = this;
-        return this.http.post('/nifi-registry-api/buckets', {'name': name, 'allowPublicRead': allowPublicRead}, headers).pipe(
+        return this.http.post('../nifi-registry-api/buckets', {'name': name, 'allowPublicRead': allowPublicRead}, headers).pipe(
             map(function (response) {
                 return response;
             }),
@@ -186,7 +186,7 @@ NfRegistryApi.prototype = {
      */
     deleteBucket: function (bucketId) {
         var self = this;
-        return this.http.delete('/nifi-registry-api/buckets/' + bucketId, headers).pipe(
+        return this.http.delete('../nifi-registry-api/buckets/' + bucketId, headers).pipe(
             map(function (response) {
                 return response;
             }),
@@ -210,7 +210,7 @@ NfRegistryApi.prototype = {
      */
     getBucket: function (bucketId) {
         var self = this;
-        var url = '/nifi-registry-api/buckets/' + bucketId;
+        var url = '../nifi-registry-api/buckets/' + bucketId;
         return this.http.get(url).pipe(
             map(function (response) {
                 return response;
@@ -237,7 +237,7 @@ NfRegistryApi.prototype = {
      */
     getBuckets: function () {
         var self = this;
-        var url = '/nifi-registry-api/buckets';
+        var url = '../nifi-registry-api/buckets';
         return this.http.get(url).pipe(
             map(function (response) {
                 return response;
@@ -261,7 +261,7 @@ NfRegistryApi.prototype = {
      * @returns {*}
      */
     updateBucket: function (updatedBucket) {
-        return this.http.put('/nifi-registry-api/buckets/' + updatedBucket.identifier, updatedBucket, headers).pipe(
+        return this.http.put('../nifi-registry-api/buckets/' + updatedBucket.identifier, updatedBucket, headers).pipe(
             map(function (response) {
                 return response;
             }),
@@ -279,7 +279,7 @@ NfRegistryApi.prototype = {
      */
     getUser: function (userId) {
         var self = this;
-        return this.http.get('/nifi-registry-api/tenants/users/' + userId).pipe(
+        return this.http.get('../nifi-registry-api/tenants/users/' + userId).pipe(
             map(function (response) {
                 return response;
             }),
@@ -303,7 +303,7 @@ NfRegistryApi.prototype = {
      */
     addUser: function (identity) {
         var self = this;
-        return this.http.post('/nifi-registry-api/tenants/users', {
+        return this.http.post('../nifi-registry-api/tenants/users', {
             identity: identity,
             resourcePermissions: {
                 anyTopLevelResource: {
@@ -356,7 +356,7 @@ NfRegistryApi.prototype = {
      * @returns {*}
      */
     updateUser: function (identifier, identity) {
-        return this.http.put('/nifi-registry-api/tenants/users/' + identifier, {
+        return this.http.put('../nifi-registry-api/tenants/users/' + identifier, {
             'identifier': identifier,
             'identity': identity
         }, headers).pipe(
@@ -376,7 +376,7 @@ NfRegistryApi.prototype = {
      */
     getUsers: function () {
         var self = this;
-        return this.http.get('/nifi-registry-api/tenants/users').pipe(
+        return this.http.get('../nifi-registry-api/tenants/users').pipe(
             map(function (response) {
                 return response;
             }),
@@ -400,7 +400,7 @@ NfRegistryApi.prototype = {
      */
     deleteUser: function (userId) {
         var self = this;
-        return this.http.delete('/nifi-registry-api/tenants/users/' + userId, headers).pipe(
+        return this.http.delete('../nifi-registry-api/tenants/users/' + userId, headers).pipe(
             map(function (response) {
                 return response;
             }),
@@ -423,7 +423,7 @@ NfRegistryApi.prototype = {
      */
     getUserGroups: function () {
         var self = this;
-        return this.http.get('/nifi-registry-api/tenants/user-groups').pipe(
+        return this.http.get('../nifi-registry-api/tenants/user-groups').pipe(
             map(function (response) {
                 return response;
             }),
@@ -447,7 +447,7 @@ NfRegistryApi.prototype = {
      */
     getUserGroup: function (groupId) {
         var self = this;
-        return this.http.get('/nifi-registry-api/tenants/user-groups/' + groupId).pipe(
+        return this.http.get('../nifi-registry-api/tenants/user-groups/' + groupId).pipe(
             map(function (response) {
                 return response;
             }),
@@ -471,7 +471,7 @@ NfRegistryApi.prototype = {
      */
     deleteUserGroup: function (userGroupId) {
         var self = this;
-        return this.http.delete('/nifi-registry-api/tenants/user-groups/' + userGroupId, headers).pipe(
+        return this.http.delete('../nifi-registry-api/tenants/user-groups/' + userGroupId, headers).pipe(
             map(function (response) {
                 return response;
             }),
@@ -497,7 +497,7 @@ NfRegistryApi.prototype = {
      */
     createNewGroup: function (identifier, identity, users) {
         var self = this;
-        return this.http.post('/nifi-registry-api/tenants/user-groups', {
+        return this.http.post('../nifi-registry-api/tenants/user-groups', {
             'identifier': identifier,
             'identity': identity,
             'users': users
@@ -526,7 +526,7 @@ NfRegistryApi.prototype = {
      * @returns {*}
      */
     updateUserGroup: function (identifier, identity, users) {
-        return this.http.put('/nifi-registry-api/tenants/user-groups/' + identifier, {
+        return this.http.put('../nifi-registry-api/tenants/user-groups/' + identifier, {
             'identifier': identifier,
             'identity': identity,
             'users': users
@@ -546,7 +546,7 @@ NfRegistryApi.prototype = {
      * @returns {*}
      */
     getPolicies: function () {
-        var url = '/nifi-registry-api/policies';
+        var url = '../nifi-registry-api/policies';
         return this.http.get(url).pipe(
             map(function (response) {
                 return response;
@@ -566,7 +566,7 @@ NfRegistryApi.prototype = {
      * @returns {*}
      */
     getResourcePoliciesById: function (action, resource, resourceId) {
-        return this.http.get('/nifi-registry-api/policies/' + action + resource + '/' + resourceId).pipe(
+        return this.http.get('../nifi-registry-api/policies/' + action + resource + '/' + resourceId).pipe(
             map(function (response) {
                 return response;
             }),
@@ -584,7 +584,7 @@ NfRegistryApi.prototype = {
      * @returns {*}
      */
     getPolicyActionResource: function (action, resource) {
-        return this.http.get('/nifi-registry-api/policies/' + action + resource).pipe(
+        return this.http.get('../nifi-registry-api/policies/' + action + resource).pipe(
             map(function (response) {
                 return response;
             }),
@@ -606,7 +606,7 @@ NfRegistryApi.prototype = {
      */
     putPolicyActionResource: function (identifier, action, resource, users, userGroups) {
         var self = this;
-        return this.http.put('/nifi-registry-api/policies/' + identifier, {
+        return this.http.put('../nifi-registry-api/policies/' + identifier, {
             'identifier': identifier,
             'resource': resource,
             'action': action,
@@ -639,7 +639,7 @@ NfRegistryApi.prototype = {
      */
     postPolicyActionResource: function (action, resource, users, userGroups) {
         var self = this;
-        return this.http.post('/nifi-registry-api/policies', {
+        return this.http.post('../nifi-registry-api/policies', {
             'resource': resource,
             'action': action,
             'users': users,
@@ -680,7 +680,7 @@ NfRegistryApi.prototype = {
             withCredentials: true,
             responseType: 'text'
         };
-        return this.http.post('/nifi-registry-api/access/token/login', null, options).pipe(
+        return this.http.post('../nifi-registry-api/access/token/login', null, options).pipe(
             map(function (jwt) {
                 // get the payload and store the token with the appropriate expiration
                 var token = self.nfStorage.getJwtPayload(jwt);
@@ -780,7 +780,7 @@ NfRegistryApi.prototype = {
      * @returns {*}
      */
     getRegistryConfig: function (action, resource) {
-        return this.http.get('/nifi-registry-api/config').pipe(
+        return this.http.get('../nifi-registry-api/config').pipe(
             map(function (response) {
                 return response;
             }),
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.spec.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.spec.js
index 9e6373b..e13be06 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.spec.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.spec.js
@@ -58,7 +58,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/access/token/kerberos');
+        req = httpMock.expectOne('../nifi-registry-api/access/token/kerberos');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
@@ -94,7 +94,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/access/token/kerberos');
+        req = httpMock.expectOne('../nifi-registry-api/access/token/kerberos');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
@@ -112,7 +112,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/access');
+        req = httpMock.expectOne('../nifi-registry-api/access');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -130,7 +130,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         nfRegistryApi.getDropletSnapshotMetadata('flow/test').subscribe(function (response) {
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/flow/test/versions');
+        req = httpMock.expectOne('../nifi-registry-api/flow/test/versions');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -151,19 +151,19 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getDropletSnapshotMetadata('flow/test').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/flow/test/versions: 401 GET droplet mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/flow/test/versions: 401 GET droplet mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/flow/test/versions: 401 GET droplet mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/flow/test/versions: 401 GET droplet mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/flow/test/versions');
+        req = httpMock.expectOne('../nifi-registry-api/flow/test/versions');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/flow/test/versions: 401 GET droplet mock error', {status: 401, statusText: 'GET droplet mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/flow/test/versions: 401 GET droplet mock error', {status: 401, statusText: 'GET droplet mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -177,7 +177,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             expect(response.name).toEqual('Flow #1');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc');
+        req = httpMock.expectOne('../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -214,20 +214,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getDroplet('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc', 'flows', '2e04b4fb-9513-47bb-aa74-1ae34616bfdc').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc: 401 GET droplet mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc: 401 GET droplet mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Flow Not Found');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc: 401 GET droplet mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc: 401 GET droplet mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc');
+        req = httpMock.expectOne('../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc: 401 GET droplet mock error', {status: 401, statusText: 'GET droplet mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc/flows/2e04b4fb-9513-47bb-aa74-1ae34616bfdc: 401 GET droplet mock error', {status: 401, statusText: 'GET droplet mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -243,7 +243,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             expect(response[1].name).toEqual('Flow #2');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/items');
+        req = httpMock.expectOne('../nifi-registry-api/items');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -286,15 +286,15 @@ describe('NfRegistry API w/ Angular testing utils', function () {
     it('should fail to GET all droplets across all buckets.', inject([HttpTestingController], function (httpMock) {
         // api call
         nfRegistryApi.getDroplets().subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/items: 401 GET droplet mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/items: 401 GET droplet mock error');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/items');
+        req = httpMock.expectOne('../nifi-registry-api/items');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/items: 401 GET droplet mock error', {status: 401, statusText: 'GET droplet mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/items: 401 GET droplet mock error', {status: 401, statusText: 'GET droplet mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -308,7 +308,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             expect(response[0].name).toEqual('Flow #1');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/items/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/items/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -336,15 +336,15 @@ describe('NfRegistry API w/ Angular testing utils', function () {
     it('should fail to GET all droplets across a single bucket.', inject([HttpTestingController], function (httpMock) {
         // api call
         nfRegistryApi.getDroplets('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/items/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET droplet mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/items/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET droplet mock error');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/items/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/items/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/items/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET droplet mock error', {status: 401, statusText: 'GET droplet mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/items/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET droplet mock error', {status: 401, statusText: 'GET droplet mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -356,7 +356,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/flows/1234');
+        req = httpMock.expectOne('../nifi-registry-api/flows/1234');
         expect(req.request.method).toEqual('DELETE');
 
         // Next, fulfill the request by transmitting a response.
@@ -373,20 +373,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.deleteDroplet('flows/1234').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/flows/1234: 401 DELETE droplet mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/flows/1234: 401 DELETE droplet mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/flows/1234: 401 DELETE droplet mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/flows/1234: 401 DELETE droplet mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/flows/1234');
+        req = httpMock.expectOne('../nifi-registry-api/flows/1234');
         expect(req.request.method).toEqual('DELETE');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/flows/1234: 401 DELETE droplet mock error', {status: 401, statusText: 'DELETE droplet mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/flows/1234: 401 DELETE droplet mock error', {status: 401, statusText: 'DELETE droplet mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -398,7 +398,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             expect(response.identifier).toBe('1234');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets');
+        req = httpMock.expectOne('../nifi-registry-api/buckets');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
@@ -417,20 +417,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.createBucket('test').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/buckets: 401 POST bucket mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/buckets: 401 POST bucket mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/buckets: 401 POST bucket mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/buckets: 401 POST bucket mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets');
+        req = httpMock.expectOne('../nifi-registry-api/buckets');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/buckets: 401 POST bucket mock error', {status: 401, statusText: 'POST bucket mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/buckets: 401 POST bucket mock error', {status: 401, statusText: 'POST bucket mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -441,7 +441,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         nfRegistryApi.deleteBucket('1234').subscribe(function (response) {
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets/1234');
+        req = httpMock.expectOne('../nifi-registry-api/buckets/1234');
         expect(req.request.method).toEqual('DELETE');
 
         // Next, fulfill the request by transmitting a response.
@@ -458,19 +458,19 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.deleteBucket('1234').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/buckets/1234: 401 DELETE bucket mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/buckets/1234: 401 DELETE bucket mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/buckets/1234: 401 DELETE bucket mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/buckets/1234: 401 DELETE bucket mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets/1234');
+        req = httpMock.expectOne('../nifi-registry-api/buckets/1234');
         expect(req.request.method).toEqual('DELETE');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/buckets/1234: 401 DELETE bucket mock error', {status: 401, statusText: 'DELETE bucket mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/buckets/1234: 401 DELETE bucket mock error', {status: 401, statusText: 'DELETE bucket mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -483,7 +483,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             expect(response.name).toEqual('Bucket #1');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -508,20 +508,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getBucket('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET bucket mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET bucket mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Bucket Not Found');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET bucket mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET bucket mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET bucket mock error', {status: 401, statusText: 'GET bucket mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET bucket mock error', {status: 401, statusText: 'GET bucket mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -534,7 +534,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             expect(response[0].name).toEqual('Bucket #1');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets');
+        req = httpMock.expectOne('../nifi-registry-api/buckets');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -554,20 +554,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getBuckets().subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/buckets: 401 GET metadata mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/buckets: 401 GET metadata mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Buckets Not Found');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/buckets: 401 GET metadata mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/buckets: 401 GET metadata mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets');
+        req = httpMock.expectOne('../nifi-registry-api/buckets');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/buckets: 401 GET metadata mock error', {status: 401, statusText: 'GET metadata mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/buckets: 401 GET metadata mock error', {status: 401, statusText: 'GET metadata mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -587,7 +587,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             expect(response[0].allowPublicRead).toEqual(true);
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('PUT');
 
         // Next, fulfill the request by transmitting a response.
@@ -609,15 +609,15 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             'name': 'Bucket #1',
             'allowBundleRedeploy': false
         }).subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 PUT to update a bucket name mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 PUT to update a bucket name mock error');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('PUT');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 PUT to update a bucket name mock error', {status: 401, statusText: 'PUT to update a bucket name mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/buckets/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 PUT to update a bucket name mock error', {status: 401, statusText: 'PUT to update a bucket name mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -630,7 +630,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             expect(response[0].name).toEqual('User #1');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -650,20 +650,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getUser('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET user by id mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET user by id mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('User Not Found');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET user by id mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET user by id mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET user by id mock error', {status: 401, statusText: 'GET user by id mock error', error: 'test'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 GET user by id mock error', {status: 401, statusText: 'GET user by id mock error', error: 'test'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -676,7 +676,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
@@ -695,20 +695,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.addUser('test').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/users: 401 POST add user mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/users: 401 POST add user mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/tenants/users: 401 POST add user mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/tenants/users: 401 POST add user mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/users: 401 POST add user mock error', {status: 401, statusText: 'POST add user mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/users: 401 POST add user mock error', {status: 401, statusText: 'POST add user mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -721,7 +721,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             expect(response[0].name).toEqual('user #1');
         });
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('PUT');
 
         // Next, fulfill the request by transmitting a response.
@@ -737,15 +737,15 @@ describe('NfRegistry API w/ Angular testing utils', function () {
     it('should fail to PUT to update a user name.', inject([HttpTestingController], function (httpMock) {
         // api call
         nfRegistryApi.updateUser('2f7f9e54-dc09-4ceb-aa58-9fe581319cdc', 'user #1').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 PUT to update a user name mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 PUT to update a user name mock error');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc');
         expect(req.request.method).toEqual('PUT');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 PUT to update a user name mock error', {status: 401, statusText: 'PUT to update a user name mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/users/2f7f9e54-dc09-4ceb-aa58-9fe581319cdc: 401 PUT to update a user name mock error', {status: 401, statusText: 'PUT to update a user name mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -758,7 +758,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -778,20 +778,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getUsers().subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/users: 401 GET users mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/users: 401 GET users mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Users Not Found');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/tenants/users: 401 GET users mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/tenants/users: 401 GET users mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/users: 401 GET users mock error', {status: 401, statusText: 'GET users mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/users: 401 GET users mock error', {status: 401, statusText: 'GET users mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -804,7 +804,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users/123');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users/123');
         expect(req.request.method).toEqual('DELETE');
 
         // Next, fulfill the request by transmitting a response.
@@ -824,20 +824,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.deleteUser(123).subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/users/123: 401 DELETE users mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/users/123: 401 DELETE users mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/tenants/users/123: 401 DELETE users mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/tenants/users/123: 401 DELETE users mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/users/123');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/users/123');
         expect(req.request.method).toEqual('DELETE');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/users/123: 401 DELETE users mock error', {status: 401, statusText: 'DELETE users mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/users/123: 401 DELETE users mock error', {status: 401, statusText: 'DELETE users mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -850,7 +850,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -870,20 +870,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getUserGroups().subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/user-groups: 401 GET user groups mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/user-groups: 401 GET user groups mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Groups Not Found');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/tenants/user-groups: 401 GET user groups mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/tenants/user-groups: 401 GET user groups mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/user-groups: 401 GET user groups mock error', {status: 401, statusText: 'GET user groups mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/user-groups: 401 GET user groups mock error', {status: 401, statusText: 'GET user groups mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -896,7 +896,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies/read/buckets/123');
+        req = httpMock.expectOne('../nifi-registry-api/policies/read/buckets/123');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -915,15 +915,15 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getResourcePoliciesById('read', '/buckets', '123').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/policies/read/buckets/123: 401 GET get resource policies by id mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/policies/read/buckets/123: 401 GET get resource policies by id mock error');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies/read/buckets/123');
+        req = httpMock.expectOne('../nifi-registry-api/policies/read/buckets/123');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/policies/read/buckets/123: 401 GET get resource policies by id mock error', {status: 401, statusText: 'GET get resource policies by id mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/policies/read/buckets/123: 401 GET get resource policies by id mock error', {status: 401, statusText: 'GET get resource policies by id mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -936,7 +936,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies/read/buckets');
+        req = httpMock.expectOne('../nifi-registry-api/policies/read/buckets');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -955,15 +955,15 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getPolicyActionResource('read', '/buckets').subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/policies/read/buckets: 401 GET policy action resource mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/policies/read/buckets: 401 GET policy action resource mock error');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies/read/buckets');
+        req = httpMock.expectOne('../nifi-registry-api/policies/read/buckets');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/policies/read/buckets: 401 GET policy action resource mock error', {status: 401, statusText: 'GET policy action resource mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/policies/read/buckets: 401 GET policy action resource mock error', {status: 401, statusText: 'GET policy action resource mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -976,7 +976,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies/123');
+        req = httpMock.expectOne('../nifi-registry-api/policies/123');
         expect(req.request.method).toEqual('PUT');
 
         // Next, fulfill the request by transmitting a response.
@@ -995,20 +995,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.putPolicyActionResource('123', 'read', '/buckets', [], []).subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/policies/123: 401 PUT policy action resource mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/policies/123: 401 PUT policy action resource mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/policies/123: 401 PUT policy action resource mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/policies/123: 401 PUT policy action resource mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies/123');
+        req = httpMock.expectOne('../nifi-registry-api/policies/123');
         expect(req.request.method).toEqual('PUT');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/policies/123: 401 PUT policy action resource mock error', {status: 401, statusText: 'PUT policy action resource mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/policies/123: 401 PUT policy action resource mock error', {status: 401, statusText: 'PUT policy action resource mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -1021,7 +1021,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies');
+        req = httpMock.expectOne('../nifi-registry-api/policies');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
@@ -1040,20 +1040,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.postPolicyActionResource('read', '/buckets', [], []).subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/policies: 401 POST policy action resource mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/policies: 401 POST policy action resource mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/policies: 401 POST policy action resource mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/policies: 401 POST policy action resource mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies');
+        req = httpMock.expectOne('../nifi-registry-api/policies');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/policies: 401 POST policy action resource mock error', {status: 401, statusText: 'POST policy action resource mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/policies: 401 POST policy action resource mock error', {status: 401, statusText: 'POST policy action resource mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -1066,7 +1066,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/access/token/login');
+        req = httpMock.expectOne('../nifi-registry-api/access/token/login');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
@@ -1092,11 +1092,11 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/access/token/login');
+        req = httpMock.expectOne('../nifi-registry-api/access/token/login');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/access/token/login: 401 POST to login mock error', {status: 401, statusText: 'POST to login mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/access/token/login: 401 POST to login mock error', {status: 401, statusText: 'POST to login mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -1109,7 +1109,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies');
+        req = httpMock.expectOne('../nifi-registry-api/policies');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -1126,15 +1126,15 @@ describe('NfRegistry API w/ Angular testing utils', function () {
     it('should fail to GET all access policies.', inject([HttpTestingController], function (httpMock) {
         // api call
         nfRegistryApi.getPolicies().subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/policies: 401 GET policies mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/policies: 401 GET policies mock error');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/policies');
+        req = httpMock.expectOne('../nifi-registry-api/policies');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/policies: 401 GET policies mock error', {status: 401, statusText: 'GET policies mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/policies: 401 GET policies mock error', {status: 401, statusText: 'GET policies mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -1147,7 +1147,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups/123');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups/123');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
@@ -1167,20 +1167,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.getUserGroup(123).subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/user-groups/123: 401 GET user groups mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/user-groups/123: 401 GET user groups mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Group Not Found');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/tenants/user-groups/123: 401 GET user groups mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/tenants/user-groups/123: 401 GET user groups mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups/123');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups/123');
         expect(req.request.method).toEqual('GET');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/user-groups/123: 401 GET user groups mock error', {status: 401, statusText: 'GET user groups mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/user-groups/123: 401 GET user groups mock error', {status: 401, statusText: 'GET user groups mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -1193,7 +1193,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups/123');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups/123');
         expect(req.request.method).toEqual('DELETE');
 
         // Next, fulfill the request by transmitting a response.
@@ -1213,20 +1213,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
 
         // api call
         nfRegistryApi.deleteUserGroup(123).subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/user-groups/123: 401 DELETE user groups mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/user-groups/123: 401 DELETE user groups mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/tenants/user-groups/123: 401 DELETE user groups mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/tenants/user-groups/123: 401 DELETE user groups mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups/123');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups/123');
         expect(req.request.method).toEqual('DELETE');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/user-groups/123: 401 DELETE user groups mock error', {status: 401, statusText: 'DELETE user groups mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/user-groups/123: 401 DELETE user groups mock error', {status: 401, statusText: 'DELETE user groups mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -1244,7 +1244,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
@@ -1268,20 +1268,20 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             identity: 'User #1',
             identifier: 9999
         }]).subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/user-groups: 401 POST user groups mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/user-groups: 401 POST user groups mock error');
             var dialogServiceCall = nfRegistryApi.dialogService.openConfirm.calls.first();
             expect(dialogServiceCall.args[0].title).toBe('Error');
-            expect(dialogServiceCall.args[0].message).toBe('Http failure response for /nifi-registry-api/tenants/user-groups: 401 POST user groups mock error');
+            expect(dialogServiceCall.args[0].message).toBe('Http failure response for ../nifi-registry-api/tenants/user-groups: 401 POST user groups mock error');
             expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
             expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups');
         expect(req.request.method).toEqual('POST');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/user-groups: 401 POST user groups mock error', {status: 401, statusText: 'POST user groups mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/user-groups: 401 POST user groups mock error', {status: 401, statusText: 'POST user groups mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
@@ -1299,7 +1299,7 @@ describe('NfRegistry API w/ Angular testing utils', function () {
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups/123');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups/123');
         expect(req.request.method).toEqual('PUT');
 
         // Next, fulfill the request by transmitting a response.
@@ -1319,15 +1319,15 @@ describe('NfRegistry API w/ Angular testing utils', function () {
             identity: 'User #1',
             identifier: '9999'
         }]).subscribe(function (response) {
-            expect(response.message).toEqual('Http failure response for /nifi-registry-api/tenants/user-groups/123: 401 PUT to update a user group name mock error');
+            expect(response.message).toEqual('Http failure response for ../nifi-registry-api/tenants/user-groups/123: 401 PUT to update a user group name mock error');
         });
 
         // the request it made
-        req = httpMock.expectOne('/nifi-registry-api/tenants/user-groups/123');
+        req = httpMock.expectOne('../nifi-registry-api/tenants/user-groups/123');
         expect(req.request.method).toEqual('PUT');
 
         // Next, fulfill the request by transmitting a response.
-        req.flush('Http failure response for /nifi-registry-api/tenants/user-groups/123: 401 PUT to update a user group name mock error', {status: 401, statusText: 'PUT to update a user group name mock error'});
+        req.flush('Http failure response for ../nifi-registry-api/tenants/user-groups/123: 401 PUT to update a user group name mock error', {status: 401, statusText: 'PUT to update a user group name mock error'});
 
         // Finally, assert that there are no outstanding requests.
         httpMock.verify();
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
index 8ac6d38..ca3c1d0 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.js
@@ -66,7 +66,7 @@ NfRegistryUsersAdministrationAuthGuard.prototype = {
                 if (currentUser.error) {
                     if (currentUser.error.status === 401) {
                         self.nfStorage.removeItem('jwt');
-                        self.router.navigateByUrl('/nifi-registry/login');
+                        self.router.navigateByUrl('login');
                     }
                 } else {
                     self.nfRegistryService.currentUser = currentUser;
@@ -84,7 +84,7 @@ NfRegistryUsersAdministrationAuthGuard.prototype = {
                                 acceptButton: 'Ok',
                                 acceptButtonColor: 'fds-warn'
                             });
-                            self.router.navigateByUrl('/nifi-registry/explorer');
+                            self.router.navigateByUrl('explorer');
                         } else if (currentUser.resourcePermissions.tenants.canRead) {
                             self.router.navigateByUrl(url);
                         } else {
@@ -94,7 +94,7 @@ NfRegistryUsersAdministrationAuthGuard.prototype = {
                                 acceptButton: 'Ok',
                                 acceptButtonColor: 'fds-warn'
                             });
-                            self.router.navigateByUrl('/nifi-registry/explorer');
+                            self.router.navigateByUrl('explorer');
                         }
                     } else if (location.protocol === 'http:') {
                         // user is anonymous and we are NOT secure, redirect to workflow perspective
@@ -104,7 +104,7 @@ NfRegistryUsersAdministrationAuthGuard.prototype = {
                             acceptButton: 'Ok',
                             acceptButtonColor: 'fds-warn'
                         });
-                        self.router.navigateByUrl('/nifi-registry/administration/workflow');
+                        self.router.navigateByUrl('administration/workflow');
                     } else {
                         // user is anonymous and we are secure so don't allow the url, navigate to the main page
                         self.dialogService.openConfirm({
@@ -113,7 +113,7 @@ NfRegistryUsersAdministrationAuthGuard.prototype = {
                             acceptButton: 'Ok',
                             acceptButtonColor: 'fds-warn'
                         });
-                        self.router.navigateByUrl('/nifi-registry/explorer');
+                        self.router.navigateByUrl('explorer');
                     }
                 }
             });
@@ -176,7 +176,7 @@ NfRegistryWorkflowsAdministrationAuthGuard.prototype = {
                 if (currentUser.error) {
                     if (currentUser.error.status === 401) {
                         self.nfStorage.removeItem('jwt');
-                        self.router.navigateByUrl('/nifi-registry/login');
+                        self.router.navigateByUrl('login');
                     }
                 } else {
                     self.nfRegistryService.currentUser = currentUser;
@@ -194,7 +194,7 @@ NfRegistryWorkflowsAdministrationAuthGuard.prototype = {
                                 acceptButton: 'Ok',
                                 acceptButtonColor: 'fds-warn'
                             });
-                            self.router.navigateByUrl('/nifi-registry/explorer');
+                            self.router.navigateByUrl('explorer');
                         } else if (currentUser.resourcePermissions.buckets.canRead) {
                             self.router.navigateByUrl(url);
                         } else {
@@ -204,7 +204,7 @@ NfRegistryWorkflowsAdministrationAuthGuard.prototype = {
                                 acceptButton: 'Ok',
                                 acceptButtonColor: 'fds-warn'
                             });
-                            self.router.navigateByUrl('/nifi-registry/administration/users');
+                            self.router.navigateByUrl('administration/users');
                         }
                     } else if (location.protocol === 'http:') {
                         // user is anonymous and we are NOT secure so allow the url
@@ -217,7 +217,7 @@ NfRegistryWorkflowsAdministrationAuthGuard.prototype = {
                             acceptButton: 'Ok',
                             acceptButtonColor: 'fds-warn'
                         });
-                        self.router.navigateByUrl('/nifi-registry/explorer');
+                        self.router.navigateByUrl('explorer');
                     }
                 }
             });
@@ -341,7 +341,7 @@ NfRegistryResourcesAuthGuard.prototype = {
                 if (currentUser.error) {
                     if (currentUser.error.status === 401) {
                         self.nfStorage.removeItem('jwt');
-                        self.router.navigateByUrl('/nifi-registry/login');
+                        self.router.navigateByUrl('login');
                     }
                 } else {
                     self.nfRegistryService.currentUser = currentUser;
@@ -351,7 +351,7 @@ NfRegistryResourcesAuthGuard.prototype = {
                             self.nfRegistryService.currentUser.canActivateResourcesAuthGuard = true;
                             self.router.navigateByUrl(url);
                         } else {
-                            self.router.navigateByUrl('/nifi-registry/login');
+                            self.router.navigateByUrl('login');
                         }
                     } else if (currentUser.anonymous === true) {
                         // render the logout button if there is a token locally
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.spec.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.spec.js
index e826fac..a656518 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.spec.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.auth-guard.service.spec.js
@@ -112,7 +112,7 @@ describe('NfRegistry Auth Guard Service NfRegistryResourcesAuthGuard isolated un
 
         //assertions
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/login');
+        expect(navigateByUrlCall.args[0]).toBe('login');
     });
 
     it('should navigate to login (error loading current user)', function () {
@@ -132,7 +132,7 @@ describe('NfRegistry Auth Guard Service NfRegistryResourcesAuthGuard isolated un
         //assertions
         expect(nfStorage.removeItem).toHaveBeenCalled();
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/login');
+        expect(navigateByUrlCall.args[0]).toBe('login');
     });
 });
 
@@ -198,7 +198,7 @@ describe('NfRegistry Auth Guard Service NfRegistryLoginAuthGuard isolated unit t
         //assertions
         expect(nfRegistryService.currentUser.canActivateResourcesAuthGuard).toBe(true);
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/explorer/grid-list');
+        expect(navigateByUrlCall.args[0]).toBe('explorer/grid-list');
     });
 });
 
@@ -250,7 +250,7 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         //assertions
         expect(nfRegistryService.redirectUrl).toBe('test');
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/login');
+        expect(navigateByUrlCall.args[0]).toBe('login');
     });
 
     it('should deny access (registry security not configured) and navigate to administration workflow perspective', function () {
@@ -271,7 +271,7 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
         expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/administration/workflow');
+        expect(navigateByUrlCall.args[0]).toBe('administration/workflow');
     });
 
     it('should deny access (non-admin) and navigate to explorer perspective', function () {
@@ -319,7 +319,7 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
         expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/explorer');
+        expect(navigateByUrlCall.args[0]).toBe('explorer');
     });
 
     it('should deny access (no tenants permissions) and navigate to explorer perspective', function () {
@@ -367,7 +367,7 @@ describe('NfRegistry Auth Guard Service NfRegistryUsersAdministrationAuthGuard i
         expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
         expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/explorer');
+        expect(navigateByUrlCall.args[0]).toBe('explorer');
     });
 
     it('should deny access (no tenants permissions) and navigate to test url', function () {
@@ -462,7 +462,7 @@ describe('NfRegistry Auth Guard Service NfRegistryWorkflowsAdministrationAuthGua
         //assertions
         expect(nfRegistryService.redirectUrl).toBe('test');
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/login');
+        expect(navigateByUrlCall.args[0]).toBe('login');
     });
 
     it('should (registry security not configured) navigate to test url', function () {
@@ -526,7 +526,7 @@ describe('NfRegistry Auth Guard Service NfRegistryWorkflowsAdministrationAuthGua
         expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
         expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/explorer');
+        expect(navigateByUrlCall.args[0]).toBe('explorer');
     });
 
     it('should deny access (no buckets permissions) and navigate to users administration perspective', function () {
@@ -574,7 +574,7 @@ describe('NfRegistry Auth Guard Service NfRegistryWorkflowsAdministrationAuthGua
         expect(dialogServiceCall.args[0].acceptButton).toBe('Ok');
         expect(dialogServiceCall.args[0].acceptButtonColor).toBe('fds-warn');
         var navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/administration/users');
+        expect(navigateByUrlCall.args[0]).toBe('administration/users');
     });
 
     it('should deny access (no tenants permissions) and navigate to test url', function () {
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
index 2c36402..7999978 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.js
@@ -41,9 +41,9 @@ function NfRegistryService(nfRegistryApi, nfStorage, tdDataTableService, router,
     };
 
     this.documentation = {
-        link: 'nifi-registry-docs/documentation'
+        link: '../nifi-registry-docs/documentation'
     };
-    this.redirectUrl = '/nifi-registry/explorer/grid-list';
+    this.redirectUrl = 'explorer/grid-list';
 
     // Services
     this.router = router;
@@ -566,7 +566,7 @@ NfRegistryService.prototype = {
             );
             break;
         case 'manage':
-            this.router.navigateByUrl('/nifi-registry/administration/workflow(' + action.type + ':' + action.name + '/bucket/' + bucket.identifier + ')');
+            this.router.navigateByUrl('administration/workflow(' + action.type + ':' + action.name + '/bucket/' + bucket.identifier + ')');
             break;
         default:
             break;
@@ -1038,7 +1038,7 @@ NfRegistryService.prototype = {
                 }
             );
         case 'manage':
-            this.router.navigateByUrl('/nifi-registry/administration/users(' + action.type + ':' + action.name + '/user/' + user.identifier + ')');
+            this.router.navigateByUrl('administration/users(' + action.type + ':' + action.name + '/user/' + user.identifier + ')');
             break;
         default:
             break;
@@ -1086,7 +1086,7 @@ NfRegistryService.prototype = {
             );
             break;
         case 'manage':
-            this.router.navigateByUrl('/nifi-registry/administration/users(' + action.type + ':' + action.name + '/group/' + group.identifier + ')');
+            this.router.navigateByUrl('administration/users(' + action.type + ':' + action.name + '/group/' + group.identifier + ')');
             break;
         default:
             break;
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.spec.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.spec.js
index da2ffd7..b70de9b 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.spec.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.service.spec.js
@@ -827,7 +827,7 @@ describe('NfRegistry Service w/ Angular testing utils', function () {
 
         //assertions
         const navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/administration/workflow(sidenav:manage/bucket/999)');
+        expect(navigateByUrlCall.args[0]).toBe('administration/workflow(sidenav:manage/bucket/999)');
     });
 
     it('should execute a `delete` action on a user.', function () {
@@ -879,7 +879,7 @@ describe('NfRegistry Service w/ Angular testing utils', function () {
 
         //assertions
         const navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/administration/users(sidenav:manage/user/999)');
+        expect(navigateByUrlCall.args[0]).toBe('administration/users(sidenav:manage/user/999)');
     });
 
     it('should execute a `delete` action on a group.', function () {
@@ -931,7 +931,7 @@ describe('NfRegistry Service w/ Angular testing utils', function () {
 
         //assertions
         const navigateByUrlCall = router.navigateByUrl.calls.first();
-        expect(navigateByUrlCall.args[0]).toBe('/nifi-registry/administration/users(sidenav:manage/group/999)');
+        expect(navigateByUrlCall.args[0]).toBe('administration/users(sidenav:manage/group/999)');
     });
 
     it('should filter buckets by name.', function () {
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.html b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.html
index 33e76d1..9f63abc 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.html
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.html
@@ -19,7 +19,13 @@
 <html>
 <head>
     <title>NiFi Registry</title>
-    <base href="/">
+    <script type="text/javascript">
+        var pathname = document.location.pathname;
+        var appRootIndex = document.location.pathname.indexOf('/nifi-registry/');
+        var base = document.createElement('base');
+        base.setAttribute('href', document.location.pathname.substring(0, appRootIndex) + '/nifi-registry/');
+        document.head.appendChild(base);
+    </script>
     <meta charset='UTF-8'>
     <meta name='viewport' content='width=device-width, initial-scale=1'>
     <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/theming/_structureElements.scss b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/theming/_structureElements.scss
index a7638ff..88ea7df 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/theming/_structureElements.scss
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/theming/_structureElements.scss
@@ -16,12 +16,12 @@
  */
 
 body {
-  background: $grey12 url('/nifi-registry/assets/images/registry-logo-web-app.svg') no-repeat center center;
+  background: $grey12 url('assets/images/registry-logo-web-app.svg') no-repeat center center;
   background-size: 40%;
 }
 
 #nifi-registry-login-perspective {
-  background: $grey12 url('/nifi-registry/assets/images/registry-logo-web-app.svg') no-repeat center center;
+  background: $grey12 url('assets/images/registry-logo-web-app.svg') no-repeat center center;
   background-size: 40%;
   position: absolute;
   top: 0;
@@ -31,7 +31,7 @@ body {
 }
 
 #nifi-registry-not-found-perspective {
-  background: $grey12 url('/nifi-registry/assets/images/registry-logo-web-app.svg') no-repeat center center;
+  background: $grey12 url('assets/images/registry-logo-web-app.svg') no-repeat center center;
   background-size: 40%;
   position: absolute;
   top: 0;
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webpack.common.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webpack.common.js
index 713900e..9504d6d 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webpack.common.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webpack.common.js
@@ -41,8 +41,7 @@ module.exports = {
     output: {
         // add the content hash for auto cache-busting
         filename: '[name].[contenthash].js',
-        path: path.resolve(__dirname, './'),
-        publicPath: 'nifi-registry/'
+        path: path.resolve(__dirname, './')
     },
 
     optimization: {
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webpack.dev.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webpack.dev.js
index fed85f3..503a09a 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webpack.dev.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webpack.dev.js
@@ -45,9 +45,6 @@ module.exports = merge(commonConfig, {
 
         historyApiFallback: true,
 
-        // The bundled files will be available in the browser under this path.
-        publicPath: '/nifi-registry/',
-
         // Enable gzip compression for everything served
         compress: true,
 


[nifi-registry] 02/03: NIFIREG-295 - use hash for routing

Posted by bb...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bbende pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-registry.git

commit a1105881b5b9b6e0a3f060c4d36fde7298a9d848
Author: Rob Fellows <ro...@gmail.com>
AuthorDate: Thu Aug 15 11:01:54 2019 -0400

    NIFIREG-295 - use hash for routing
    
    Signed-off-by: Bryan Bende <bb...@apache.org>
---
 .../nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js     | 2 +-
 .../nifi-registry-web-ui/src/main/webapp/template.dev.html         | 1 -
 .../nifi-registry-web-ui/src/main/webapp/template.html             | 7 -------
 3 files changed, 1 insertion(+), 9 deletions(-)

diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
index 1b1b8d0..70630e6 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/nf-registry.routes.js
@@ -109,6 +109,6 @@ const NfRegistryRoutes = new RouterModule.forRoot([{
     component: NfRegistryManageBucket,
     canActivate: [NfRegistryWorkflowsAdministrationAuthGuard],
     outlet: 'sidenav'
-}]);
+}], { useHash: true });
 
 export default NfRegistryRoutes;
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.dev.html b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.dev.html
index 33e76d1..c3f06c0 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.dev.html
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.dev.html
@@ -19,7 +19,6 @@
 <html>
 <head>
     <title>NiFi Registry</title>
-    <base href="/">
     <meta charset='UTF-8'>
     <meta name='viewport' content='width=device-width, initial-scale=1'>
     <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
diff --git a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.html b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.html
index 9f63abc..c3f06c0 100644
--- a/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.html
+++ b/nifi-registry-core/nifi-registry-web-ui/src/main/webapp/template.html
@@ -19,13 +19,6 @@
 <html>
 <head>
     <title>NiFi Registry</title>
-    <script type="text/javascript">
-        var pathname = document.location.pathname;
-        var appRootIndex = document.location.pathname.indexOf('/nifi-registry/');
-        var base = document.createElement('base');
-        base.setAttribute('href', document.location.pathname.substring(0, appRootIndex) + '/nifi-registry/');
-        document.head.appendChild(base);
-    </script>
     <meta charset='UTF-8'>
     <meta name='viewport' content='width=device-width, initial-scale=1'>
     <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>