UNPKG

16 kBTypeScriptView Raw
1import { NgZone, OnDestroy } from '@angular/core';
2import { HttpClient, HttpHeaders } from '@angular/common/http';
3import { Observable, Subject, Subscription } from 'rxjs';
4import { DateTimeProvider } from './date-time-provider';
5import { ValidationHandler, ValidationParams } from './token-validation/validation-handler';
6import { UrlHelperService } from './url-helper.service';
7import { OAuthEvent, OAuthSuccessEvent } from './events';
8import { OAuthLogger, OAuthStorage, LoginOptions, ParsedIdToken, OidcDiscoveryDoc, TokenResponse } from './types';
9import { AuthConfig } from './auth.config';
10import { HashHandler } from './token-validation/hash-handler';
11import * as i0 from "@angular/core";
12/**
13 * Service for logging in and logging out with
14 * OIDC and OAuth2. Supports implicit flow and
15 * password flow.
16 */
17export declare class OAuthService extends AuthConfig implements OnDestroy {
18 protected ngZone: NgZone;
19 protected http: HttpClient;
20 protected config: AuthConfig;
21 protected urlHelper: UrlHelperService;
22 protected logger: OAuthLogger;
23 protected crypto: HashHandler;
24 protected dateTimeService: DateTimeProvider;
25 /**
26 * The ValidationHandler used to validate received
27 * id_tokens.
28 */
29 tokenValidationHandler: ValidationHandler;
30 /**
31 * @internal
32 * Deprecated: use property events instead
33 */
34 discoveryDocumentLoaded: boolean;
35 /**
36 * @internal
37 * Deprecated: use property events instead
38 */
39 discoveryDocumentLoaded$: Observable<OidcDiscoveryDoc>;
40 /**
41 * Informs about events, like token_received or token_expires.
42 * See the string enum EventType for a full list of event types.
43 */
44 events: Observable<OAuthEvent>;
45 /**
46 * The received (passed around) state, when logging
47 * in with implicit flow.
48 */
49 state?: string;
50 protected eventsSubject: Subject<OAuthEvent>;
51 protected discoveryDocumentLoadedSubject: Subject<OidcDiscoveryDoc>;
52 protected silentRefreshPostMessageEventListener: EventListener;
53 protected grantTypesSupported: Array<string>;
54 protected _storage: OAuthStorage;
55 protected accessTokenTimeoutSubscription: Subscription;
56 protected idTokenTimeoutSubscription: Subscription;
57 protected tokenReceivedSubscription: Subscription;
58 protected automaticRefreshSubscription: Subscription;
59 protected sessionCheckEventListener: EventListener;
60 protected jwksUri: string;
61 protected sessionCheckTimer: any;
62 protected silentRefreshSubject: string;
63 protected inImplicitFlow: boolean;
64 protected saveNoncesInLocalStorage: boolean;
65 private document;
66 constructor(ngZone: NgZone, http: HttpClient, storage: OAuthStorage, tokenValidationHandler: ValidationHandler, config: AuthConfig, urlHelper: UrlHelperService, logger: OAuthLogger, crypto: HashHandler, document: Document, dateTimeService: DateTimeProvider);
67 private checkLocalStorageAccessable;
68 /**
69 * Use this method to configure the service
70 * @param config the configuration
71 */
72 configure(config: AuthConfig): void;
73 protected configChanged(): void;
74 restartSessionChecksIfStillLoggedIn(): void;
75 protected restartRefreshTimerIfStillLoggedIn(): void;
76 protected setupSessionCheck(): void;
77 /**
78 * Will setup up silent refreshing for when the token is
79 * about to expire. When the user is logged out via this.logOut method, the
80 * silent refreshing will pause and not refresh the tokens until the user is
81 * logged back in via receiving a new token.
82 * @param params Additional parameter to pass
83 * @param listenTo Setup automatic refresh of a specific token type
84 */
85 setupAutomaticSilentRefresh(params?: object, listenTo?: 'access_token' | 'id_token' | 'any', noPrompt?: boolean): void;
86 protected refreshInternal(params: any, noPrompt: any): Promise<TokenResponse | OAuthEvent>;
87 /**
88 * Convenience method that first calls `loadDiscoveryDocument(...)` and
89 * directly chains using the `then(...)` part of the promise to call
90 * the `tryLogin(...)` method.
91 *
92 * @param options LoginOptions to pass through to `tryLogin(...)`
93 */
94 loadDiscoveryDocumentAndTryLogin(options?: LoginOptions): Promise<boolean>;
95 /**
96 * Convenience method that first calls `loadDiscoveryDocumentAndTryLogin(...)`
97 * and if then chains to `initLoginFlow()`, but only if there is no valid
98 * IdToken or no valid AccessToken.
99 *
100 * @param options LoginOptions to pass through to `tryLogin(...)`
101 */
102 loadDiscoveryDocumentAndLogin(options?: LoginOptions & {
103 state?: string;
104 }): Promise<boolean>;
105 protected debug(...args: any[]): void;
106 protected validateUrlFromDiscoveryDocument(url: string): string[];
107 protected validateUrlForHttps(url: string): boolean;
108 protected assertUrlNotNullAndCorrectProtocol(url: string | undefined, description: string): void;
109 protected validateUrlAgainstIssuer(url: string): boolean;
110 protected setupRefreshTimer(): void;
111 protected setupExpirationTimers(): void;
112 protected setupAccessTokenTimer(): void;
113 protected setupIdTokenTimer(): void;
114 /**
115 * Stops timers for automatic refresh.
116 * To restart it, call setupAutomaticSilentRefresh again.
117 */
118 stopAutomaticRefresh(): void;
119 protected clearAccessTokenTimer(): void;
120 protected clearIdTokenTimer(): void;
121 protected clearAutomaticRefreshTimer(): void;
122 protected calcTimeout(storedAt: number, expiration: number): number;
123 /**
124 * DEPRECATED. Use a provider for OAuthStorage instead:
125 *
126 * { provide: OAuthStorage, useFactory: oAuthStorageFactory }
127 * export function oAuthStorageFactory(): OAuthStorage { return localStorage; }
128 * Sets a custom storage used to store the received
129 * tokens on client side. By default, the browser's
130 * sessionStorage is used.
131 * @ignore
132 *
133 * @param storage
134 */
135 setStorage(storage: OAuthStorage): void;
136 /**
137 * Loads the discovery document to configure most
138 * properties of this service. The url of the discovery
139 * document is infered from the issuer's url according
140 * to the OpenId Connect spec. To use another url you
141 * can pass it to to optional parameter fullUrl.
142 *
143 * @param fullUrl
144 */
145 loadDiscoveryDocument(fullUrl?: string): Promise<OAuthSuccessEvent>;
146 protected loadJwks(): Promise<object>;
147 protected validateDiscoveryDocument(doc: OidcDiscoveryDoc): boolean;
148 /**
149 * Uses password flow to exchange userName and password for an
150 * access_token. After receiving the access_token, this method
151 * uses it to query the userinfo endpoint in order to get information
152 * about the user in question.
153 *
154 * When using this, make sure that the property oidc is set to false.
155 * Otherwise stricter validations take place that make this operation
156 * fail.
157 *
158 * @param userName
159 * @param password
160 * @param headers Optional additional http-headers.
161 */
162 fetchTokenUsingPasswordFlowAndLoadUserProfile(userName: string, password: string, headers?: HttpHeaders): Promise<object>;
163 /**
164 * Loads the user profile by accessing the user info endpoint defined by OpenId Connect.
165 *
166 * When using this with OAuth2 password flow, make sure that the property oidc is set to false.
167 * Otherwise stricter validations take place that make this operation fail.
168 */
169 loadUserProfile(): Promise<object>;
170 /**
171 * Uses password flow to exchange userName and password for an access_token.
172 * @param userName
173 * @param password
174 * @param headers Optional additional http-headers.
175 */
176 fetchTokenUsingPasswordFlow(userName: string, password: string, headers?: HttpHeaders): Promise<TokenResponse>;
177 /**
178 * Uses a custom grant type to retrieve tokens.
179 * @param grantType Grant type.
180 * @param parameters Parameters to pass.
181 * @param headers Optional additional HTTP headers.
182 */
183 fetchTokenUsingGrant(grantType: string, parameters: object, headers?: HttpHeaders): Promise<TokenResponse>;
184 /**
185 * Refreshes the token using a refresh_token.
186 * This does not work for implicit flow, b/c
187 * there is no refresh_token in this flow.
188 * A solution for this is provided by the
189 * method silentRefresh.
190 */
191 refreshToken(): Promise<TokenResponse>;
192 protected removeSilentRefreshEventListener(): void;
193 protected setupSilentRefreshEventListener(): void;
194 /**
195 * Performs a silent refresh for implicit flow.
196 * Use this method to get new tokens when/before
197 * the existing tokens expire.
198 */
199 silentRefresh(params?: object, noPrompt?: boolean): Promise<OAuthEvent>;
200 /**
201 * This method exists for backwards compatibility.
202 * {@link OAuthService#initLoginFlowInPopup} handles both code
203 * and implicit flows.
204 */
205 initImplicitFlowInPopup(options?: {
206 height?: number;
207 width?: number;
208 windowRef?: Window;
209 }): Promise<unknown>;
210 initLoginFlowInPopup(options?: {
211 height?: number;
212 width?: number;
213 windowRef?: Window;
214 }): Promise<unknown>;
215 protected calculatePopupFeatures(options: {
216 height?: number;
217 width?: number;
218 }): string;
219 protected processMessageEventMessage(e: MessageEvent): string;
220 protected canPerformSessionCheck(): boolean;
221 protected setupSessionCheckEventListener(): void;
222 protected handleSessionUnchanged(): void;
223 protected handleSessionChange(): void;
224 protected waitForSilentRefreshAfterSessionChange(): void;
225 protected handleSessionError(): void;
226 protected removeSessionCheckEventListener(): void;
227 protected initSessionCheck(): void;
228 protected startSessionCheckTimer(): void;
229 protected stopSessionCheckTimer(): void;
230 checkSession(): void;
231 protected createLoginUrl(state?: string, loginHint?: string, customRedirectUri?: string, noPrompt?: boolean, params?: object): Promise<string>;
232 initImplicitFlowInternal(additionalState?: string, params?: string | object): void;
233 /**
234 * Starts the implicit flow and redirects to user to
235 * the auth servers' login url.
236 *
237 * @param additionalState Optional state that is passed around.
238 * You'll find this state in the property `state` after `tryLogin` logged in the user.
239 * @param params Hash with additional parameter. If it is a string, it is used for the
240 * parameter loginHint (for the sake of compatibility with former versions)
241 */
242 initImplicitFlow(additionalState?: string, params?: string | object): void;
243 /**
244 * Reset current implicit flow
245 *
246 * @description This method allows resetting the current implict flow in order to be initialized again.
247 */
248 resetImplicitFlow(): void;
249 protected callOnTokenReceivedIfExists(options: LoginOptions): void;
250 protected storeAccessTokenResponse(accessToken: string, refreshToken: string, expiresIn: number, grantedScopes: string, customParameters?: Map<string, string>): void;
251 /**
252 * Delegates to tryLoginImplicitFlow for the sake of competability
253 * @param options Optional options.
254 */
255 tryLogin(options?: LoginOptions): Promise<boolean>;
256 private parseQueryString;
257 tryLoginCodeFlow(options?: LoginOptions): Promise<void>;
258 private saveRequestedRoute;
259 private restoreRequestedRoute;
260 /**
261 * Retrieve the returned auth code from the redirect uri that has been called.
262 * If required also check hash, as we could use hash location strategy.
263 */
264 private getCodePartsFromUrl;
265 /**
266 * Get token using an intermediate code. Works for the Authorization Code flow.
267 */
268 private getTokenFromCode;
269 private fetchAndProcessToken;
270 /**
271 * Checks whether there are tokens in the hash fragment
272 * as a result of the implicit flow. These tokens are
273 * parsed, validated and used to sign the user in to the
274 * current client.
275 *
276 * @param options Optional options.
277 */
278 tryLoginImplicitFlow(options?: LoginOptions): Promise<boolean>;
279 private parseState;
280 protected validateNonce(nonceInState: string): boolean;
281 protected storeIdToken(idToken: ParsedIdToken): void;
282 protected storeSessionState(sessionState: string): void;
283 protected getSessionState(): string;
284 protected handleLoginError(options: LoginOptions, parts: object): void;
285 private getClockSkewInMsec;
286 /**
287 * @ignore
288 */
289 processIdToken(idToken: string, accessToken: string, skipNonceCheck?: boolean): Promise<ParsedIdToken>;
290 /**
291 * Returns the received claims about the user.
292 */
293 getIdentityClaims(): Record<string, any>;
294 /**
295 * Returns the granted scopes from the server.
296 */
297 getGrantedScopes(): object;
298 /**
299 * Returns the current id_token.
300 */
301 getIdToken(): string;
302 protected padBase64(base64data: any): string;
303 /**
304 * Returns the current access_token.
305 */
306 getAccessToken(): string;
307 getRefreshToken(): string;
308 /**
309 * Returns the expiration date of the access_token
310 * as milliseconds since 1970.
311 */
312 getAccessTokenExpiration(): number;
313 protected getAccessTokenStoredAt(): number;
314 protected getIdTokenStoredAt(): number;
315 /**
316 * Returns the expiration date of the id_token
317 * as milliseconds since 1970.
318 */
319 getIdTokenExpiration(): number;
320 /**
321 * Checkes, whether there is a valid access_token.
322 */
323 hasValidAccessToken(): boolean;
324 /**
325 * Checks whether there is a valid id_token.
326 */
327 hasValidIdToken(): boolean;
328 /**
329 * Retrieve a saved custom property of the TokenReponse object. Only if predefined in authconfig.
330 */
331 getCustomTokenResponseProperty(requestedProperty: string): any;
332 /**
333 * Returns the auth-header that can be used
334 * to transmit the access_token to a service
335 */
336 authorizationHeader(): string;
337 /**
338 * Removes all tokens and logs the user out.
339 * If a logout url is configured, the user is
340 * redirected to it with optional state parameter.
341 * @param noRedirectToLogoutUrl
342 * @param state
343 */
344 logOut(): void;
345 logOut(customParameters: boolean | object): void;
346 logOut(noRedirectToLogoutUrl: boolean): void;
347 logOut(noRedirectToLogoutUrl: boolean, state: string): void;
348 /**
349 * @ignore
350 */
351 createAndSaveNonce(): Promise<string>;
352 /**
353 * @ignore
354 */
355 ngOnDestroy(): void;
356 protected createNonce(): Promise<string>;
357 protected checkAtHash(params: ValidationParams): Promise<boolean>;
358 protected checkSignature(params: ValidationParams): Promise<any>;
359 /**
360 * Start the implicit flow or the code flow,
361 * depending on your configuration.
362 */
363 initLoginFlow(additionalState?: string, params?: {}): void;
364 /**
365 * Starts the authorization code flow and redirects to user to
366 * the auth servers login url.
367 */
368 initCodeFlow(additionalState?: string, params?: {}): void;
369 private initCodeFlowInternal;
370 protected createChallangeVerifierPairForPKCE(): Promise<[
371 string,
372 string
373 ]>;
374 private extractRecognizedCustomParameters;
375 /**
376 * Revokes the auth token to secure the vulnarability
377 * of the token issued allowing the authorization server to clean
378 * up any security credentials associated with the authorization
379 */
380 revokeTokenAndLogout(customParameters?: boolean | object, ignoreCorsIssues?: boolean): Promise<any>;
381 /**
382 * Clear location.hash if it's present
383 */
384 private clearLocationHash;
385 static ɵfac: i0.ɵɵFactoryDeclaration<OAuthService, [null, null, { optional: true; }, { optional: true; }, { optional: true; }, null, null, { optional: true; }, null, null]>;
386 static ɵprov: i0.ɵɵInjectableDeclaration<OAuthService>;
387}