From 2d825dd366dd856353afeba8f1ae655dcdf64449 Mon Sep 17 00:00:00 2001 From: Stan Silvert Date: Fri, 5 May 2017 15:08:23 -0400 Subject: [PATCH 1/2] KEYCLOAK-4822: Update to ES6-compatible typings --- .../js/src/main/resources/keycloak-authz.d.ts | 59 ++ .../oidc/js/src/main/resources/keycloak.d.ts | 551 +++++++++++++++--- 2 files changed, 523 insertions(+), 87 deletions(-) create mode 100644 adapters/oidc/js/src/main/resources/keycloak-authz.d.ts diff --git a/adapters/oidc/js/src/main/resources/keycloak-authz.d.ts b/adapters/oidc/js/src/main/resources/keycloak-authz.d.ts new file mode 100644 index 0000000000..c897276acd --- /dev/null +++ b/adapters/oidc/js/src/main/resources/keycloak-authz.d.ts @@ -0,0 +1,59 @@ +/* + * MIT License + * + * Copyright 2017 Andy Hanson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + * following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +import * as Keycloak from 'keycloak'; + +export as namespace KeycloakAuthorization; + +export = KeycloakAuthorization; + +/** + * Creates a new Keycloak client instance. + * @param config Path to a JSON config file or a plain config object. + */ +declare function KeycloakAuthorization(keycloak: Keycloak.KeycloakInstance): KeycloakAuthorization.KeycloakAuthorizationInstance; + +declare namespace KeycloakAuthorization { + interface KeycloakAuthorizationPromise { + then(onGrant: (rpt: string) => void, onDeny: () => void, onError: () => void): void; + } + + interface KeycloakAuthorizationInstance { + rpt: any; + config: { rpt_endpoint: string }; + + init(): void; + + /** + * This method enables client applications to better integrate with resource servers protected by a Keycloak + * policy enforcer. + * + * In this case, the resource server will respond with a 401 status code and a WWW-Authenticate header holding the + * necessary information to ask a Keycloak server for authorization data using both UMA and Entitlement protocol, + * depending on how the policy enforcer at the resource server was configured. + */ + authorize(wwwAuthenticateHeader: string): KeycloakAuthorizationPromise; + + /** + * Obtains all entitlements from a Keycloak server based on a given resourceServerId. + */ + entitlement(resourceServerId: string, entitlementRequest: {}): KeycloakAuthorizationPromise; + } +} diff --git a/adapters/oidc/js/src/main/resources/keycloak.d.ts b/adapters/oidc/js/src/main/resources/keycloak.d.ts index 5579da1cbe..e7e6e387a6 100644 --- a/adapters/oidc/js/src/main/resources/keycloak.d.ts +++ b/adapters/oidc/js/src/main/resources/keycloak.d.ts @@ -1,101 +1,478 @@ /* - * Copyright 2017 Red Hat, Inc. and/or its affiliates - * and other contributors as indicated by the @author tags. + * MIT License * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * Copyright 2017 Andy Hanson * - * http://www.apache.org/licenses/LICENSE-2.0 + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the + * following conditions: * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * The above copyright notice and this permission notice shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -declare module KeycloakModule { +export as namespace Keycloak; - export interface Promise { - success(callback: Function): Promise; - error(callback: Function): Promise; - } +export = Keycloak; - export type ResponseModes = "query" | "fragment"; - export type Flows = "standard" | "implicit" | "hybrid"; - - export interface InitOptions { - checkLoginIframe?: boolean; - checkLoginIframeInterval?: number; - onLoad?: string; - adapter?: string; - responseMode?: ResponseModes; - flow?: Flows; - token?: string; - refreshToken?: string; - idToken?: string; - timeSkew?: number; - } +/** + * Creates a new Keycloak client instance. + * @param config Path to a JSON config file or a plain config object. + */ +declare function Keycloak(config?: string|{}): Keycloak.KeycloakInstance; - export interface LoginOptions { - redirectUri?: string; - prompt?: string; - maxAge?: number; - loginHint?: string; - action?: string; - locale?: string; - } +declare namespace Keycloak { + type KeycloakAdapterName = 'cordova'|'default'; + type KeycloakOnLoad = 'login-required'|'check-sso'; + type KeycloakResponseMode = 'query'|'fragment'; + type KeycloakResponseType = 'code'|'id_token token'|'code id_token token'; + type KeycloakFlow = 'standard'|'implicit'|'hybrid'; - export interface RedirectUriOptions { - redirectUri?: string; - } + interface KeycloakInitOptions { + /** + * @private Undocumented. + */ + adapter?: KeycloakAdapterName; - export interface KeycloakClient { - init(options?: InitOptions): Promise; - login(options?: LoginOptions): Promise; - createLoginUrl(options?: LoginOptions): string; - logout(options?: RedirectUriOptions): Promise; - createLogoutUrl(options?: RedirectUriOptions): string; - register(options?: LoginOptions): Promise; - createRegisterUrl(options?: RedirectUriOptions): string; - accountManagement(): Promise; - createAccountUrl(options?: RedirectUriOptions): string; - hasRealmRole(role: string): boolean; - hasResourceRole(role: string, resource?: string): boolean; - loadUserProfile(): Promise; - isTokenExpired(minValidity: number): boolean; - updateToken(minValidity: number): Promise; - clearToken(): any; + /** + * Specifies an action to do on load. + */ + onLoad?: KeycloakOnLoad; - realm: string; - clientId: string; - authServerUrl: string; + /** + * Set an initial value for the token. + */ + token?: string; - token: string; - tokenParsed: any; - refreshToken: string; - refreshTokenParsed: any; - idToken: string; - idTokenParsed: any; - realmAccess: any; - resourceAccess: any; - authenticated: boolean; - subject: string; - timeSkew: number; - responseMode: ResponseModes; - flow: Flows; - responseType: string; + /** + * Set an initial value for the refresh token. + */ + refreshToken?: string; - onReady: Function; - onAuthSuccess: Function; - onAuthError: Function; - onAuthRefreshSuccess: Function; - onAuthRefreshError: Function; - onAuthLogout: Function; - onTokenExpired: Function; - } + /** + * Set an initial value for the id token (only together with `token` or + * `refreshToken`). + */ + idToken?: string; + + /** + * Set an initial value for skew between local time and Keycloak server in + * seconds (only together with `token` or `refreshToken`). + */ + timeSkew?: number; + + /** + * Set to enable/disable monitoring login state. + * @default true + */ + checkLoginIframe?: boolean; + + /** + * Set the interval to check login state (in seconds). + * @default 5 + */ + checkLoginIframeInterval?: boolean; + + /** + * Set the OpenID Connect response mode to send to Keycloak upon login. + * @default fragment After successful authentication Keycloak will redirect + * to JavaScript application with OpenID Connect parameters + * added in URL fragment. This is generally safer and + * recommended over query. + */ + responseMode?: KeycloakResponseMode; + + /** + * Set the OpenID Connect flow. + * @default standard + */ + flow?: KeycloakFlow; + } + + interface KeycloakLoginOptions { + /** + * @private Undocumented. + */ + scope?: string; + + /** + * Specifies the uri to redirect to after login. + */ + redirectUri?: string; + + /** + * By default the login screen is displayed if the user is not logged into + * Keycloak. To only authenticate to the application if the user is already + * logged in and not display the login page if the user is not logged in, set + * this option to `'none'`. To always require re-authentication and ignore + * SSO, set this option to `'login'`. + */ + prompt?: 'none'|'login'; + + /** + * If value is `'register'` then user is redirected to registration page, + * otherwise to login page. + */ + action?: 'register'; + + /** + * Used just if user is already authenticated. Specifies maximum time since + * the authentication of user happened. If user is already authenticated for + * longer time than `'maxAge'`, the SSO is ignored and he will need to + * authenticate again. + */ + maxAge?: number; + + /** + * Used to pre-fill the username/email field on the login form. + */ + loginHint?: string; + + /** + * Used to tell Keycloak which IDP the user wants to authenticate with. + */ + idpHint?: string; + + /** + * Specifies the desired locale for the UI. + */ + locale?: string; + } + + type KeycloakPromiseCallback = (result: T) => void; + + interface KeycloakPromise { + /** + * Function to call if the promised action succeeds. + */ + success(callback: KeycloakPromiseCallback): KeycloakPromise; + + /** + * Function to call if the promised action throws an error. + */ + error(callback: KeycloakPromiseCallback): KeycloakPromise; + } + + interface KeycloakError { + error: string; + error_description: string; + } + + interface KeycloakAdapter { + login(options?: KeycloakLoginOptions): KeycloakPromise; + logout(options?: any): KeycloakPromise; + register(options?: KeycloakLoginOptions): KeycloakPromise; + accountManagement(): KeycloakPromise; + redirectUri(options: { redirectUri: string; }, encodeHash: boolean): string; + } + + interface KeycloakProfile { + id?: string; + username?: string; + email?: string; + firstName?: string; + lastName?: string; + enabled?: boolean; + emailVerified?: boolean; + totp?: boolean; + createdTimestamp?: number; + } + + // export interface KeycloakUserInfo {} + + /** + * A client for the Keycloak authentication server. + * @see {@link https://keycloak.gitbooks.io/securing-client-applications-guide/content/topics/oidc/javascript-adapter.html|Keycloak JS adapter documentation} + */ + interface KeycloakInstance { + /** + * Is true if the user is authenticated, false otherwise. + */ + authenticated?: boolean; + + /** + * The user id. + */ + subject?: string; + + /** + * Response mode passed in init (default value is `'fragment'`). + */ + responseMode?: KeycloakResponseMode; + + /** + * Response type sent to Keycloak with login requests. This is determined + * based on the flow value used during initialization, but can be overridden + * by setting this value. + */ + responseType?: KeycloakResponseType; + + /** + * Flow passed in init. + */ + flow?: KeycloakFlow; + + /** + * The realm roles associated with the token. + */ + realmAccess?: { roles: string[] }; + + /** + * The resource roles associated with the token. + */ + resourceAccess?: string[]; + + /** + * The base64 encoded token that can be sent in the Authorization header in + * requests to services. + */ + token?: string; + + /** + * The parsed token as a JavaScript object. + */ + tokenParsed?: { + exp?: number; + iat?: number; + nonce?: string; + sub?: string; + session_state?: string; + realm_access?: { roles: string[] }; + resource_access?: string[]; + }; + + /** + * The base64 encoded refresh token that can be used to retrieve a new token. + */ + refreshToken?: string; + + /** + * The parsed refresh token as a JavaScript object. + */ + refreshTokenParsed?: { nonce?: string }; + + /** + * The base64 encoded ID token. + */ + idToken?: string; + + /** + * The parsed id token as a JavaScript object. + */ + idTokenParsed?: { nonce?: string }; + + /** + * The estimated time difference between the browser time and the Keycloak + * server in seconds. This value is just an estimation, but is accurate + * enough when determining if a token is expired or not. + */ + timeSkew?: number; + + /** + * @private Undocumented. + */ + loginRequired?: boolean; + + /** + * @private Undocumented. + */ + authServerUrl?: string; + + /** + * @private Undocumented. + */ + realm?: string; + + /** + * @private Undocumented. + */ + clientId?: string; + + /** + * @private Undocumented. + */ + clientSecret?: string; + + /** + * @private Undocumented. + */ + redirectUri?: string; + + /** + * @private Undocumented. + */ + sessionId?: string; + + /** + * @private Undocumented. + */ + profile?: KeycloakProfile; + + /** + * @private Undocumented. + */ + userInfo?: {}; // KeycloakUserInfo; + + /** + * Called when the adapter is initialized. + */ + onReady?(authenticated?: boolean): void; + + /** + * Called when a user is successfully authenticated. + */ + onAuthSuccess?(): void; + + /** + * Called if there was an error during authentication. + */ + onAuthError?(errorData: KeycloakError): void; + + /** + * Called when the token is refreshed. + */ + onAuthRefreshSuccess?(): void; + + /** + * Called if there was an error while trying to refresh the token. + */ + onAuthRefreshError?(): void; + + /** + * Called if the user is logged out (will only be called if the session + * status iframe is enabled, or in Cordova mode). + */ + onAuthLogout?(): void; + + /** + * Called when the access token is expired. If a refresh token is available + * the token can be refreshed with Keycloak#updateToken, or in cases where + * it's not (ie. with implicit flow) you can redirect to login screen to + * obtain a new access token. + */ + onTokenExpired?(): void; + + /** + * Called to initialize the adapter. + * @param initOptions Initialization options. + * @returns A promise to set functions to be invoked on success or error. + */ + init(initOptions: KeycloakInitOptions): KeycloakPromise; + + /** + * Redirects to login form. + * @param options Login options. + */ + login(options?: KeycloakLoginOptions): KeycloakPromise; + + /** + * Redirects to logout. + * @param options Logout options. + * @param options.redirectUri Specifies the uri to redirect to after logout. + */ + logout(options?: any): KeycloakPromise; + + /** + * Redirects to registration form. + * @param options Supports same options as Keycloak#login but `action` is + * set to `'register'`. + */ + register(options?: any): KeycloakPromise; + + /** + * Redirects to the Account Management Console. + */ + accountManagement(): KeycloakPromise; + + /** + * Returns the URL to login form. + * @param options Supports same options as Keycloak#login. + */ + createLoginUrl(options?: KeycloakLoginOptions): string; + + /** + * Returns the URL to logout the user. + * @param options Logout options. + * @param options.redirectUri Specifies the uri to redirect to after logout. + */ + createLogoutUrl(options?: any): string; + + /** + * Returns the URL to registration page. + * @param options Supports same options as Keycloak#createLoginUrl but + * `action` is set to `'register'`. + */ + createRegisterUrl(options?: KeycloakLoginOptions): string; + + /** + * Returns the URL to the Account Management Console. + */ + createAccountUrl(): string; + + /** + * Returns true if the token has less than `minValidity` seconds left before + * it expires. + * @param minValidity If not specified, `0` is used. + */ + isTokenExpired(minValidity?: number): boolean; + + /** + * If the token expires within `minValidity` seconds, the token is refreshed. + * If the session status iframe is enabled, the session status is also + * checked. + * @returns A promise to set functions that can be invoked if the token is + * still valid, or if the token is no longer valid. + * @example + * ```js + * keycloak.updateToken(5).success(function(refreshed) { + * if (refreshed) { + * alert('Token was successfully refreshed'); + * } else { + * alert('Token is still valid'); + * } + * }).error(function() { + * alert('Failed to refresh the token, or the session has expired'); + * }); + */ + updateToken(minValidity: number): KeycloakPromise; + + /** + * Clears authentication state, including tokens. This can be useful if + * the application has detected the session was expired, for example if + * updating token fails. Invoking this results in Keycloak#onAuthLogout + * callback listener being invoked. + */ + clearToken(): void; + + /** + * Returns true if the token has the given realm role. + * @param role A realm role name. + */ + hasRealmRole(role: string): boolean; + + /** + * Returns true if the token has the given role for the resource. + * @param role A role name. + * @param resource If not specified, `clientId` is used. + */ + hasResourceRole(role: string, resource?: string): boolean; + + /** + * Loads the user's profile. + * @returns A promise to set functions to be invoked on success or error. + */ + loadUserProfile(): KeycloakPromise; + + /** + * @private Undocumented. + */ + loadUserInfo(): KeycloakPromise<{}, void>; + } } - -declare var Keycloak: { - new(config?: any): KeycloakModule.KeycloakClient; -}; \ No newline at end of file From 64cd689e38d3d5f91c5e740a28ad2423d90114d1 Mon Sep 17 00:00:00 2001 From: Stan Silvert Date: Wed, 10 May 2017 16:32:05 -0400 Subject: [PATCH 2/2] KEYCLOAK-4822: Change copyright to reflect correct author. --- adapters/oidc/js/src/main/resources/keycloak-authz.d.ts | 2 +- adapters/oidc/js/src/main/resources/keycloak.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/adapters/oidc/js/src/main/resources/keycloak-authz.d.ts b/adapters/oidc/js/src/main/resources/keycloak-authz.d.ts index c897276acd..c7e0b2f69f 100644 --- a/adapters/oidc/js/src/main/resources/keycloak-authz.d.ts +++ b/adapters/oidc/js/src/main/resources/keycloak-authz.d.ts @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright 2017 Andy Hanson + * Copyright 2017 Brett Epps * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, including diff --git a/adapters/oidc/js/src/main/resources/keycloak.d.ts b/adapters/oidc/js/src/main/resources/keycloak.d.ts index e7e6e387a6..2f5d220d5a 100644 --- a/adapters/oidc/js/src/main/resources/keycloak.d.ts +++ b/adapters/oidc/js/src/main/resources/keycloak.d.ts @@ -1,7 +1,7 @@ /* * MIT License * - * Copyright 2017 Andy Hanson + * Copyright 2017 Brett Epps * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and * associated documentation files (the "Software"), to deal in the Software without restriction, including