fix(licensing): render licensing pages like any other route
An activated app that loaded a licensing URL (bookmark, browser reload, or cy.visit in a spec) was redirected to /home as soon as the startupservice response landed, and LicensingGuard redirected there too while isAppActivated was still null. Both redirects meant the page only existed for the window between the router rendering it and startup completing - so the same link worked or failed depending on whether a key was installed. Drop both: the guard keeps only canDeactivate, which still holds a user on the registration page and blocks leaving a locked app. Unactivated apps are still sent to licensing/key from any other page.
This commit is contained in:
1 parent
c3985b941b
commit
cb3f806d6b
4 files changed
+50
-37
No files matched your search
@@ -7,7 +7,6 @@ const routes: Routes = [
|
||||
{
|
||||
path: ':action',
|
||||
component: LicensingComponent,
|
||||
canActivate: [LicensingGuard],
|
||||
canDeactivate: [LicensingGuard]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,40 +1,15 @@
|
||||
import {
|
||||
ActivatedRouteSnapshot,
|
||||
RouterStateSnapshot,
|
||||
Router
|
||||
} from '@angular/router'
|
||||
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'
|
||||
import { LicensingComponent } from '../licensing/licensing.component'
|
||||
import { Injectable } from '@angular/core'
|
||||
import { LicenceService } from '../services/licence.service'
|
||||
|
||||
@Injectable()
|
||||
export class LicensingGuard {
|
||||
constructor(
|
||||
private licenceService: LicenceService,
|
||||
private router: Router
|
||||
) {}
|
||||
|
||||
canActivate(
|
||||
currentRoute: ActivatedRouteSnapshot,
|
||||
currentState: RouterStateSnapshot
|
||||
): boolean {
|
||||
if (currentState?.root.queryParams.force !== undefined) return true
|
||||
|
||||
if (currentState?.url.includes('licensing/update')) {
|
||||
if (!!this.licenceService.isAppActivated) return true
|
||||
}
|
||||
|
||||
if (
|
||||
this.licenceService.isAppActivated.value !== null &&
|
||||
this.licenceService.isAppActivated.value === false
|
||||
) {
|
||||
return true
|
||||
} else {
|
||||
this.router.navigateByUrl('/home')
|
||||
return false
|
||||
}
|
||||
}
|
||||
constructor(private licenceService: LicenceService) {}
|
||||
|
||||
// Leaving the registration page would strand a user who has not registered
|
||||
// yet, so it stays blocked until registration completes; a locked app
|
||||
// cannot be navigated away from either.
|
||||
canDeactivate(
|
||||
component: LicensingComponent,
|
||||
currentRoute: ActivatedRouteSnapshot,
|
||||
@@ -48,8 +23,5 @@ export class LicensingGuard {
|
||||
if (!!this.licenceService.appLocked.value) return false
|
||||
|
||||
return true
|
||||
if (this.licenceService.isAppActivated.value === null) return true
|
||||
|
||||
return !!this.licenceService.isAppActivated.value
|
||||
}
|
||||
}
|
||||
@@ -178,3 +178,48 @@ describe('AppService - startup retry', () => {
|
||||
expect(deps.licenceService.isAppActivated.value).toBeFalse()
|
||||
})
|
||||
})
|
||||
|
||||
// Licensing pages are ordinary pages: an activated app that loads one of their
|
||||
// URLs directly (bookmark, browser reload, or a spec's cy.visit) must stay
|
||||
// there instead of being bounced to /home once the startupservice response
|
||||
// lands. Unactivated apps are still pushed to the key page from anywhere else.
|
||||
describe('AppService - licensing routes', () => {
|
||||
it('leaves an activated app on a licensing URL instead of redirecting to /home', async () => {
|
||||
const deps = buildDeps()
|
||||
deps.sasService.request.and.resolveTo(validStartupResponse())
|
||||
deps.licenceService.isAppActivated.next(true)
|
||||
deps.router.url = '/#/licensing/update'
|
||||
|
||||
const appService = buildAppService(deps)
|
||||
await appService.startUpData()
|
||||
|
||||
expect(deps.eventService.startupDataLoaded).toHaveBeenCalled()
|
||||
expect(deps.router.navigateByUrl).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('sends an unactivated app on any other page to the licence key page', async () => {
|
||||
const deps = buildDeps()
|
||||
deps.sasService.request.and.resolveTo(validStartupResponse())
|
||||
deps.licenceService.isAppActivated.next(false)
|
||||
deps.router.url = '/#/home/tables'
|
||||
|
||||
const appService = buildAppService(deps)
|
||||
await appService.startUpData()
|
||||
|
||||
expect(deps.router.navigateByUrl).toHaveBeenCalledWith(
|
||||
'/licensing/key?error=missing&force=true'
|
||||
)
|
||||
})
|
||||
|
||||
it('does not redirect an unactivated app that is already on a licensing page', async () => {
|
||||
const deps = buildDeps()
|
||||
deps.sasService.request.and.resolveTo(validStartupResponse())
|
||||
deps.licenceService.isAppActivated.next(false)
|
||||
deps.router.url = '/#/licensing/register'
|
||||
|
||||
const appService = buildAppService(deps)
|
||||
await appService.startUpData()
|
||||
|
||||
expect(deps.router.navigateByUrl).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
@@ -248,9 +248,6 @@ export class AppService {
|
||||
) {
|
||||
this.router.navigateByUrl('/licensing/key?error=missing&force=true')
|
||||
}
|
||||
} else {
|
||||
if (this.router.url.includes('licensing'))
|
||||
this.router.navigateByUrl('/home')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user