mirror of
https://github.com/bitwarden/browser
synced 2025-12-14 23:33:31 +00:00
docs(redirect-guard): [BEEEP] Document redirectGuard (#15196)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
export * from "./auth.guard";
|
||||
export * from "./active-auth.guard";
|
||||
export * from "./lock.guard";
|
||||
export * from "./redirect.guard";
|
||||
export * from "./redirect/redirect.guard";
|
||||
export * from "./tde-decryption-required.guard";
|
||||
export * from "./unauth.guard";
|
||||
|
||||
53
libs/angular/src/auth/guards/redirect/README.md
Normal file
53
libs/angular/src/auth/guards/redirect/README.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# Redirect Guard
|
||||
|
||||
The `redirectGuard` redirects the user based on their `AuthenticationStatus`. It is applied to the root route (`/`).
|
||||
|
||||
<br>
|
||||
|
||||
### Order of Operations
|
||||
|
||||
The `redirectGuard` will redirect the user based on the following checks, _in order_:
|
||||
|
||||
- **`AuthenticationStatus.LoggedOut`** → redirect to `/login`
|
||||
- **`AuthenticationStatus.Unlocked`** → redirect to `/vault`
|
||||
- **`AuthenticationStatus.Locked`**
|
||||
- **TDE Locked State** → redirect to `/login-initiated`
|
||||
- A user is in a TDE Locked State if they meet all 3 of the following conditions
|
||||
1. Auth status is `Locked`
|
||||
2. TDE is enabled
|
||||
3. User has never had a user key (that is, user has not unlocked/decrypted yet)
|
||||
- **Standard Locked State** → redirect to `/lock`
|
||||
|
||||
<br>
|
||||
|
||||
| Order | AuthenticationStatus | Redirect To |
|
||||
| ----- | ------------------------------------------------------------------------------- | ------------------ |
|
||||
| 1 | `LoggedOut` | `/login` |
|
||||
| 2 | `Unlocked` | `/vault` |
|
||||
| 3 | **TDE Locked State** <br> `Locked` + <br> `tdeEnabled` + <br> `!everHadUserKey` | `/login-initiated` |
|
||||
| 4 | **Standard Locked State** <br> `Locked` | `/lock` |
|
||||
|
||||
<br>
|
||||
|
||||
### Default Routes and Route Overrides
|
||||
|
||||
The default redirect routes are mapped to object properties:
|
||||
|
||||
```typescript
|
||||
const defaultRoutes: RedirectRoutes = {
|
||||
loggedIn: "/vault",
|
||||
loggedOut: "/login",
|
||||
locked: "/lock",
|
||||
notDecrypted: "/login-initiated",
|
||||
};
|
||||
```
|
||||
|
||||
But when applying the guard to the root route, the developer can override specific redirect routes by passing in a custom object. This is useful for subtle differences in client-specific routing:
|
||||
|
||||
```typescript
|
||||
// app-routing.module.ts (Browser Extension)
|
||||
{
|
||||
path: "",
|
||||
canActivate: [redirectGuard({ loggedIn: "/tabs/current"})],
|
||||
}
|
||||
```
|
||||
@@ -25,12 +25,14 @@ const defaultRoutes: RedirectRoutes = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Guard that consolidates all redirection logic, should be applied to root route.
|
||||
* Redirects the user to the appropriate route based on their `AuthenticationStatus`.
|
||||
* This guard should be applied to the root route.
|
||||
*
|
||||
* TODO: This should return Observable<boolean | UrlTree> once we can get rid of all the promises
|
||||
*/
|
||||
export function redirectGuard(overrides: Partial<RedirectRoutes> = {}): CanActivateFn {
|
||||
const routes = { ...defaultRoutes, ...overrides };
|
||||
|
||||
return async (route) => {
|
||||
const authService = inject(AuthService);
|
||||
const keyService = inject(KeyService);
|
||||
@@ -41,16 +43,21 @@ export function redirectGuard(overrides: Partial<RedirectRoutes> = {}): CanActiv
|
||||
|
||||
const authStatus = await authService.getAuthStatus();
|
||||
|
||||
// Logged Out
|
||||
if (authStatus === AuthenticationStatus.LoggedOut) {
|
||||
return router.createUrlTree([routes.loggedOut], { queryParams: route.queryParams });
|
||||
}
|
||||
|
||||
// Unlocked
|
||||
if (authStatus === AuthenticationStatus.Unlocked) {
|
||||
return router.createUrlTree([routes.loggedIn], { queryParams: route.queryParams });
|
||||
}
|
||||
|
||||
// If locked, TDE is enabled, and the user hasn't decrypted yet, then redirect to the
|
||||
// login decryption options component.
|
||||
// Locked: TDE Locked State
|
||||
// - If user meets all 3 of the following conditions:
|
||||
// 1. Auth status is Locked
|
||||
// 2. TDE is enabled
|
||||
// 3. User has never had a user key (has not decrypted yet)
|
||||
const tdeEnabled = await firstValueFrom(deviceTrustService.supportsDeviceTrust$);
|
||||
const userId = await firstValueFrom(accountService.activeAccount$.pipe(getUserId));
|
||||
const everHadUserKey = await firstValueFrom(keyService.everHadUserKey$(userId));
|
||||
@@ -64,6 +71,7 @@ export function redirectGuard(overrides: Partial<RedirectRoutes> = {}): CanActiv
|
||||
return router.createUrlTree([routes.notDecrypted], { queryParams: route.queryParams });
|
||||
}
|
||||
|
||||
// Locked: Standard Locked State
|
||||
if (authStatus === AuthenticationStatus.Locked) {
|
||||
return router.createUrlTree([routes.locked], { queryParams: route.queryParams });
|
||||
}
|
||||
Reference in New Issue
Block a user