oidc-client
Advanced tools
Comparing version 1.11.0-beta.2 to 1.11.0
@@ -60,5 +60,7 @@ /* Provides a namespace for when the library is loaded outside a module loader environment */ | ||
export interface MetadataService { | ||
new (settings: OidcClientSettings): MetadataService; | ||
new(settings: OidcClientSettings): MetadataService; | ||
metadataUrl?: string; | ||
resetSigningKeys(): void; | ||
@@ -73,3 +75,3 @@ getMetadata(): Promise<OidcMetadata>; | ||
getTokenEndpoint(): Promise<string | undefined>; | ||
getTokenEndpoint(optional: boolean = true): Promise<string | undefined>; | ||
@@ -161,4 +163,6 @@ getCheckSessionIframe(): Promise<string | undefined>; | ||
readonly clockSkew?: number; | ||
readonly clockService?: ClockService; | ||
readonly stateStore?: StateStore; | ||
readonly userInfoJwtIssuer?: 'ANY' | 'OP' | string; | ||
readonly mergeClaims?: boolean; | ||
ResponseValidatorCtor?: ResponseValidatorCtor; | ||
@@ -168,2 +172,4 @@ MetadataServiceCtor?: MetadataServiceCtor; | ||
extraQueryParams?: Record<string, any>; | ||
getEpochTime(): Promise<number>; | ||
} | ||
@@ -215,3 +221,3 @@ | ||
/** Proxy to Popup and Redirect callbacks */ | ||
signoutCallback(url?: string, keepWindowOpen?: boolean): Promise<SignoutResponse | void>; | ||
signoutCallback(url?: string, keepWindowOpen?: boolean): Promise<SignoutResponse | undefined>; | ||
@@ -256,2 +262,6 @@ /** Query OP for user's current signin status */ | ||
/** Subscribe to events raised when the user's signed-in */ | ||
addUserSignedIn(callback: UserManagerEvents.UserSignedInCallback): void; | ||
removeUserSignedIn(callback: UserManagerEvents.UserSignedInCallback): void; | ||
/** Subscribe to events raised when the user's sign-in status at the OP has changed */ | ||
@@ -270,2 +280,3 @@ addUserSignedOut(callback: UserManagerEvents.UserSignedOutCallback): void; | ||
export type SilentRenewErrorCallback = (error: Error) => void; | ||
export type UserSignedInCallback = () => void; | ||
export type UserSignedOutCallback = () => void; | ||
@@ -310,2 +321,6 @@ export type UserSessionChangedCallback = () => void; | ||
export interface ClockService { | ||
getEpochTime(): Promise<number>; | ||
} | ||
export interface WebStorageStateStoreSettings { | ||
@@ -339,5 +354,8 @@ prefix?: string; | ||
export interface SigninResponse { | ||
new (url: string, delimiter?: string): SigninResponse; | ||
new(url: string, delimiter?: string): SigninResponse; | ||
access_token: string; | ||
/** Refresh token returned from the OIDC provider (if requested, via the | ||
* 'offline_access' scope) */ | ||
refresh_token?: string; | ||
code: string; | ||
@@ -361,3 +379,3 @@ error: string; | ||
export interface SignoutResponse { | ||
new (url: string): SignoutResponse; | ||
new(url: string): SignoutResponse; | ||
@@ -519,5 +537,5 @@ error?: string; | ||
issuer: string; | ||
authorization_endpoint:string; | ||
authorization_endpoint: string; | ||
token_endpoint: string; | ||
token_endpoint_auth_methods_supported:string[]; | ||
token_endpoint_auth_methods_supported: string[]; | ||
token_endpoint_auth_signing_alg_values_supported: string[]; | ||
@@ -559,3 +577,3 @@ userinfo_endpoint: string; | ||
export interface CheckSessionIFrame { | ||
new (callback: () => void, client_id: string, url: string, interval?: number, stopOnError?: boolean): CheckSessionIFrame | ||
new(callback: () => void, client_id: string, url: string, interval?: number, stopOnError?: boolean): CheckSessionIFrame | ||
@@ -562,0 +580,0 @@ load(): Promise<void>; |
@@ -60,5 +60,7 @@ /* Provides a namespace for when the library is loaded outside a module loader environment */ | ||
export interface MetadataService { | ||
new (settings: OidcClientSettings): MetadataService; | ||
new(settings: OidcClientSettings): MetadataService; | ||
metadataUrl?: string; | ||
resetSigningKeys(): void; | ||
@@ -73,3 +75,3 @@ getMetadata(): Promise<OidcMetadata>; | ||
getTokenEndpoint(): Promise<string | undefined>; | ||
getTokenEndpoint(optional: boolean = true): Promise<string | undefined>; | ||
@@ -161,4 +163,6 @@ getCheckSessionIframe(): Promise<string | undefined>; | ||
readonly clockSkew?: number; | ||
readonly clockService?: ClockService; | ||
readonly stateStore?: StateStore; | ||
readonly userInfoJwtIssuer?: 'ANY' | 'OP' | string; | ||
readonly mergeClaims?: boolean; | ||
ResponseValidatorCtor?: ResponseValidatorCtor; | ||
@@ -168,2 +172,4 @@ MetadataServiceCtor?: MetadataServiceCtor; | ||
extraQueryParams?: Record<string, any>; | ||
getEpochTime(): Promise<number>; | ||
} | ||
@@ -215,3 +221,3 @@ | ||
/** Proxy to Popup and Redirect callbacks */ | ||
signoutCallback(url?: string, keepWindowOpen?: boolean): Promise<SignoutResponse | void>; | ||
signoutCallback(url?: string, keepWindowOpen?: boolean): Promise<SignoutResponse | undefined>; | ||
@@ -256,2 +262,6 @@ /** Query OP for user's current signin status */ | ||
/** Subscribe to events raised when the user's signed-in */ | ||
addUserSignedIn(callback: UserManagerEvents.UserSignedInCallback): void; | ||
removeUserSignedIn(callback: UserManagerEvents.UserSignedInCallback): void; | ||
/** Subscribe to events raised when the user's sign-in status at the OP has changed */ | ||
@@ -270,2 +280,3 @@ addUserSignedOut(callback: UserManagerEvents.UserSignedOutCallback): void; | ||
export type SilentRenewErrorCallback = (error: Error) => void; | ||
export type UserSignedInCallback = () => void; | ||
export type UserSignedOutCallback = () => void; | ||
@@ -310,2 +321,6 @@ export type UserSessionChangedCallback = () => void; | ||
export interface ClockService { | ||
getEpochTime(): Promise<number>; | ||
} | ||
export interface WebStorageStateStoreSettings { | ||
@@ -339,5 +354,8 @@ prefix?: string; | ||
export interface SigninResponse { | ||
new (url: string, delimiter?: string): SigninResponse; | ||
new(url: string, delimiter?: string): SigninResponse; | ||
access_token: string; | ||
/** Refresh token returned from the OIDC provider (if requested, via the | ||
* 'offline_access' scope) */ | ||
refresh_token?: string; | ||
code: string; | ||
@@ -361,3 +379,3 @@ error: string; | ||
export interface SignoutResponse { | ||
new (url: string): SignoutResponse; | ||
new(url: string): SignoutResponse; | ||
@@ -519,5 +537,5 @@ error?: string; | ||
issuer: string; | ||
authorization_endpoint:string; | ||
authorization_endpoint: string; | ||
token_endpoint: string; | ||
token_endpoint_auth_methods_supported:string[]; | ||
token_endpoint_auth_methods_supported: string[]; | ||
token_endpoint_auth_signing_alg_values_supported: string[]; | ||
@@ -559,3 +577,3 @@ userinfo_endpoint: string; | ||
export interface CheckSessionIFrame { | ||
new (callback: () => void, client_id: string, url: string, interval?: number, stopOnError?: boolean): CheckSessionIFrame | ||
new(callback: () => void, client_id: string, url: string, interval?: number, stopOnError?: boolean): CheckSessionIFrame | ||
@@ -562,0 +580,0 @@ load(): Promise<void>; |
{ | ||
"name": "oidc-client", | ||
"version": "1.11.0-beta.2", | ||
"version": "1.11.0", | ||
"description": "OpenID Connect (OIDC) & OAuth2 client library", | ||
@@ -5,0 +5,0 @@ "main": "lib/oidc-client.min.js", |
@@ -25,4 +25,4 @@ // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. | ||
this._frame.style.display = "none"; | ||
this._frame.style.width = 0; | ||
this._frame.style.height = 0; | ||
this._frame.width = 0; | ||
this._frame.height = 0; | ||
@@ -29,0 +29,0 @@ this._frame.src = url; |
@@ -24,4 +24,4 @@ // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. | ||
this._frame.style.position = "absolute"; | ||
this._frame.style.width = 0; | ||
this._frame.style.height = 0; | ||
this._frame.width = 0; | ||
this._frame.height = 0; | ||
@@ -90,3 +90,4 @@ window.document.body.appendChild(this._frame); | ||
e.origin === this._origin && | ||
e.source === this._frame.contentWindow | ||
e.source === this._frame.contentWindow && | ||
(typeof e.data === 'string' && (e.data.startsWith('http://') || e.data.startsWith('https://'))) | ||
) { | ||
@@ -93,0 +94,0 @@ let url = e.data; |
@@ -99,3 +99,3 @@ // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. | ||
postForm(url, payload) { | ||
postForm(url, payload, basicAuth) { | ||
if (!url){ | ||
@@ -201,2 +201,8 @@ Log.error("JsonService.postForm: No url passed"); | ||
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); | ||
if (basicAuth !== undefined) | ||
{ | ||
req.setRequestHeader("Authorization", "Basic " + btoa(basicAuth)); | ||
} | ||
req.send(body); | ||
@@ -203,0 +209,0 @@ }); |
@@ -40,2 +40,7 @@ // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. | ||
resetSigningKeys() { | ||
this._settings = this._settings || {} | ||
this._settings.signingKeys = undefined | ||
} | ||
getMetadata() { | ||
@@ -42,0 +47,0 @@ if (this._settings.metadata) { |
@@ -14,2 +14,3 @@ // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. | ||
const DefaultScope = "openid"; | ||
const DefaultClientAuthentication = "client_secret_post" // The default value must be client_secret_basic, as explained in https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication | ||
const DefaultStaleStateAge = 60 * 15; // seconds | ||
@@ -25,2 +26,3 @@ const DefaultClockSkewInSeconds = 60 * 5; | ||
redirect_uri, post_logout_redirect_uri, | ||
client_authentication = DefaultClientAuthentication, | ||
// optional protocol | ||
@@ -34,2 +36,3 @@ prompt, display, max_age, ui_locales, acr_values, resource, response_mode, | ||
userInfoJwtIssuer = 'OP', | ||
mergeClaims = false, | ||
// other behavior | ||
@@ -55,2 +58,3 @@ stateStore = new WebStorageStateStore(), | ||
this._post_logout_redirect_uri = post_logout_redirect_uri; | ||
this._client_authentication = client_authentication; | ||
@@ -71,2 +75,3 @@ this._prompt = prompt; | ||
this._userInfoJwtIssuer = userInfoJwtIssuer; | ||
this._mergeClaims = !!mergeClaims; | ||
@@ -110,4 +115,7 @@ this._stateStore = stateStore; | ||
} | ||
get client_authentication() { | ||
return this._client_authentication; | ||
} | ||
// optional protocol params | ||
@@ -197,3 +205,6 @@ get prompt() { | ||
} | ||
get mergeClaims() { | ||
return this._mergeClaims; | ||
} | ||
get stateStore() { | ||
@@ -200,0 +211,0 @@ return this._stateStore; |
@@ -195,5 +195,5 @@ // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. | ||
else if (result[name] !== value) { | ||
if (typeof value === 'object') { | ||
if (typeof value === 'object' && this._settings.mergeClaims) { | ||
result[name] = this._mergeClaims(result[name], value); | ||
} | ||
} | ||
else { | ||
@@ -312,2 +312,45 @@ result[name] = [result[name], value]; | ||
_getSigningKeyForJwt(jwt) { | ||
return this._metadataService.getSigningKeys().then(keys => { | ||
const kid = jwt.header.kid; | ||
if (!keys) { | ||
Log.error("ResponseValidator._validateIdToken: No signing keys from metadata"); | ||
return Promise.reject(new Error("No signing keys from metadata")); | ||
} | ||
Log.debug("ResponseValidator._validateIdToken: Received signing keys"); | ||
let key; | ||
if (!kid) { | ||
keys = this._filterByAlg(keys, jwt.header.alg); | ||
if (keys.length > 1) { | ||
Log.error("ResponseValidator._validateIdToken: No kid found in id_token and more than one key found in metadata"); | ||
return Promise.reject(new Error("No kid found in id_token and more than one key found in metadata")); | ||
} else { | ||
// kid is mandatory only when there are multiple keys in the referenced JWK Set document | ||
// see http://openid.net/specs/openid-connect-core-1_0.html#Signing | ||
key = keys[0]; | ||
} | ||
} else { | ||
key = keys.filter(key => { | ||
return key.kid === kid; | ||
})[0]; | ||
} | ||
return Promise.resolve(key); | ||
}); | ||
} | ||
_getSigningKeyForJwtWithSingleRetry(jwt) { | ||
return this._getSigningKeyForJwt(jwt).then(key => { | ||
// Refreshing signingKeys if no suitable verification key is present for given jwt header. | ||
if (!key) { | ||
// set to undefined, to trigger network call to jwks_uri. | ||
this._metadataService.resetSigningKeys(); | ||
return this._getSigningKeyForJwt(jwt); | ||
} else { | ||
return Promise.resolve(key); | ||
} | ||
}); | ||
} | ||
_validateIdToken(state, response) { | ||
@@ -330,34 +373,5 @@ if (!state.nonce) { | ||
var kid = jwt.header.kid; | ||
return this._metadataService.getIssuer().then(issuer => { | ||
Log.debug("ResponseValidator._validateIdToken: Received issuer"); | ||
return this._metadataService.getSigningKeys().then(keys => { | ||
if (!keys) { | ||
Log.error("ResponseValidator._validateIdToken: No signing keys from metadata"); | ||
return Promise.reject(new Error("No signing keys from metadata")); | ||
} | ||
Log.debug("ResponseValidator._validateIdToken: Received signing keys"); | ||
let key; | ||
if (!kid) { | ||
keys = this._filterByAlg(keys, jwt.header.alg); | ||
if (keys.length > 1) { | ||
Log.error("ResponseValidator._validateIdToken: No kid found in id_token and more than one key found in metadata"); | ||
return Promise.reject(new Error("No kid found in id_token and more than one key found in metadata")); | ||
} | ||
else { | ||
// kid is mandatory only when there are multiple keys in the referenced JWK Set document | ||
// see http://openid.net/specs/openid-connect-core-1_0.html#Signing | ||
key = keys[0]; | ||
} | ||
} | ||
else { | ||
key = keys.filter(key => { | ||
return key.kid === kid; | ||
})[0]; | ||
} | ||
return this._getSigningKeyForJwtWithSingleRetry(jwt).then(key => { | ||
if (!key) { | ||
@@ -364,0 +378,0 @@ Log.error("ResponseValidator._validateIdToken: No key matching kid or alg found in signing keys"); |
@@ -25,4 +25,9 @@ // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. | ||
args.client_id = args.client_id || this._settings.client_id; | ||
args.client_secret = args.client_secret || this._settings.client_secret; | ||
args.redirect_uri = args.redirect_uri || this._settings.redirect_uri; | ||
var basicAuth = undefined; | ||
var client_authentication = args._client_authentication || this._settings._client_authentication; | ||
delete args._client_authentication; | ||
if (!args.code) { | ||
@@ -44,7 +49,18 @@ Log.error("TokenClient.exchangeCode: No code passed"); | ||
} | ||
if (!args.client_secret && client_authentication == "client_secret_basic") { | ||
Log.error("TokenClient.exchangeCode: No client_secret passed"); | ||
return Promise.reject(new Error("A client_secret is required")); | ||
} | ||
// Sending the client credentials using the Basic Auth method | ||
if(client_authentication == "client_secret_basic") | ||
{ | ||
basicAuth = args.client_id + ':' + args.client_secret; | ||
delete args.client_id; | ||
delete args.client_secret; | ||
} | ||
return this._metadataService.getTokenEndpoint(false).then(url => { | ||
Log.debug("TokenClient.exchangeCode: Received token endpoint"); | ||
return this._jsonService.postForm(url, args).then(response => { | ||
return this._jsonService.postForm(url, args, basicAuth).then(response => { | ||
Log.debug("TokenClient.exchangeCode: response received"); | ||
@@ -63,2 +79,6 @@ return response; | ||
var basicAuth = undefined; | ||
var client_authentication = args._client_authentication || this._settings._client_authentication; | ||
delete args._client_authentication; | ||
if (!args.refresh_token) { | ||
@@ -73,6 +93,14 @@ Log.error("TokenClient.exchangeRefreshToken: No refresh_token passed"); | ||
// Sending the client credentials using the Basic Auth method | ||
if(client_authentication == "client_secret_basic") | ||
{ | ||
basicAuth = args.client_id + ':' + args.client_secret; | ||
delete args.client_id; | ||
delete args.client_secret; | ||
} | ||
return this._metadataService.getTokenEndpoint(false).then(url => { | ||
Log.debug("TokenClient.exchangeRefreshToken: Received token endpoint"); | ||
return this._jsonService.postForm(url, args).then(response => { | ||
return this._jsonService.postForm(url, args, basicAuth).then(response => { | ||
Log.debug("TokenClient.exchangeRefreshToken: response received"); | ||
@@ -79,0 +107,0 @@ return response; |
@@ -163,3 +163,2 @@ // Copyright (c) Brock Allen & Dominick Baier. All rights reserved. | ||
args.request_type = "si:s"; | ||
// first determine if we have a refresh token, or need to use iframe | ||
@@ -172,2 +171,3 @@ return this._loadUser().then(user => { | ||
else { | ||
args.request_type = "si:s"; | ||
args.id_token_hint = args.id_token_hint || (this.settings.includeIdTokenInSilentRenew && user && user.id_token); | ||
@@ -203,3 +203,3 @@ if (user && this._settings.validateSubOnSilentRenew) { | ||
Log.debug("UserManager._useRefreshToken: refresh token response success"); | ||
user.id_token = result.id_token; | ||
user.id_token = result.id_token || user.id_token; | ||
user.access_token = result.access_token; | ||
@@ -206,0 +206,0 @@ user.refresh_token = result.refresh_token || user.refresh_token; |
@@ -1,1 +0,1 @@ | ||
const Version = "1.11.0-beta.2"; export {Version}; | ||
const Version = "1.11.0"; export {Version}; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
10467475
80401
0