diff --git a/frontend/projects/shared-meet-components/src/lib/guards/index.ts b/frontend/projects/shared-meet-components/src/lib/guards/index.ts index 2d5f3e5..eb8bf25 100644 --- a/frontend/projects/shared-meet-components/src/lib/guards/index.ts +++ b/frontend/projects/shared-meet-components/src/lib/guards/index.ts @@ -5,3 +5,4 @@ export * from './application-mode.guard'; export * from './participant-name.guard'; export * from './replace-moderator-secret.guard'; export * from './room-creator.guard'; +export * from './run-serially.guard'; diff --git a/frontend/projects/shared-meet-components/src/lib/guards/run-serially.guard.ts b/frontend/projects/shared-meet-components/src/lib/guards/run-serially.guard.ts new file mode 100644 index 0000000..645814e --- /dev/null +++ b/frontend/projects/shared-meet-components/src/lib/guards/run-serially.guard.ts @@ -0,0 +1,36 @@ +import { EnvironmentInjector, inject, runInInjectionContext } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivateFn, GuardResult, RouterStateSnapshot } from '@angular/router'; +import { isObservable, lastValueFrom } from 'rxjs'; + +/** + * This guard is used to run multiple guards serially. + * + * @param guards List of guards to run serially. + * @returns A guard that runs the provided guards serially. + */ +export const runGuardsSerially = (...guards: CanActivateFn[]): CanActivateFn => { + return async (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => { + const injector = inject(EnvironmentInjector); + + for (const guard of guards) { + const result = runInInjectionContext(injector, () => guard(route, state)); + let resolvedResult: GuardResult; + + if (result instanceof Promise) { + resolvedResult = await result; + } else if (isObservable(result)) { + resolvedResult = await lastValueFrom(result); + } else { + resolvedResult = result; + } + + if (typeof resolvedResult === 'boolean' && !resolvedResult) { + return false; + } else if (typeof resolvedResult !== 'boolean') { + return resolvedResult; + } + } + + return true; + }; +};