( options?: SignInCheckOptionsBasic | SignInCheckOptionsClaimsObject | SignInCheckOptionsClaimsValidator )
| 122 | * ``` |
| 123 | */ |
| 124 | export function useSigninCheck( |
| 125 | options?: SignInCheckOptionsBasic | SignInCheckOptionsClaimsObject | SignInCheckOptionsClaimsValidator |
| 126 | ): ObservableStatus<SigninCheckResult> { |
| 127 | // If both `requiredClaims` and `validateCustomClaims` are provided, we won't know which one to use |
| 128 | if (options?.hasOwnProperty('requiredClaims') && options?.hasOwnProperty('validateCustomClaims')) { |
| 129 | throw new Error('Cannot have both "requiredClaims" and "validateCustomClaims". Use one or the other.'); |
| 130 | } |
| 131 | |
| 132 | const auth = useAuth(); |
| 133 | |
| 134 | // ObservableId should change for different options configurations to ensure no cache collisions |
| 135 | let observableId = `auth:signInCheck:${auth.name}::forceRefresh:${!!options?.forceRefresh}`; |
| 136 | if (options?.forceRefresh) { |
| 137 | observableId = `${observableId}:forceRefresh:${options.forceRefresh}`; |
| 138 | } |
| 139 | if (options?.hasOwnProperty('requiredClaims')) { |
| 140 | observableId = `${observableId}:requiredClaims:${JSON.stringify((options as SignInCheckOptionsClaimsObject).requiredClaims)}`; |
| 141 | } else if (options?.hasOwnProperty('validateCustomClaims')) { |
| 142 | // TODO(jamesdaniels): Check if stringifying this function breaks in IE11 |
| 143 | observableId = `${observableId}:validateCustomClaims:${JSON.stringify((options as SignInCheckOptionsClaimsValidator).validateCustomClaims)}`; |
| 144 | } |
| 145 | |
| 146 | const observable = user(auth).pipe( |
| 147 | switchMap((user) => { |
| 148 | if (!user) { |
| 149 | const result: SigninCheckResult = { signedIn: false, hasRequiredClaims: false, errors: {}, user: null }; |
| 150 | return of(result); |
| 151 | } else if (options && (options.hasOwnProperty('requiredClaims') || options.hasOwnProperty('validateCustomClaims'))) { |
| 152 | return from(user.getIdTokenResult(options?.forceRefresh ?? false)).pipe( |
| 153 | map((idTokenResult) => { |
| 154 | let validator: ClaimsValidator; |
| 155 | |
| 156 | if (options.hasOwnProperty('requiredClaims')) { |
| 157 | validator = getClaimsObjectValidator((options as SignInCheckOptionsClaimsObject).requiredClaims); |
| 158 | } else { |
| 159 | validator = (options as SignInCheckOptionsClaimsValidator).validateCustomClaims; |
| 160 | } |
| 161 | |
| 162 | const { hasRequiredClaims, errors } = validator(idTokenResult.claims); |
| 163 | |
| 164 | const result: SigninCheckResult = { signedIn: true, hasRequiredClaims, errors, user: user }; |
| 165 | return result; |
| 166 | }) |
| 167 | ); |
| 168 | } else { |
| 169 | // If no claims are provided to be checked, `hasRequiredClaims` is true |
| 170 | const result: SigninCheckResult = { signedIn: true, hasRequiredClaims: true, errors: {}, user: user }; |
| 171 | return of(result); |
| 172 | } |
| 173 | }) |
| 174 | ); |
| 175 | |
| 176 | return useObservable(observableId, observable); |
| 177 | } |
| 178 | |
| 179 | function getClaimsObjectValidator(requiredClaims: Claims): ClaimsValidator { |
| 180 | return function claimsObjectValidator(userClaims) { |
no test coverage detected