diff --git a/jslib b/jslib index 87e273252b..91081d9232 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 87e273252be42dab90d9a33857fe7755f378338b +Subproject commit 91081d92327da22ab3be88a60f8b71be26933370 diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d56cef6918..2a8d165612 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -37,10 +37,14 @@ import { ToolsComponent } from './tools/tools.component'; import { VaultComponent } from './vault/vault.component'; +import { OrganizationGuardService } from './services/organization-guard.service'; +import { OrganizationTypeGuardService } from './services/organization-type-guard.service'; import { UnauthGuardService } from './services/unauth-guard.service'; import { AuthGuardService } from 'jslib/angular/services/auth-guard.service'; +import { OrganizationUserType } from 'jslib/enums/organizationUserType'; + const routes: Routes = [ { path: '', @@ -56,36 +60,34 @@ const routes: Routes = [ { path: '', component: UserLayoutComponent, + canActivate: [AuthGuardService], children: [ - { path: 'vault', component: VaultComponent, canActivate: [AuthGuardService] }, + { path: 'vault', component: VaultComponent }, { path: 'settings', component: SettingsComponent, children: [ { path: '', pathMatch: 'full', redirectTo: 'account' }, - { path: 'account', component: AccountComponent, canActivate: [AuthGuardService] }, - { path: 'options', component: OptionsComponent, canActivate: [AuthGuardService] }, - { path: 'domain-rules', component: DomainRulesComponent, canActivate: [AuthGuardService] }, - { path: 'two-factor', component: TwoFactorSetupComponent, canActivate: [AuthGuardService] }, - { path: 'premium', component: PremiumComponent, canActivate: [AuthGuardService] }, - { path: 'billing', component: UserBillingComponent, canActivate: [AuthGuardService] }, - { path: 'organizations', component: OrganizationsComponent, canActivate: [AuthGuardService] }, - { - path: 'create-organization', - component: CreateOrganizationComponent, - canActivate: [AuthGuardService], - }, + { path: 'account', component: AccountComponent }, + { path: 'options', component: OptionsComponent }, + { path: 'domain-rules', component: DomainRulesComponent }, + { path: 'two-factor', component: TwoFactorSetupComponent }, + { path: 'premium', component: PremiumComponent }, + { path: 'billing', component: UserBillingComponent }, + { path: 'organizations', component: OrganizationsComponent }, + { path: 'create-organization', component: CreateOrganizationComponent }, ], }, { path: 'tools', component: ToolsComponent, + canActivate: [AuthGuardService], children: [ { path: '', pathMatch: 'full', redirectTo: 'generator' }, - { path: 'import', component: ImportComponent, canActivate: [AuthGuardService] }, - { path: 'export', component: ExportComponent, canActivate: [AuthGuardService] }, - { path: 'generator', component: PasswordGeneratorComponent, canActivate: [AuthGuardService] }, - { path: 'breach-report', component: BreachReportComponent, canActivate: [AuthGuardService] }, + { path: 'import', component: ImportComponent }, + { path: 'export', component: ExportComponent }, + { path: 'generator', component: PasswordGeneratorComponent }, + { path: 'breach-report', component: BreachReportComponent }, ], }, ], @@ -93,16 +95,19 @@ const routes: Routes = [ { path: 'organizations/:organizationId', component: OrganizationLayoutComponent, + canActivate: [AuthGuardService, OrganizationGuardService], children: [ { path: '', pathMatch: 'full', redirectTo: 'vault' }, - { path: 'vault', component: OrgVaultComponent, canActivate: [AuthGuardService] }, + { path: 'vault', component: OrgVaultComponent }, { path: 'tools', component: OrgToolsComponent, + canActivate: [OrganizationTypeGuardService], + data: { allowedTypes: [OrganizationUserType.Owner, OrganizationUserType.Admin] }, children: [ { path: '', pathMatch: 'full', redirectTo: 'export' }, - // { path: 'import', component: ImportComponent, canActivate: [AuthGuardService] }, - { path: 'export', component: OrgExportComponent, canActivate: [AuthGuardService] }, + // { path: 'import', component: ImportComponent }, + { path: 'export', component: OrgExportComponent }, ], }, ], diff --git a/src/app/services/organization-guard.service.ts b/src/app/services/organization-guard.service.ts new file mode 100644 index 0000000000..4ee4b94756 --- /dev/null +++ b/src/app/services/organization-guard.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + CanActivate, + Router, +} from '@angular/router'; + +import { UserService } from 'jslib/abstractions/user.service'; + +@Injectable() +export class OrganizationGuardService implements CanActivate { + constructor(private userService: UserService, private router: Router) { } + + async canActivate(route: ActivatedRouteSnapshot) { + const org = await this.userService.getOrganization(route.params.organizationId); + if (org == null) { + this.router.navigate(['/']); + return false; + } + + return true; + } +} diff --git a/src/app/services/organization-type-guard.service.ts b/src/app/services/organization-type-guard.service.ts new file mode 100644 index 0000000000..13b3703e81 --- /dev/null +++ b/src/app/services/organization-type-guard.service.ts @@ -0,0 +1,26 @@ +import { Injectable } from '@angular/core'; +import { + ActivatedRouteSnapshot, + CanActivate, + Router, +} from '@angular/router'; + +import { UserService } from 'jslib/abstractions/user.service'; + +import { OrganizationUserType } from 'jslib/enums/organizationUserType'; + +@Injectable() +export class OrganizationTypeGuardService implements CanActivate { + constructor(private userService: UserService, private router: Router) { } + + async canActivate(route: ActivatedRouteSnapshot) { + const org = await this.userService.getOrganization(route.parent.params.organizationId); + const allowedTypes = route.data['allowedTypes'] as OrganizationUserType[]; + if (allowedTypes == null || allowedTypes.indexOf(org.type) === -1) { + this.router.navigate(['/organizations', org.id]); + return false; + } + + return true; + } +} diff --git a/src/app/services/services.module.ts b/src/app/services/services.module.ts index c178772865..45d6aa0210 100644 --- a/src/app/services/services.module.ts +++ b/src/app/services/services.module.ts @@ -11,6 +11,8 @@ import { I18nService } from '../../services/i18n.service'; import { MemoryStorageService } from '../../services/memoryStorage.service'; import { WebPlatformUtilsService } from '../../services/webPlatformUtils.service'; +import { OrganizationGuardService } from './organization-guard.service'; +import { OrganizationTypeGuardService } from './organization-type-guard.service'; import { RouterService } from './router.service'; import { UnauthGuardService } from './unauth-guard.service'; @@ -142,6 +144,8 @@ export function initFactory(): Function { providers: [ ValidationService, AuthGuardService, + OrganizationGuardService, + OrganizationTypeGuardService, UnauthGuardService, RouterService, { provide: AuditServiceAbstraction, useValue: auditService }, diff --git a/src/scss/styles.scss b/src/scss/styles.scss index 7fef3c0b43..a663a5f428 100644 --- a/src/scss/styles.scss +++ b/src/scss/styles.scss @@ -595,7 +595,7 @@ app-user-billing { a { color: $body-color; - &:hover:not(.active) { + &:not(.active) { border-color: transparent; }