[Feature Request] authCanMatchGuard + helpers
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Estancado
- Stack tecnológico
- angular, firebase, typescript
- Área
- authentication, frontend
Línea de trabajo
Lee primero src/auth-guard/auth-guard.ts y site/src/auth/route-guards.md; después, compáralos con la implementación propuesta de auth-can-match.guard.ts. La tarea estará terminada cuando el guard canMatch funcional y sus helpers estén integrados en AngularFire y se hayan añadido pruebas para su comportamiento de autenticación y redirección.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Feature Request - authCanMatchGuard + helpers
Description
The current auth-guard provided with angular fire is still using the now deprecated class based approach and targets the canActivate property on route definitions.
To freshen things up a bit, I have generated a new guard which utilizes the new functional approach and targets the newer canMatch route definition property. This has the added benefit of preventing components from being unnecessarily loaded which seems to work well and should be more performant.
I based the new code off of the previous implementation documented here. You will notice similarities with the previous guard code here. Would love to see this incorporated into the AngularFire package but honestly I'm too lazy to write tests 😅 so if someone would be interested in owning that and collaborating, I'd be happy to open up a PR.
Code
auth-can-match.guard.ts
import { inject } from '@angular/core';
import { Auth, user, User } from '@angular/fire/auth';
import { CanMatchFn, Route, Router, UrlSegment } from '@angular/router';
import { Observable, of, pipe, UnaryFunction } from 'rxjs';
import { map, switchMap, take } from 'rxjs/operators';
/** Utility type to allow for adding an additional property to the CanMatchFn type */
type ExtendFn<BaseFnT, AddPT extends any[]> = BaseFnT extends (...a: infer P) => infer R
? (...a: [...P, ...AddPT]) => R
: never
export type AuthPipe = UnaryFunction<Observable<User | null>, Observable<boolean | string | any[]>>;
export const authCanMatchGuard: ExtendFn<CanMatchFn, [authPipe: AuthPipe]> = (route, segments, authPipe?) => {
const auth = inject(Auth)
const user$ = user(auth)
const router = inject(Router)
const authPipeFactory = authPipe
? authPipe
: loggedIn
return user$
.pipe(
take(1),
authPipeFactory,
map(can => {
if (typeof can === 'boolean') {
return can;
} else if (Array.isArray(can)) {
return router.createUrlTree(can)
} else {
return router.parseUrl(can)
}
})
)
}
/** canMatch helper to be used with spread operator to make route definitions more concise.
* @example
* const redirectUnauthorizedToLogin = redirectUnauthorizedTo(['login'])
* ...
* export const routes: Routes = [
* {
* ...authCanMatch(redirectUnauthorizedToLogin)
* path: 'authProtectedRoute'
* },
*/
export const authCanMatch = (authPipe: AuthPipe) =>
({ canMatch: [(route: Route, segments: UrlSegment[]) => authCanMatchGuard(route, segments, authPipe)] })
/** Predefined auth guard helper pipes. So friendly & helpful 😍 */
export const loggedIn: AuthPipe = map(user => !!user)
export const isNotAnonymous: AuthPipe = map(user => !!user && !user.isAnonymous)
export const idTokenResult = switchMap((user: User | null) => user ? user.getIdTokenResult() : of(null))
export const emailVerified: AuthPipe = map(user => !!user && user.emailVerified)
export const customClaims = pipe(idTokenResult, map(idTokenResult => idTokenResult ? idTokenResult.claims : []))
export const hasCustomClaim: (claim: string) => AuthPipe =
// eslint-disable-next-line no-prototype-builtins
(claim) => pipe(customClaims, map(claims => claims.hasOwnProperty(claim)))
export const redirectUnauthorizedTo: (redirect: string | any[]) => AuthPipe =
(redirect) => pipe(loggedIn, map(loggedIn => loggedIn || redirect))
export const redirectLoggedInTo: (redirect: string | any[]) => AuthPipe =
(redirect) => pipe(loggedIn, map(loggedIn => loggedIn && redirect || true))
- Lenguaje dominante
- TypeScript
- Estrellas
- 7.8k
- Forks
- 2.2k
- Merge medio
- 3 d 6 h
- PR fusionados (30 d)
- 5
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de angular/angularfire
-
comp: build/pipeline type: bug version: current (v17+)
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
angular/angularfire#3766 ·
-
comp: schematics type: bug version: current (v17+)
Dificultad 3/5 1-2 días Aptitud para principiantes 76/100
angular/angularfire#3768 ·
-
comp: docs type: chore version: current (v17+)
Dificultad 4/5 3-5 días Aptitud para principiantes 58/100
angular/angularfire#3764 ·
-
comp: firestore comp: ssr priority: P0 (critical) type: feature version: current (v17+)
angular/angularfire#3757 · 1 asignado ·
-
Six `firebase` entry points have no `@angular/fire` equivalent, so their exports are unreachable Abiertocomp: core type: feature
angular/angularfire#3755 · 1 asignado ·
Todos los issues de angular/angularfire
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
-
bug v2
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
modelcontextprotocol/inspector#2458 · 1 comentario ·
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 75/100
railmapgen/rmp-gallery#4068 ·
-
Mend: dependency security vulnerability status: needs triage 🕵️♀️
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
carbon-design-system/ibm-products#9907 ·