@forgerock/javascript-sdk
Advanced tools
Comparing version 1.0.5 to 2.0.0-alpha1
@@ -17,2 +17,3 @@ /** | ||
ConfirmationCallback = "ConfirmationCallback", | ||
DeviceProfileCallback = "DeviceProfileCallback", | ||
HiddenValueCallback = "HiddenValueCallback", | ||
@@ -19,0 +20,0 @@ KbaCreateCallback = "KbaCreateCallback", |
@@ -19,2 +19,3 @@ /** | ||
CallbackType["ConfirmationCallback"] = "ConfirmationCallback"; | ||
CallbackType["DeviceProfileCallback"] = "DeviceProfileCallback"; | ||
CallbackType["HiddenValueCallback"] = "HiddenValueCallback"; | ||
@@ -21,0 +22,0 @@ CallbackType["KbaCreateCallback"] = "KbaCreateCallback"; |
@@ -50,5 +50,4 @@ var __assign = (this && this.__assign) || function () { | ||
import { REQUESTED_WITH } from '../shared/constants'; | ||
import { getRealmUrlPath } from '../util/realm'; | ||
import { withTimeout } from '../util/timeout'; | ||
import { resolve, stringify } from '../util/url'; | ||
import { getEndpointPath, resolve, stringify } from '../util/url'; | ||
/** | ||
@@ -89,8 +88,7 @@ * Provides direct access to the OpenAM authentication tree API. | ||
Auth.constructUrl = function (serverConfig, realmPath, tree, query) { | ||
var realmUrlPath = getRealmUrlPath(realmPath); | ||
var treeParams = tree ? { authIndexType: 'service', authIndexValue: tree } : undefined; | ||
var params = __assign(__assign({}, query), treeParams); | ||
var queryString = Object.keys(params).length > 0 ? "?" + stringify(params) : ''; | ||
var path = "json/" + realmUrlPath + "/authenticate" + queryString; | ||
var url = resolve(serverConfig.baseUrl, path); | ||
var path = getEndpointPath('authenticate', realmPath, serverConfig.paths); | ||
var url = resolve(serverConfig.baseUrl, "" + path + queryString); | ||
return url; | ||
@@ -97,0 +95,0 @@ }; |
/** @hidden */ | ||
declare const DEFAULT_TIMEOUT = 5000; | ||
declare const DEFAULT_TIMEOUT: number; | ||
export { DEFAULT_TIMEOUT }; |
/** @hidden */ | ||
var DEFAULT_TIMEOUT = 5000; | ||
var DEFAULT_TIMEOUT = 60 * 1000; | ||
export { DEFAULT_TIMEOUT }; | ||
//# sourceMappingURL=constants.js.map |
import { FRCallbackFactory } from '../fr-auth/callbacks/factory'; | ||
import { Tokens } from '../shared/interfaces'; | ||
/** | ||
* Configuration settings for connecting to a server. | ||
*/ | ||
interface ServerConfig { | ||
baseUrl: string; | ||
timeout: number; | ||
} | ||
/** | ||
* Configuration options. | ||
@@ -19,5 +13,35 @@ */ | ||
serverConfig?: ServerConfig; | ||
tokenStore?: TokenStoreObject | 'indexedDB' | 'localStorage'; | ||
tree?: string; | ||
} | ||
declare type ConfigurablePaths = 'authenticate' | 'authorize' | 'accessToken' | 'endSession' | 'userInfo' | 'revoke' | 'sessions'; | ||
/** | ||
* Optional configuration for custom paths for actions | ||
*/ | ||
interface CustomPathConfig { | ||
authenticate?: string; | ||
authorize?: string; | ||
accessToken?: string; | ||
endSession?: string; | ||
userInfo?: string; | ||
revoke?: string; | ||
sessions?: string; | ||
} | ||
/** | ||
* Configuration settings for connecting to a server. | ||
*/ | ||
interface ServerConfig { | ||
baseUrl: string; | ||
paths?: CustomPathConfig; | ||
timeout: number; | ||
} | ||
/** | ||
* API for implementing a custom token store | ||
*/ | ||
interface TokenStoreObject { | ||
get: (clientId: string) => Promise<Tokens>; | ||
set: (clientId: string, token: Tokens) => Promise<void>; | ||
remove: (clientId: string) => Promise<void>; | ||
} | ||
/** | ||
* Configuration options with a server configuration specified. | ||
@@ -28,2 +52,2 @@ */ | ||
} | ||
export { ConfigOptions, ServerConfig, ValidConfigOptions }; | ||
export { ConfigOptions, ConfigurablePaths, CustomPathConfig, ServerConfig, TokenStoreObject, ValidConfigOptions, }; |
@@ -6,2 +6,3 @@ import FRCallback from '.'; | ||
import ConfirmationCallback from './confirmation-callback'; | ||
import DeviceProfileCallback from './device-profile-callback'; | ||
import HiddenValueCallback from './hidden-value-callback'; | ||
@@ -29,2 +30,4 @@ import KbaCreateCallback from './kba-create-callback'; | ||
return new ConfirmationCallback(callback); | ||
case CallbackType.DeviceProfileCallback: | ||
return new DeviceProfileCallback(callback); | ||
case CallbackType.HiddenValueCallback: | ||
@@ -31,0 +34,0 @@ return new HiddenValueCallback(callback); |
@@ -13,6 +13,7 @@ import Dispatcher from '../event'; | ||
static request(options: HttpClientRequestOptions): Promise<Response>; | ||
private static setAuthHeaders; | ||
private static stepIterator; | ||
private static _request; | ||
private static newTokenRequired; | ||
} | ||
export default HttpClient; | ||
export { HttpClientRequestOptions, RequiresNewTokenFn }; |
@@ -50,5 +50,11 @@ var __extends = (this && this.__extends) || (function () { | ||
}; | ||
import Config from '../config'; | ||
import Dispatcher from '../event'; | ||
import FRAuth from '../fr-auth'; | ||
import { StepType } from '../fr-auth/enums'; | ||
import FRStep from '../fr-auth/fr-step'; | ||
import TokenManager from '../token-manager'; | ||
import TokenStorage from '../token-storage'; | ||
import { withTimeout } from '../util/timeout'; | ||
import { buildTxnAuthOptions, examineForIGTxnAuth, examineForRESTTxnAuth, hasTransactionAdvice, isAuthStep, newTokenRequired, normalizeIGJSON, normalizeRESTJSON, } from './util'; | ||
/** | ||
@@ -69,14 +75,59 @@ * HTTP client that includes bearer token injection and refresh. | ||
return __awaiter(this, void 0, void 0, function () { | ||
var res; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
var res, txnAuthJSON, _a, realmPath, serverConfig, txnAuthOptions, initialStep, err_1; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: return [4 /*yield*/, this._request(options, false)]; | ||
case 1: | ||
res = _a.sent(); | ||
if (!this.newTokenRequired(res, options.requiresNewToken)) return [3 /*break*/, 3]; | ||
res = _b.sent(); | ||
if (!newTokenRequired(res, options.requiresNewToken)) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, this._request(options, true)]; | ||
case 2: | ||
res = _a.sent(); | ||
_a.label = 3; | ||
case 3: return [2 /*return*/, res]; | ||
res = _b.sent(); | ||
_b.label = 3; | ||
case 3: | ||
if (!(options.txnAuth && options.txnAuth.handleStep)) return [3 /*break*/, 14]; | ||
if (!(res.redirected && examineForIGTxnAuth(res))) return [3 /*break*/, 4]; | ||
txnAuthJSON = normalizeIGJSON(res); | ||
return [3 /*break*/, 7]; | ||
case 4: return [4 /*yield*/, examineForRESTTxnAuth(res)]; | ||
case 5: | ||
if (!_b.sent()) return [3 /*break*/, 7]; | ||
return [4 /*yield*/, normalizeRESTJSON(res)]; | ||
case 6: | ||
txnAuthJSON = _b.sent(); | ||
_b.label = 7; | ||
case 7: | ||
if (!(txnAuthJSON && txnAuthJSON.advices)) return [3 /*break*/, 14]; | ||
_a = Config.get(options.txnAuth.config), realmPath = _a.realmPath, serverConfig = _a.serverConfig; | ||
txnAuthOptions = buildTxnAuthOptions(txnAuthJSON, serverConfig.baseUrl, options.timeout, realmPath, serverConfig.paths); | ||
return [4 /*yield*/, this._request(txnAuthOptions, false)]; | ||
case 8: | ||
initialStep = _b.sent(); | ||
return [4 /*yield*/, isAuthStep(initialStep)]; | ||
case 9: | ||
if (!(_b.sent())) { | ||
throw new Error('Error: Initial response from auth server not a "step".'); | ||
} | ||
if (!hasTransactionAdvice(txnAuthJSON)) { | ||
throw new Error("Error: TransactionConditionAdvice is empty."); | ||
} | ||
_b.label = 10; | ||
case 10: | ||
_b.trys.push([10, 13, , 14]); | ||
// Walk through auth tree | ||
return [4 /*yield*/, this.stepIterator(initialStep, options.txnAuth.handleStep)]; | ||
case 11: | ||
// Walk through auth tree | ||
_b.sent(); | ||
// Add Txn ID to *original* request options | ||
options.txnAuth.txnID = txnAuthJSON.advices.TransactionConditionAdvice[0]; | ||
return [4 /*yield*/, this._request(options, false)]; | ||
case 12: | ||
// Retry original resource request | ||
res = _b.sent(); | ||
return [3 /*break*/, 14]; | ||
case 13: | ||
err_1 = _b.sent(); | ||
throw new Error(err_1); | ||
case 14: return [2 /*return*/, res]; | ||
} | ||
@@ -86,5 +137,82 @@ }); | ||
}; | ||
HttpClient.setAuthHeaders = function (headers, options, forceRenew) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var txnAuthRequest, tokens; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
txnAuthRequest = options.txnAuth && options.txnAuth.handleStep; | ||
return [4 /*yield*/, TokenStorage.get()]; | ||
case 1: | ||
tokens = _a.sent(); | ||
if (!tokens.accessToken) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, TokenManager.getTokens({ forceRenew: forceRenew })]; | ||
case 2: | ||
// Access tokens are an OAuth artifact | ||
tokens = _a.sent(); | ||
headers.set('Authorization', "Bearer " + tokens.accessToken); | ||
if (txnAuthRequest) { | ||
headers.set('X-Id-Token', tokens.idToken || ''); | ||
headers.set('X-Txn-Id', (options.txnAuth && options.txnAuth.txnID) || ''); | ||
} | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
// If no access tokens, OAuth is not being used. | ||
if (txnAuthRequest) { | ||
headers.set('X-Txn-Id', (options.txnAuth && options.txnAuth.txnID) || ''); | ||
} | ||
_a.label = 4; | ||
case 4: return [2 /*return*/, headers]; | ||
} | ||
}); | ||
}); | ||
}; | ||
HttpClient.stepIterator = function (res, handleStep) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var jsonRes, initialStep; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, res.json()]; | ||
case 1: | ||
jsonRes = _a.sent(); | ||
initialStep = new FRStep(jsonRes); | ||
return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { | ||
function handleNext(step) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var input, output; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, handleStep(step)]; | ||
case 1: | ||
input = _a.sent(); | ||
return [4 /*yield*/, FRAuth.next(input)]; | ||
case 2: | ||
output = _a.sent(); | ||
if (output.type === StepType.LoginSuccess) { | ||
resolve(); | ||
} | ||
else if (output.type === StepType.LoginFailure) { | ||
reject('Transaction authorization failure.'); | ||
} | ||
else { | ||
handleNext(output); | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
} | ||
return __generator(this, function (_a) { | ||
handleNext(initialStep); | ||
return [2 /*return*/]; | ||
}); | ||
}); })]; | ||
} | ||
}); | ||
}); | ||
}; | ||
HttpClient._request = function (options, forceRenew) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, init, timeout, headers, tokens; | ||
var url, init, timeout, headers; | ||
return __generator(this, function (_a) { | ||
@@ -96,6 +224,5 @@ switch (_a.label) { | ||
if (!!options.bypassAuthentication) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, TokenManager.getTokens({ forceRenew: forceRenew })]; | ||
return [4 /*yield*/, this.setAuthHeaders(headers, options, forceRenew)]; | ||
case 1: | ||
tokens = _a.sent(); | ||
headers.set('authorization', "Bearer " + tokens.accessToken); | ||
headers = _a.sent(); | ||
_a.label = 2; | ||
@@ -110,8 +237,2 @@ case 2: | ||
}; | ||
HttpClient.newTokenRequired = function (res, requiresNewToken) { | ||
if (typeof requiresNewToken === 'function') { | ||
return requiresNewToken(res); | ||
} | ||
return res.status === 401; | ||
}; | ||
return HttpClient; | ||
@@ -118,0 +239,0 @@ }(Dispatcher)); |
@@ -0,10 +1,15 @@ | ||
import { ConfigOptions } from '../config/interfaces'; | ||
import FRStep from '../fr-auth/fr-step'; | ||
export declare type HandleStep = (step: FRStep) => Promise<FRStep>; | ||
/** | ||
* A function that determines whether a new token is required based on a HTTP response. | ||
*/ | ||
declare type RequiresNewTokenFn = (res: Response) => boolean; | ||
/** | ||
* Options to use when making an HTTP call. | ||
*/ | ||
interface HttpClientRequestOptions { | ||
export interface HttpClientRequestOptions { | ||
bypassAuthentication?: boolean; | ||
txnAuth?: { | ||
config?: ConfigOptions; | ||
handleStep: HandleStep; | ||
idToken?: string; | ||
txnID?: string; | ||
}; | ||
init: RequestInit; | ||
@@ -15,2 +20,18 @@ requiresNewToken?: RequiresNewTokenFn; | ||
} | ||
export { HttpClientRequestOptions, RequiresNewTokenFn }; | ||
/** | ||
* A function that determines whether a new token is required based on a HTTP response. | ||
*/ | ||
export declare type RequiresNewTokenFn = (res: Response) => boolean; | ||
export interface TxnAuthJSON { | ||
resource: string; | ||
actions: { | ||
[key: string]: string; | ||
}; | ||
attributes: { | ||
[key: string]: string; | ||
}; | ||
advices: { | ||
TransactionConditionAdvice: string[]; | ||
} | null; | ||
ttl: number; | ||
} |
@@ -11,2 +11,3 @@ import Auth from './auth'; | ||
import ConfirmationCallback from './fr-auth/callbacks/confirmation-callback'; | ||
import DeviceProfileCallback from './fr-auth/callbacks/device-profile-callback'; | ||
import { FRCallbackFactory } from './fr-auth/callbacks/factory'; | ||
@@ -29,2 +30,3 @@ import HiddenValueCallback from './fr-auth/callbacks/hidden-value-callback'; | ||
import { AuthResponse, FailureDetail } from './fr-auth/interfaces'; | ||
import FRDevice from './fr-device'; | ||
import FRPolicy, { MessageCreator, PolicyKey, ProcessedPropertyError } from './fr-policy'; | ||
@@ -46,2 +48,2 @@ import defaultMessageCreator from './fr-policy/message-creator'; | ||
import LocalStorage from './util/storage'; | ||
export { defaultMessageCreator, nonce, AttributeInputCallback, Auth, AuthResponse, Callback, CallbackContainer, CallbackType, ChoiceCallback, Config, ConfigOptions, ConfirmationCallback, Deferred, Dispatcher, ErrorCode, FailureDetail, FRAuth, FRCallback, FRCallbackFactory, FREvent, FRLoginFailure, FRLoginSuccess, FRPolicy, FRStep, FRStepHandler, FRUI, FRUser, FRWebAuthn, GetAuthorizationUrlOptions, GetOAuth2TokensOptions, GetTokensOptions, HiddenValueCallback, HttpClient, KbaCreateCallback, Listener, LocalStorage, MessageCreator, MetadataCallback, NameCallback, NameValue, OAuth2Client, OAuth2Tokens, PasswordCallback, PKCE, PolicyKey, PolicyRequirement, PollingWaitCallback, ProcessedPropertyError, ReCaptchaCallback, RelyingParty, ResponseType, SessionManager, Step, StepDetail, StepType, TermsAndConditionsCallback, TextOutputCallback, TokenManager, Tokens, TokenStorage, UserManager, ValidatedCreatePasswordCallback, ValidatedCreateUsernameCallback, ValidConfigOptions, WebAuthnAuthenticationMetadata, WebAuthnCallbacks, WebAuthnOutcome, WebAuthnRegistrationMetadata, WebAuthnStepType, }; | ||
export { defaultMessageCreator, nonce, AttributeInputCallback, Auth, AuthResponse, Callback, CallbackContainer, CallbackType, ChoiceCallback, Config, ConfigOptions, ConfirmationCallback, Deferred, DeviceProfileCallback, Dispatcher, ErrorCode, FailureDetail, FRAuth, FRCallback, FRCallbackFactory, FRDevice, FREvent, FRLoginFailure, FRLoginSuccess, FRPolicy, FRStep, FRStepHandler, FRUI, FRUser, FRWebAuthn, GetAuthorizationUrlOptions, GetOAuth2TokensOptions, GetTokensOptions, HiddenValueCallback, HttpClient, KbaCreateCallback, Listener, LocalStorage, MessageCreator, MetadataCallback, NameCallback, NameValue, OAuth2Client, OAuth2Tokens, PasswordCallback, PKCE, PolicyKey, PolicyRequirement, PollingWaitCallback, ProcessedPropertyError, ReCaptchaCallback, RelyingParty, ResponseType, SessionManager, Step, StepDetail, StepType, TermsAndConditionsCallback, TextOutputCallback, TokenManager, Tokens, TokenStorage, UserManager, ValidatedCreatePasswordCallback, ValidatedCreateUsernameCallback, ValidConfigOptions, WebAuthnAuthenticationMetadata, WebAuthnCallbacks, WebAuthnOutcome, WebAuthnRegistrationMetadata, WebAuthnStepType, }; |
@@ -10,2 +10,3 @@ import Auth from './auth'; | ||
import ConfirmationCallback from './fr-auth/callbacks/confirmation-callback'; | ||
import DeviceProfileCallback from './fr-auth/callbacks/device-profile-callback'; | ||
import HiddenValueCallback from './fr-auth/callbacks/hidden-value-callback'; | ||
@@ -28,2 +29,3 @@ import KbaCreateCallback from './fr-auth/callbacks/kba-create-callback'; | ||
import FRStep from './fr-auth/fr-step'; | ||
import FRDevice from './fr-device'; | ||
import FRPolicy, { PolicyKey } from './fr-policy'; | ||
@@ -43,3 +45,3 @@ import defaultMessageCreator from './fr-policy/message-creator'; | ||
import LocalStorage from './util/storage'; | ||
export { defaultMessageCreator, nonce, AttributeInputCallback, Auth, CallbackType, ChoiceCallback, Config, ConfirmationCallback, Deferred, Dispatcher, ErrorCode, FRAuth, FRCallback, FRLoginFailure, FRLoginSuccess, FRPolicy, FRStep, FRUser, FRWebAuthn, HiddenValueCallback, HttpClient, KbaCreateCallback, LocalStorage, MetadataCallback, NameCallback, OAuth2Client, PasswordCallback, PKCE, PolicyKey, PollingWaitCallback, ReCaptchaCallback, ResponseType, SessionManager, StepType, TermsAndConditionsCallback, TextOutputCallback, TokenManager, TokenStorage, UserManager, ValidatedCreatePasswordCallback, ValidatedCreateUsernameCallback, WebAuthnOutcome, WebAuthnStepType, }; | ||
export { defaultMessageCreator, nonce, AttributeInputCallback, Auth, CallbackType, ChoiceCallback, Config, ConfirmationCallback, Deferred, DeviceProfileCallback, Dispatcher, ErrorCode, FRAuth, FRCallback, FRDevice, FRLoginFailure, FRLoginSuccess, FRPolicy, FRStep, FRUser, FRWebAuthn, HiddenValueCallback, HttpClient, KbaCreateCallback, LocalStorage, MetadataCallback, NameCallback, OAuth2Client, PasswordCallback, PKCE, PolicyKey, PollingWaitCallback, ReCaptchaCallback, ResponseType, SessionManager, StepType, TermsAndConditionsCallback, TextOutputCallback, TokenManager, TokenStorage, UserManager, ValidatedCreatePasswordCallback, ValidatedCreateUsernameCallback, WebAuthnOutcome, WebAuthnStepType, }; | ||
//# sourceMappingURL=index.js.map |
@@ -23,7 +23,7 @@ import { ConfigOptions } from '../config/index'; | ||
*/ | ||
static endSession(options?: ConfigOptions): Promise<void>; | ||
static endSession(options?: ConfigOptions): Promise<Response>; | ||
/** | ||
* Immediately revokes the stored access token. | ||
*/ | ||
static revokeToken(options?: ConfigOptions): Promise<void>; | ||
static revokeToken(options?: ConfigOptions): Promise<Response>; | ||
private static request; | ||
@@ -30,0 +30,0 @@ private static containsAuthCode; |
@@ -41,5 +41,4 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import PKCE from '../util/pkce'; | ||
import { getRealmUrlPath } from '../util/realm'; | ||
import { withTimeout } from '../util/timeout'; | ||
import { resolve, stringify } from '../util/url'; | ||
import { getEndpointPath, resolve, stringify } from '../util/url'; | ||
import { ResponseType } from './enums'; | ||
@@ -146,3 +145,3 @@ /** | ||
}; | ||
return [4 /*yield*/, this.request('access_token', undefined, false, init, options)]; | ||
return [4 /*yield*/, this.request('accessToken', undefined, false, init, options)]; | ||
case 1: | ||
@@ -180,3 +179,3 @@ response = _b.sent(); | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.request('userinfo', undefined, true, undefined, options)]; | ||
case 0: return [4 /*yield*/, this.request('userInfo', undefined, true, undefined, options)]; | ||
case 1: | ||
@@ -211,3 +210,3 @@ response = _a.sent(); | ||
} | ||
return [4 /*yield*/, this.request('connect/endSession', query, true, undefined, options)]; | ||
return [4 /*yield*/, this.request('endSession', query, true, undefined, options)]; | ||
case 2: | ||
@@ -218,3 +217,3 @@ response = _a.sent(); | ||
} | ||
return [2 /*return*/]; | ||
return [2 /*return*/, response]; | ||
} | ||
@@ -244,3 +243,3 @@ }); | ||
}; | ||
return [4 /*yield*/, this.request('token/revoke', undefined, false, init, options)]; | ||
return [4 /*yield*/, this.request('revoke', undefined, false, init, options)]; | ||
case 2: | ||
@@ -251,3 +250,3 @@ response = _a.sent(); | ||
} | ||
return [2 /*return*/]; | ||
return [2 /*return*/, response]; | ||
} | ||
@@ -257,3 +256,3 @@ }); | ||
}; | ||
OAuth2Client.request = function (path, query, includeToken, init, options) { | ||
OAuth2Client.request = function (endpoint, query, includeToken, init, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
@@ -265,3 +264,3 @@ var serverConfig, url, accessToken; | ||
serverConfig = Config.get(options).serverConfig; | ||
url = this.getUrl(path, query, options); | ||
url = this.getUrl(endpoint, query, options); | ||
init = init || {}; | ||
@@ -312,6 +311,6 @@ if (!includeToken) return [3 /*break*/, 2]; | ||
}; | ||
OAuth2Client.getUrl = function (path, query, options) { | ||
OAuth2Client.getUrl = function (endpoint, query, options) { | ||
var _a = Config.get(options), realmPath = _a.realmPath, serverConfig = _a.serverConfig; | ||
var realmUrlPath = getRealmUrlPath(realmPath); | ||
var url = resolve(serverConfig.baseUrl, "oauth2/" + realmUrlPath + "/" + path); | ||
var path = getEndpointPath(endpoint, realmPath, serverConfig.paths); | ||
var url = resolve(serverConfig.baseUrl, path); | ||
if (query) { | ||
@@ -318,0 +317,0 @@ url += "?" + stringify(query); |
@@ -9,4 +9,4 @@ import { ConfigOptions } from '../config/index'; | ||
*/ | ||
static logout(options?: ConfigOptions): Promise<void>; | ||
static logout(options?: ConfigOptions): Promise<Response>; | ||
} | ||
export default SessionManager; |
@@ -40,5 +40,4 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { isOkOr4xx } from '../util/http'; | ||
import { getRealmUrlPath } from '../util/realm'; | ||
import { withTimeout } from '../util/timeout'; | ||
import { resolve } from '../util/url'; | ||
import { getEndpointPath, resolve } from '../util/url'; | ||
/** | ||
@@ -55,3 +54,3 @@ * Provides access to the session management API. | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _a, realmPath, serverConfig, init, realmUrlPath, url, response; | ||
var _a, realmPath, serverConfig, init, path, url, response; | ||
return __generator(this, function (_b) { | ||
@@ -69,4 +68,4 @@ switch (_b.label) { | ||
}; | ||
realmUrlPath = getRealmUrlPath(realmPath); | ||
url = resolve(serverConfig.baseUrl, "json/" + realmUrlPath + "/sessions/?_action=logout"); | ||
path = getEndpointPath('sessions', realmPath, serverConfig.paths) + "?_action=logout"; | ||
url = resolve(serverConfig.baseUrl, path); | ||
return [4 /*yield*/, withTimeout(fetch(url, init), serverConfig.timeout)]; | ||
@@ -78,3 +77,3 @@ case 1: | ||
} | ||
return [2 /*return*/]; | ||
return [2 /*return*/, response]; | ||
} | ||
@@ -81,0 +80,0 @@ }); |
@@ -18,5 +18,4 @@ import { Tokens } from '../shared/interfaces'; | ||
static remove(): Promise<void>; | ||
private static getClientId; | ||
private static getResult; | ||
private static getClientConfig; | ||
} | ||
export default TokenStorage; |
@@ -38,3 +38,4 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import Config from '../config/index'; | ||
import { DB_NAME, TOKEN_KEY } from './constants'; | ||
import IndexedDBWrapper from './indexed-db'; | ||
import LocalStorageWrapper from './local-storage'; | ||
/** | ||
@@ -51,31 +52,25 @@ * Provides access to the token storage API. | ||
return __awaiter(this, void 0, void 0, function () { | ||
var clientId; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
clientId = this.getClientId(); | ||
return [2 /*return*/, new Promise(function (resolve, reject) { | ||
var onError = function () { return reject(); }; | ||
var openReq = window.indexedDB.open(DB_NAME); | ||
openReq.onsuccess = function () { | ||
if (!openReq.result.objectStoreNames.contains(clientId)) { | ||
openReq.result.close(); | ||
return resolve(undefined); | ||
} | ||
var getReq = openReq.result | ||
.transaction(clientId, 'readonly') | ||
.objectStore(clientId) | ||
.get(TOKEN_KEY); | ||
getReq.onsuccess = function (event) { | ||
var tokens = _this.getResult(event); | ||
openReq.result.close(); | ||
resolve(tokens); | ||
}; | ||
getReq.onerror = onError; | ||
}; | ||
openReq.onupgradeneeded = function () { | ||
openReq.result.close(); | ||
resolve(undefined); | ||
}; | ||
openReq.onerror = onError; | ||
})]; | ||
var _a, clientId, tokenStore; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_a = this.getClientConfig(), clientId = _a.clientId, tokenStore = _a.tokenStore; | ||
if (!(tokenStore === 'localStorage')) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, LocalStorageWrapper.get(clientId)]; | ||
case 1: return [2 /*return*/, _b.sent()]; | ||
case 2: | ||
if (!(tokenStore === 'indexedDB')) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, IndexedDBWrapper.get(clientId)]; | ||
case 3: return [2 /*return*/, _b.sent()]; | ||
case 4: | ||
if (!(tokenStore && tokenStore.get)) return [3 /*break*/, 6]; | ||
return [4 /*yield*/, tokenStore.get(clientId)]; | ||
case 5: | ||
// User supplied token store | ||
return [2 /*return*/, _b.sent()]; | ||
case 6: return [4 /*yield*/, IndexedDBWrapper.get(clientId)]; | ||
case 7: | ||
// if tokenStore is undefined, default to previous behavior | ||
return [2 /*return*/, _b.sent()]; | ||
} | ||
}); | ||
@@ -89,36 +84,25 @@ }); | ||
return __awaiter(this, void 0, void 0, function () { | ||
var clientId; | ||
return __generator(this, function (_a) { | ||
clientId = this.getClientId(); | ||
return [2 /*return*/, new Promise(function (resolve, reject) { | ||
var openReq = window.indexedDB.open(DB_NAME); | ||
var onSetSuccess = function () { | ||
openReq.result.close(); | ||
resolve(); | ||
}; | ||
var onError = function () { return reject(); }; | ||
var onUpgradeNeeded = function () { | ||
openReq.result.createObjectStore(clientId); | ||
}; | ||
var onOpenSuccess = function () { | ||
if (!openReq.result.objectStoreNames.contains(clientId)) { | ||
var version = openReq.result.version + 1; | ||
openReq.result.close(); | ||
openReq = window.indexedDB.open(DB_NAME, version); | ||
openReq.onupgradeneeded = onUpgradeNeeded; | ||
openReq.onsuccess = onOpenSuccess; | ||
openReq.onerror = onError; | ||
return; | ||
} | ||
var txnReq = openReq.result.transaction(clientId, 'readwrite'); | ||
txnReq.onerror = onError; | ||
var objectStore = txnReq.objectStore(clientId); | ||
var putReq = objectStore.put(tokens, TOKEN_KEY); | ||
putReq.onsuccess = onSetSuccess; | ||
putReq.onerror = onError; | ||
}; | ||
openReq.onupgradeneeded = onUpgradeNeeded; | ||
openReq.onsuccess = onOpenSuccess; | ||
openReq.onerror = onError; | ||
})]; | ||
var _a, clientId, tokenStore; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_a = this.getClientConfig(), clientId = _a.clientId, tokenStore = _a.tokenStore; | ||
if (!(tokenStore === 'localStorage')) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, LocalStorageWrapper.set(clientId, tokens)]; | ||
case 1: return [2 /*return*/, _b.sent()]; | ||
case 2: | ||
if (!(tokenStore === 'indexedDB')) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, IndexedDBWrapper.set(clientId, tokens)]; | ||
case 3: return [2 /*return*/, _b.sent()]; | ||
case 4: | ||
if (!(tokenStore && tokenStore.set)) return [3 /*break*/, 6]; | ||
return [4 /*yield*/, tokenStore.set(clientId, tokens)]; | ||
case 5: | ||
// User supplied token store | ||
return [2 /*return*/, _b.sent()]; | ||
case 6: return [4 /*yield*/, IndexedDBWrapper.set(clientId, tokens)]; | ||
case 7: | ||
// if tokenStore is undefined, default to previous behavior | ||
return [2 /*return*/, _b.sent()]; | ||
} | ||
}); | ||
@@ -132,39 +116,35 @@ }); | ||
return __awaiter(this, void 0, void 0, function () { | ||
var clientId; | ||
return __generator(this, function (_a) { | ||
clientId = this.getClientId(); | ||
return [2 /*return*/, new Promise(function (resolve, reject) { | ||
var onError = function () { return reject(); }; | ||
var openReq = window.indexedDB.open(DB_NAME); | ||
openReq.onsuccess = function () { | ||
if (!openReq.result.objectStoreNames.contains(clientId)) { | ||
return resolve(); | ||
} | ||
var removeReq = openReq.result | ||
.transaction(clientId, 'readwrite') | ||
.objectStore(clientId) | ||
.delete(TOKEN_KEY); | ||
removeReq.onsuccess = function () { | ||
resolve(); | ||
}; | ||
removeReq.onerror = onError; | ||
}; | ||
openReq.onerror = onError; | ||
})]; | ||
var _a, clientId, tokenStore; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_a = this.getClientConfig(), clientId = _a.clientId, tokenStore = _a.tokenStore; | ||
if (!(tokenStore === 'localStorage')) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, LocalStorageWrapper.remove(clientId)]; | ||
case 1: return [2 /*return*/, _b.sent()]; | ||
case 2: | ||
if (!(tokenStore === 'indexedDB')) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, IndexedDBWrapper.remove(clientId)]; | ||
case 3: return [2 /*return*/, _b.sent()]; | ||
case 4: | ||
if (!(tokenStore && tokenStore.remove)) return [3 /*break*/, 6]; | ||
return [4 /*yield*/, tokenStore.remove(clientId)]; | ||
case 5: | ||
// User supplied token store | ||
return [2 /*return*/, _b.sent()]; | ||
case 6: return [4 /*yield*/, IndexedDBWrapper.remove(clientId)]; | ||
case 7: | ||
// if tokenStore is undefined, default to previous behavior | ||
return [2 /*return*/, _b.sent()]; | ||
} | ||
}); | ||
}); | ||
}; | ||
TokenStorage.getClientId = function () { | ||
var clientId = Config.get().clientId; | ||
TokenStorage.getClientConfig = function () { | ||
var _a = Config.get(), clientId = _a.clientId, tokenStore = _a.tokenStore; | ||
if (!clientId) { | ||
throw new Error('clientId is required to manage token storage'); | ||
} | ||
return clientId; | ||
return { clientId: clientId, tokenStore: tokenStore }; | ||
}; | ||
TokenStorage.getResult = function (event) { | ||
if (!event || !event.target) { | ||
throw new Error('Missing storage event target'); | ||
} | ||
return event.target.result; | ||
}; | ||
return TokenStorage; | ||
@@ -171,0 +151,0 @@ }()); |
@@ -0,1 +1,2 @@ | ||
import { ConfigurablePaths, CustomPathConfig } from '../config/interfaces'; | ||
import { StringDict } from '../shared/interfaces'; | ||
@@ -7,5 +8,6 @@ /** | ||
declare function getBaseUrl(url: URL): string; | ||
declare function getEndpointPath(endpoint: ConfigurablePaths, realmPath?: string, customPaths?: CustomPathConfig): string; | ||
declare function resolve(baseUrl: string, path: string): string; | ||
declare function parseQuery(fullUrl: string): StringDict<string>; | ||
declare function stringify(data: StringDict<string | undefined>): string; | ||
export { getBaseUrl, parseQuery, resolve, stringify }; | ||
export { getBaseUrl, getEndpointPath, parseQuery, resolve, stringify }; |
@@ -8,2 +8,3 @@ var __spreadArrays = (this && this.__spreadArrays) || function () { | ||
}; | ||
import { getRealmUrlPath } from '../util/realm'; | ||
/** | ||
@@ -20,2 +21,24 @@ * Returns the base URL including protocol, hostname and any non-standard port. | ||
} | ||
function getEndpointPath(endpoint, realmPath, customPaths) { | ||
var realmUrlPath = getRealmUrlPath(realmPath); | ||
var defaultPaths = { | ||
authenticate: "json/" + realmUrlPath + "/authenticate", | ||
authorize: "oauth2/" + realmUrlPath + "/authorize", | ||
accessToken: "oauth2/" + realmUrlPath + "/access_token", | ||
endSession: "oauth2/" + realmUrlPath + "/connect/endSession", | ||
userInfo: "oauth2/" + realmUrlPath + "/userinfo", | ||
revoke: "oauth2/" + realmUrlPath + "/token/revoke", | ||
sessions: "json/" + realmUrlPath + "/sessions/", | ||
}; | ||
if (customPaths && customPaths[endpoint]) { | ||
// TypeScript is not correctly reading the condition above | ||
// It's thinking that customPaths[endpoint] may result in undefined | ||
// eslint-disable-next-line | ||
// @ts-ignore | ||
return customPaths[endpoint]; | ||
} | ||
else { | ||
return defaultPaths[endpoint]; | ||
} | ||
} | ||
function resolve(baseUrl, path) { | ||
@@ -46,3 +69,3 @@ var url = new URL(baseUrl); | ||
} | ||
export { getBaseUrl, parseQuery, resolve, stringify }; | ||
export { getBaseUrl, getEndpointPath, parseQuery, resolve, stringify }; | ||
//# sourceMappingURL=url.js.map |
@@ -17,2 +17,3 @@ /** | ||
ConfirmationCallback = "ConfirmationCallback", | ||
DeviceProfileCallback = "DeviceProfileCallback", | ||
HiddenValueCallback = "HiddenValueCallback", | ||
@@ -19,0 +20,0 @@ KbaCreateCallback = "KbaCreateCallback", |
@@ -22,2 +22,3 @@ "use strict"; | ||
CallbackType["ConfirmationCallback"] = "ConfirmationCallback"; | ||
CallbackType["DeviceProfileCallback"] = "DeviceProfileCallback"; | ||
CallbackType["HiddenValueCallback"] = "HiddenValueCallback"; | ||
@@ -24,0 +25,0 @@ CallbackType["KbaCreateCallback"] = "KbaCreateCallback"; |
@@ -55,3 +55,2 @@ "use strict"; | ||
var constants_1 = require("../shared/constants"); | ||
var realm_1 = require("../util/realm"); | ||
var timeout_1 = require("../util/timeout"); | ||
@@ -94,8 +93,7 @@ var url_1 = require("../util/url"); | ||
Auth.constructUrl = function (serverConfig, realmPath, tree, query) { | ||
var realmUrlPath = realm_1.getRealmUrlPath(realmPath); | ||
var treeParams = tree ? { authIndexType: 'service', authIndexValue: tree } : undefined; | ||
var params = __assign(__assign({}, query), treeParams); | ||
var queryString = Object.keys(params).length > 0 ? "?" + url_1.stringify(params) : ''; | ||
var path = "json/" + realmUrlPath + "/authenticate" + queryString; | ||
var url = url_1.resolve(serverConfig.baseUrl, path); | ||
var path = url_1.getEndpointPath('authenticate', realmPath, serverConfig.paths); | ||
var url = url_1.resolve(serverConfig.baseUrl, "" + path + queryString); | ||
return url; | ||
@@ -102,0 +100,0 @@ }; |
/** @hidden */ | ||
declare const DEFAULT_TIMEOUT = 5000; | ||
declare const DEFAULT_TIMEOUT: number; | ||
export { DEFAULT_TIMEOUT }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** @hidden */ | ||
var DEFAULT_TIMEOUT = 5000; | ||
var DEFAULT_TIMEOUT = 60 * 1000; | ||
exports.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT; | ||
//# sourceMappingURL=constants.js.map |
import { FRCallbackFactory } from '../fr-auth/callbacks/factory'; | ||
import { Tokens } from '../shared/interfaces'; | ||
/** | ||
* Configuration settings for connecting to a server. | ||
*/ | ||
interface ServerConfig { | ||
baseUrl: string; | ||
timeout: number; | ||
} | ||
/** | ||
* Configuration options. | ||
@@ -19,5 +13,35 @@ */ | ||
serverConfig?: ServerConfig; | ||
tokenStore?: TokenStoreObject | 'indexedDB' | 'localStorage'; | ||
tree?: string; | ||
} | ||
declare type ConfigurablePaths = 'authenticate' | 'authorize' | 'accessToken' | 'endSession' | 'userInfo' | 'revoke' | 'sessions'; | ||
/** | ||
* Optional configuration for custom paths for actions | ||
*/ | ||
interface CustomPathConfig { | ||
authenticate?: string; | ||
authorize?: string; | ||
accessToken?: string; | ||
endSession?: string; | ||
userInfo?: string; | ||
revoke?: string; | ||
sessions?: string; | ||
} | ||
/** | ||
* Configuration settings for connecting to a server. | ||
*/ | ||
interface ServerConfig { | ||
baseUrl: string; | ||
paths?: CustomPathConfig; | ||
timeout: number; | ||
} | ||
/** | ||
* API for implementing a custom token store | ||
*/ | ||
interface TokenStoreObject { | ||
get: (clientId: string) => Promise<Tokens>; | ||
set: (clientId: string, token: Tokens) => Promise<void>; | ||
remove: (clientId: string) => Promise<void>; | ||
} | ||
/** | ||
* Configuration options with a server configuration specified. | ||
@@ -28,2 +52,2 @@ */ | ||
} | ||
export { ConfigOptions, ServerConfig, ValidConfigOptions }; | ||
export { ConfigOptions, ConfigurablePaths, CustomPathConfig, ServerConfig, TokenStoreObject, ValidConfigOptions, }; |
@@ -11,2 +11,3 @@ "use strict"; | ||
var confirmation_callback_1 = __importDefault(require("./confirmation-callback")); | ||
var device_profile_callback_1 = __importDefault(require("./device-profile-callback")); | ||
var hidden_value_callback_1 = __importDefault(require("./hidden-value-callback")); | ||
@@ -34,2 +35,4 @@ var kba_create_callback_1 = __importDefault(require("./kba-create-callback")); | ||
return new confirmation_callback_1.default(callback); | ||
case enums_1.CallbackType.DeviceProfileCallback: | ||
return new device_profile_callback_1.default(callback); | ||
case enums_1.CallbackType.HiddenValueCallback: | ||
@@ -36,0 +39,0 @@ return new hidden_value_callback_1.default(callback); |
@@ -13,6 +13,7 @@ import Dispatcher from '../event'; | ||
static request(options: HttpClientRequestOptions): Promise<Response>; | ||
private static setAuthHeaders; | ||
private static stepIterator; | ||
private static _request; | ||
private static newTokenRequired; | ||
} | ||
export default HttpClient; | ||
export { HttpClientRequestOptions, RequiresNewTokenFn }; |
@@ -55,5 +55,11 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var config_1 = __importDefault(require("../config")); | ||
var event_1 = __importDefault(require("../event")); | ||
var fr_auth_1 = __importDefault(require("../fr-auth")); | ||
var enums_1 = require("../fr-auth/enums"); | ||
var fr_step_1 = __importDefault(require("../fr-auth/fr-step")); | ||
var token_manager_1 = __importDefault(require("../token-manager")); | ||
var token_storage_1 = __importDefault(require("../token-storage")); | ||
var timeout_1 = require("../util/timeout"); | ||
var util_1 = require("./util"); | ||
/** | ||
@@ -74,14 +80,59 @@ * HTTP client that includes bearer token injection and refresh. | ||
return __awaiter(this, void 0, void 0, function () { | ||
var res; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
var res, txnAuthJSON, _a, realmPath, serverConfig, txnAuthOptions, initialStep, err_1; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: return [4 /*yield*/, this._request(options, false)]; | ||
case 1: | ||
res = _a.sent(); | ||
if (!this.newTokenRequired(res, options.requiresNewToken)) return [3 /*break*/, 3]; | ||
res = _b.sent(); | ||
if (!util_1.newTokenRequired(res, options.requiresNewToken)) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, this._request(options, true)]; | ||
case 2: | ||
res = _a.sent(); | ||
_a.label = 3; | ||
case 3: return [2 /*return*/, res]; | ||
res = _b.sent(); | ||
_b.label = 3; | ||
case 3: | ||
if (!(options.txnAuth && options.txnAuth.handleStep)) return [3 /*break*/, 14]; | ||
if (!(res.redirected && util_1.examineForIGTxnAuth(res))) return [3 /*break*/, 4]; | ||
txnAuthJSON = util_1.normalizeIGJSON(res); | ||
return [3 /*break*/, 7]; | ||
case 4: return [4 /*yield*/, util_1.examineForRESTTxnAuth(res)]; | ||
case 5: | ||
if (!_b.sent()) return [3 /*break*/, 7]; | ||
return [4 /*yield*/, util_1.normalizeRESTJSON(res)]; | ||
case 6: | ||
txnAuthJSON = _b.sent(); | ||
_b.label = 7; | ||
case 7: | ||
if (!(txnAuthJSON && txnAuthJSON.advices)) return [3 /*break*/, 14]; | ||
_a = config_1.default.get(options.txnAuth.config), realmPath = _a.realmPath, serverConfig = _a.serverConfig; | ||
txnAuthOptions = util_1.buildTxnAuthOptions(txnAuthJSON, serverConfig.baseUrl, options.timeout, realmPath, serverConfig.paths); | ||
return [4 /*yield*/, this._request(txnAuthOptions, false)]; | ||
case 8: | ||
initialStep = _b.sent(); | ||
return [4 /*yield*/, util_1.isAuthStep(initialStep)]; | ||
case 9: | ||
if (!(_b.sent())) { | ||
throw new Error('Error: Initial response from auth server not a "step".'); | ||
} | ||
if (!util_1.hasTransactionAdvice(txnAuthJSON)) { | ||
throw new Error("Error: TransactionConditionAdvice is empty."); | ||
} | ||
_b.label = 10; | ||
case 10: | ||
_b.trys.push([10, 13, , 14]); | ||
// Walk through auth tree | ||
return [4 /*yield*/, this.stepIterator(initialStep, options.txnAuth.handleStep)]; | ||
case 11: | ||
// Walk through auth tree | ||
_b.sent(); | ||
// Add Txn ID to *original* request options | ||
options.txnAuth.txnID = txnAuthJSON.advices.TransactionConditionAdvice[0]; | ||
return [4 /*yield*/, this._request(options, false)]; | ||
case 12: | ||
// Retry original resource request | ||
res = _b.sent(); | ||
return [3 /*break*/, 14]; | ||
case 13: | ||
err_1 = _b.sent(); | ||
throw new Error(err_1); | ||
case 14: return [2 /*return*/, res]; | ||
} | ||
@@ -91,5 +142,82 @@ }); | ||
}; | ||
HttpClient.setAuthHeaders = function (headers, options, forceRenew) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var txnAuthRequest, tokens; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
txnAuthRequest = options.txnAuth && options.txnAuth.handleStep; | ||
return [4 /*yield*/, token_storage_1.default.get()]; | ||
case 1: | ||
tokens = _a.sent(); | ||
if (!tokens.accessToken) return [3 /*break*/, 3]; | ||
return [4 /*yield*/, token_manager_1.default.getTokens({ forceRenew: forceRenew })]; | ||
case 2: | ||
// Access tokens are an OAuth artifact | ||
tokens = _a.sent(); | ||
headers.set('Authorization', "Bearer " + tokens.accessToken); | ||
if (txnAuthRequest) { | ||
headers.set('X-Id-Token', tokens.idToken || ''); | ||
headers.set('X-Txn-Id', (options.txnAuth && options.txnAuth.txnID) || ''); | ||
} | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
// If no access tokens, OAuth is not being used. | ||
if (txnAuthRequest) { | ||
headers.set('X-Txn-Id', (options.txnAuth && options.txnAuth.txnID) || ''); | ||
} | ||
_a.label = 4; | ||
case 4: return [2 /*return*/, headers]; | ||
} | ||
}); | ||
}); | ||
}; | ||
HttpClient.stepIterator = function (res, handleStep) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var jsonRes, initialStep; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, res.json()]; | ||
case 1: | ||
jsonRes = _a.sent(); | ||
initialStep = new fr_step_1.default(jsonRes); | ||
return [2 /*return*/, new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { | ||
function handleNext(step) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var input, output; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, handleStep(step)]; | ||
case 1: | ||
input = _a.sent(); | ||
return [4 /*yield*/, fr_auth_1.default.next(input)]; | ||
case 2: | ||
output = _a.sent(); | ||
if (output.type === enums_1.StepType.LoginSuccess) { | ||
resolve(); | ||
} | ||
else if (output.type === enums_1.StepType.LoginFailure) { | ||
reject('Transaction authorization failure.'); | ||
} | ||
else { | ||
handleNext(output); | ||
} | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
} | ||
return __generator(this, function (_a) { | ||
handleNext(initialStep); | ||
return [2 /*return*/]; | ||
}); | ||
}); })]; | ||
} | ||
}); | ||
}); | ||
}; | ||
HttpClient._request = function (options, forceRenew) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, init, timeout, headers, tokens; | ||
var url, init, timeout, headers; | ||
return __generator(this, function (_a) { | ||
@@ -101,6 +229,5 @@ switch (_a.label) { | ||
if (!!options.bypassAuthentication) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, token_manager_1.default.getTokens({ forceRenew: forceRenew })]; | ||
return [4 /*yield*/, this.setAuthHeaders(headers, options, forceRenew)]; | ||
case 1: | ||
tokens = _a.sent(); | ||
headers.set('authorization', "Bearer " + tokens.accessToken); | ||
headers = _a.sent(); | ||
_a.label = 2; | ||
@@ -115,8 +242,2 @@ case 2: | ||
}; | ||
HttpClient.newTokenRequired = function (res, requiresNewToken) { | ||
if (typeof requiresNewToken === 'function') { | ||
return requiresNewToken(res); | ||
} | ||
return res.status === 401; | ||
}; | ||
return HttpClient; | ||
@@ -123,0 +244,0 @@ }(event_1.default)); |
@@ -0,10 +1,15 @@ | ||
import { ConfigOptions } from '../config/interfaces'; | ||
import FRStep from '../fr-auth/fr-step'; | ||
export declare type HandleStep = (step: FRStep) => Promise<FRStep>; | ||
/** | ||
* A function that determines whether a new token is required based on a HTTP response. | ||
*/ | ||
declare type RequiresNewTokenFn = (res: Response) => boolean; | ||
/** | ||
* Options to use when making an HTTP call. | ||
*/ | ||
interface HttpClientRequestOptions { | ||
export interface HttpClientRequestOptions { | ||
bypassAuthentication?: boolean; | ||
txnAuth?: { | ||
config?: ConfigOptions; | ||
handleStep: HandleStep; | ||
idToken?: string; | ||
txnID?: string; | ||
}; | ||
init: RequestInit; | ||
@@ -15,2 +20,18 @@ requiresNewToken?: RequiresNewTokenFn; | ||
} | ||
export { HttpClientRequestOptions, RequiresNewTokenFn }; | ||
/** | ||
* A function that determines whether a new token is required based on a HTTP response. | ||
*/ | ||
export declare type RequiresNewTokenFn = (res: Response) => boolean; | ||
export interface TxnAuthJSON { | ||
resource: string; | ||
actions: { | ||
[key: string]: string; | ||
}; | ||
attributes: { | ||
[key: string]: string; | ||
}; | ||
advices: { | ||
TransactionConditionAdvice: string[]; | ||
} | null; | ||
ttl: number; | ||
} |
@@ -11,2 +11,3 @@ import Auth from './auth'; | ||
import ConfirmationCallback from './fr-auth/callbacks/confirmation-callback'; | ||
import DeviceProfileCallback from './fr-auth/callbacks/device-profile-callback'; | ||
import { FRCallbackFactory } from './fr-auth/callbacks/factory'; | ||
@@ -29,2 +30,3 @@ import HiddenValueCallback from './fr-auth/callbacks/hidden-value-callback'; | ||
import { AuthResponse, FailureDetail } from './fr-auth/interfaces'; | ||
import FRDevice from './fr-device'; | ||
import FRPolicy, { MessageCreator, PolicyKey, ProcessedPropertyError } from './fr-policy'; | ||
@@ -46,2 +48,2 @@ import defaultMessageCreator from './fr-policy/message-creator'; | ||
import LocalStorage from './util/storage'; | ||
export { defaultMessageCreator, nonce, AttributeInputCallback, Auth, AuthResponse, Callback, CallbackContainer, CallbackType, ChoiceCallback, Config, ConfigOptions, ConfirmationCallback, Deferred, Dispatcher, ErrorCode, FailureDetail, FRAuth, FRCallback, FRCallbackFactory, FREvent, FRLoginFailure, FRLoginSuccess, FRPolicy, FRStep, FRStepHandler, FRUI, FRUser, FRWebAuthn, GetAuthorizationUrlOptions, GetOAuth2TokensOptions, GetTokensOptions, HiddenValueCallback, HttpClient, KbaCreateCallback, Listener, LocalStorage, MessageCreator, MetadataCallback, NameCallback, NameValue, OAuth2Client, OAuth2Tokens, PasswordCallback, PKCE, PolicyKey, PolicyRequirement, PollingWaitCallback, ProcessedPropertyError, ReCaptchaCallback, RelyingParty, ResponseType, SessionManager, Step, StepDetail, StepType, TermsAndConditionsCallback, TextOutputCallback, TokenManager, Tokens, TokenStorage, UserManager, ValidatedCreatePasswordCallback, ValidatedCreateUsernameCallback, ValidConfigOptions, WebAuthnAuthenticationMetadata, WebAuthnCallbacks, WebAuthnOutcome, WebAuthnRegistrationMetadata, WebAuthnStepType, }; | ||
export { defaultMessageCreator, nonce, AttributeInputCallback, Auth, AuthResponse, Callback, CallbackContainer, CallbackType, ChoiceCallback, Config, ConfigOptions, ConfirmationCallback, Deferred, DeviceProfileCallback, Dispatcher, ErrorCode, FailureDetail, FRAuth, FRCallback, FRCallbackFactory, FRDevice, FREvent, FRLoginFailure, FRLoginSuccess, FRPolicy, FRStep, FRStepHandler, FRUI, FRUser, FRWebAuthn, GetAuthorizationUrlOptions, GetOAuth2TokensOptions, GetTokensOptions, HiddenValueCallback, HttpClient, KbaCreateCallback, Listener, LocalStorage, MessageCreator, MetadataCallback, NameCallback, NameValue, OAuth2Client, OAuth2Tokens, PasswordCallback, PKCE, PolicyKey, PolicyRequirement, PollingWaitCallback, ProcessedPropertyError, ReCaptchaCallback, RelyingParty, ResponseType, SessionManager, Step, StepDetail, StepType, TermsAndConditionsCallback, TextOutputCallback, TokenManager, Tokens, TokenStorage, UserManager, ValidatedCreatePasswordCallback, ValidatedCreateUsernameCallback, ValidConfigOptions, WebAuthnAuthenticationMetadata, WebAuthnCallbacks, WebAuthnOutcome, WebAuthnRegistrationMetadata, WebAuthnStepType, }; |
@@ -32,2 +32,4 @@ "use strict"; | ||
exports.ConfirmationCallback = confirmation_callback_1.default; | ||
var device_profile_callback_1 = __importDefault(require("./fr-auth/callbacks/device-profile-callback")); | ||
exports.DeviceProfileCallback = device_profile_callback_1.default; | ||
var hidden_value_callback_1 = __importDefault(require("./fr-auth/callbacks/hidden-value-callback")); | ||
@@ -65,2 +67,4 @@ exports.HiddenValueCallback = hidden_value_callback_1.default; | ||
exports.FRStep = fr_step_1.default; | ||
var fr_device_1 = __importDefault(require("./fr-device")); | ||
exports.FRDevice = fr_device_1.default; | ||
var fr_policy_1 = __importStar(require("./fr-policy")); | ||
@@ -67,0 +71,0 @@ exports.FRPolicy = fr_policy_1.default; |
@@ -23,7 +23,7 @@ import { ConfigOptions } from '../config/index'; | ||
*/ | ||
static endSession(options?: ConfigOptions): Promise<void>; | ||
static endSession(options?: ConfigOptions): Promise<Response>; | ||
/** | ||
* Immediately revokes the stored access token. | ||
*/ | ||
static revokeToken(options?: ConfigOptions): Promise<void>; | ||
static revokeToken(options?: ConfigOptions): Promise<Response>; | ||
private static request; | ||
@@ -30,0 +30,0 @@ private static containsAuthCode; |
@@ -46,3 +46,2 @@ "use strict"; | ||
var pkce_1 = __importDefault(require("../util/pkce")); | ||
var realm_1 = require("../util/realm"); | ||
var timeout_1 = require("../util/timeout"); | ||
@@ -152,3 +151,3 @@ var url_1 = require("../util/url"); | ||
}; | ||
return [4 /*yield*/, this.request('access_token', undefined, false, init, options)]; | ||
return [4 /*yield*/, this.request('accessToken', undefined, false, init, options)]; | ||
case 1: | ||
@@ -186,3 +185,3 @@ response = _b.sent(); | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.request('userinfo', undefined, true, undefined, options)]; | ||
case 0: return [4 /*yield*/, this.request('userInfo', undefined, true, undefined, options)]; | ||
case 1: | ||
@@ -217,3 +216,3 @@ response = _a.sent(); | ||
} | ||
return [4 /*yield*/, this.request('connect/endSession', query, true, undefined, options)]; | ||
return [4 /*yield*/, this.request('endSession', query, true, undefined, options)]; | ||
case 2: | ||
@@ -224,3 +223,3 @@ response = _a.sent(); | ||
} | ||
return [2 /*return*/]; | ||
return [2 /*return*/, response]; | ||
} | ||
@@ -250,3 +249,3 @@ }); | ||
}; | ||
return [4 /*yield*/, this.request('token/revoke', undefined, false, init, options)]; | ||
return [4 /*yield*/, this.request('revoke', undefined, false, init, options)]; | ||
case 2: | ||
@@ -257,3 +256,3 @@ response = _a.sent(); | ||
} | ||
return [2 /*return*/]; | ||
return [2 /*return*/, response]; | ||
} | ||
@@ -263,3 +262,3 @@ }); | ||
}; | ||
OAuth2Client.request = function (path, query, includeToken, init, options) { | ||
OAuth2Client.request = function (endpoint, query, includeToken, init, options) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
@@ -271,3 +270,3 @@ var serverConfig, url, accessToken; | ||
serverConfig = index_1.default.get(options).serverConfig; | ||
url = this.getUrl(path, query, options); | ||
url = this.getUrl(endpoint, query, options); | ||
init = init || {}; | ||
@@ -318,6 +317,6 @@ if (!includeToken) return [3 /*break*/, 2]; | ||
}; | ||
OAuth2Client.getUrl = function (path, query, options) { | ||
OAuth2Client.getUrl = function (endpoint, query, options) { | ||
var _a = index_1.default.get(options), realmPath = _a.realmPath, serverConfig = _a.serverConfig; | ||
var realmUrlPath = realm_1.getRealmUrlPath(realmPath); | ||
var url = url_1.resolve(serverConfig.baseUrl, "oauth2/" + realmUrlPath + "/" + path); | ||
var path = url_1.getEndpointPath(endpoint, realmPath, serverConfig.paths); | ||
var url = url_1.resolve(serverConfig.baseUrl, path); | ||
if (query) { | ||
@@ -324,0 +323,0 @@ url += "?" + url_1.stringify(query); |
@@ -9,4 +9,4 @@ import { ConfigOptions } from '../config/index'; | ||
*/ | ||
static logout(options?: ConfigOptions): Promise<void>; | ||
static logout(options?: ConfigOptions): Promise<Response>; | ||
} | ||
export default SessionManager; |
@@ -45,3 +45,2 @@ "use strict"; | ||
var http_1 = require("../util/http"); | ||
var realm_1 = require("../util/realm"); | ||
var timeout_1 = require("../util/timeout"); | ||
@@ -60,3 +59,3 @@ var url_1 = require("../util/url"); | ||
return __awaiter(this, void 0, void 0, function () { | ||
var _a, realmPath, serverConfig, init, realmUrlPath, url, response; | ||
var _a, realmPath, serverConfig, init, path, url, response; | ||
return __generator(this, function (_b) { | ||
@@ -74,4 +73,4 @@ switch (_b.label) { | ||
}; | ||
realmUrlPath = realm_1.getRealmUrlPath(realmPath); | ||
url = url_1.resolve(serverConfig.baseUrl, "json/" + realmUrlPath + "/sessions/?_action=logout"); | ||
path = url_1.getEndpointPath('sessions', realmPath, serverConfig.paths) + "?_action=logout"; | ||
url = url_1.resolve(serverConfig.baseUrl, path); | ||
return [4 /*yield*/, timeout_1.withTimeout(fetch(url, init), serverConfig.timeout)]; | ||
@@ -83,3 +82,3 @@ case 1: | ||
} | ||
return [2 /*return*/]; | ||
return [2 /*return*/, response]; | ||
} | ||
@@ -86,0 +85,0 @@ }); |
@@ -18,5 +18,4 @@ import { Tokens } from '../shared/interfaces'; | ||
static remove(): Promise<void>; | ||
private static getClientId; | ||
private static getResult; | ||
private static getClientConfig; | ||
} | ||
export default TokenStorage; |
@@ -43,3 +43,4 @@ "use strict"; | ||
var index_1 = __importDefault(require("../config/index")); | ||
var constants_1 = require("./constants"); | ||
var indexed_db_1 = __importDefault(require("./indexed-db")); | ||
var local_storage_1 = __importDefault(require("./local-storage")); | ||
/** | ||
@@ -56,31 +57,25 @@ * Provides access to the token storage API. | ||
return __awaiter(this, void 0, void 0, function () { | ||
var clientId; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
clientId = this.getClientId(); | ||
return [2 /*return*/, new Promise(function (resolve, reject) { | ||
var onError = function () { return reject(); }; | ||
var openReq = window.indexedDB.open(constants_1.DB_NAME); | ||
openReq.onsuccess = function () { | ||
if (!openReq.result.objectStoreNames.contains(clientId)) { | ||
openReq.result.close(); | ||
return resolve(undefined); | ||
} | ||
var getReq = openReq.result | ||
.transaction(clientId, 'readonly') | ||
.objectStore(clientId) | ||
.get(constants_1.TOKEN_KEY); | ||
getReq.onsuccess = function (event) { | ||
var tokens = _this.getResult(event); | ||
openReq.result.close(); | ||
resolve(tokens); | ||
}; | ||
getReq.onerror = onError; | ||
}; | ||
openReq.onupgradeneeded = function () { | ||
openReq.result.close(); | ||
resolve(undefined); | ||
}; | ||
openReq.onerror = onError; | ||
})]; | ||
var _a, clientId, tokenStore; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_a = this.getClientConfig(), clientId = _a.clientId, tokenStore = _a.tokenStore; | ||
if (!(tokenStore === 'localStorage')) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, local_storage_1.default.get(clientId)]; | ||
case 1: return [2 /*return*/, _b.sent()]; | ||
case 2: | ||
if (!(tokenStore === 'indexedDB')) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, indexed_db_1.default.get(clientId)]; | ||
case 3: return [2 /*return*/, _b.sent()]; | ||
case 4: | ||
if (!(tokenStore && tokenStore.get)) return [3 /*break*/, 6]; | ||
return [4 /*yield*/, tokenStore.get(clientId)]; | ||
case 5: | ||
// User supplied token store | ||
return [2 /*return*/, _b.sent()]; | ||
case 6: return [4 /*yield*/, indexed_db_1.default.get(clientId)]; | ||
case 7: | ||
// if tokenStore is undefined, default to previous behavior | ||
return [2 /*return*/, _b.sent()]; | ||
} | ||
}); | ||
@@ -94,36 +89,25 @@ }); | ||
return __awaiter(this, void 0, void 0, function () { | ||
var clientId; | ||
return __generator(this, function (_a) { | ||
clientId = this.getClientId(); | ||
return [2 /*return*/, new Promise(function (resolve, reject) { | ||
var openReq = window.indexedDB.open(constants_1.DB_NAME); | ||
var onSetSuccess = function () { | ||
openReq.result.close(); | ||
resolve(); | ||
}; | ||
var onError = function () { return reject(); }; | ||
var onUpgradeNeeded = function () { | ||
openReq.result.createObjectStore(clientId); | ||
}; | ||
var onOpenSuccess = function () { | ||
if (!openReq.result.objectStoreNames.contains(clientId)) { | ||
var version = openReq.result.version + 1; | ||
openReq.result.close(); | ||
openReq = window.indexedDB.open(constants_1.DB_NAME, version); | ||
openReq.onupgradeneeded = onUpgradeNeeded; | ||
openReq.onsuccess = onOpenSuccess; | ||
openReq.onerror = onError; | ||
return; | ||
} | ||
var txnReq = openReq.result.transaction(clientId, 'readwrite'); | ||
txnReq.onerror = onError; | ||
var objectStore = txnReq.objectStore(clientId); | ||
var putReq = objectStore.put(tokens, constants_1.TOKEN_KEY); | ||
putReq.onsuccess = onSetSuccess; | ||
putReq.onerror = onError; | ||
}; | ||
openReq.onupgradeneeded = onUpgradeNeeded; | ||
openReq.onsuccess = onOpenSuccess; | ||
openReq.onerror = onError; | ||
})]; | ||
var _a, clientId, tokenStore; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_a = this.getClientConfig(), clientId = _a.clientId, tokenStore = _a.tokenStore; | ||
if (!(tokenStore === 'localStorage')) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, local_storage_1.default.set(clientId, tokens)]; | ||
case 1: return [2 /*return*/, _b.sent()]; | ||
case 2: | ||
if (!(tokenStore === 'indexedDB')) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, indexed_db_1.default.set(clientId, tokens)]; | ||
case 3: return [2 /*return*/, _b.sent()]; | ||
case 4: | ||
if (!(tokenStore && tokenStore.set)) return [3 /*break*/, 6]; | ||
return [4 /*yield*/, tokenStore.set(clientId, tokens)]; | ||
case 5: | ||
// User supplied token store | ||
return [2 /*return*/, _b.sent()]; | ||
case 6: return [4 /*yield*/, indexed_db_1.default.set(clientId, tokens)]; | ||
case 7: | ||
// if tokenStore is undefined, default to previous behavior | ||
return [2 /*return*/, _b.sent()]; | ||
} | ||
}); | ||
@@ -137,39 +121,35 @@ }); | ||
return __awaiter(this, void 0, void 0, function () { | ||
var clientId; | ||
return __generator(this, function (_a) { | ||
clientId = this.getClientId(); | ||
return [2 /*return*/, new Promise(function (resolve, reject) { | ||
var onError = function () { return reject(); }; | ||
var openReq = window.indexedDB.open(constants_1.DB_NAME); | ||
openReq.onsuccess = function () { | ||
if (!openReq.result.objectStoreNames.contains(clientId)) { | ||
return resolve(); | ||
} | ||
var removeReq = openReq.result | ||
.transaction(clientId, 'readwrite') | ||
.objectStore(clientId) | ||
.delete(constants_1.TOKEN_KEY); | ||
removeReq.onsuccess = function () { | ||
resolve(); | ||
}; | ||
removeReq.onerror = onError; | ||
}; | ||
openReq.onerror = onError; | ||
})]; | ||
var _a, clientId, tokenStore; | ||
return __generator(this, function (_b) { | ||
switch (_b.label) { | ||
case 0: | ||
_a = this.getClientConfig(), clientId = _a.clientId, tokenStore = _a.tokenStore; | ||
if (!(tokenStore === 'localStorage')) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, local_storage_1.default.remove(clientId)]; | ||
case 1: return [2 /*return*/, _b.sent()]; | ||
case 2: | ||
if (!(tokenStore === 'indexedDB')) return [3 /*break*/, 4]; | ||
return [4 /*yield*/, indexed_db_1.default.remove(clientId)]; | ||
case 3: return [2 /*return*/, _b.sent()]; | ||
case 4: | ||
if (!(tokenStore && tokenStore.remove)) return [3 /*break*/, 6]; | ||
return [4 /*yield*/, tokenStore.remove(clientId)]; | ||
case 5: | ||
// User supplied token store | ||
return [2 /*return*/, _b.sent()]; | ||
case 6: return [4 /*yield*/, indexed_db_1.default.remove(clientId)]; | ||
case 7: | ||
// if tokenStore is undefined, default to previous behavior | ||
return [2 /*return*/, _b.sent()]; | ||
} | ||
}); | ||
}); | ||
}; | ||
TokenStorage.getClientId = function () { | ||
var clientId = index_1.default.get().clientId; | ||
TokenStorage.getClientConfig = function () { | ||
var _a = index_1.default.get(), clientId = _a.clientId, tokenStore = _a.tokenStore; | ||
if (!clientId) { | ||
throw new Error('clientId is required to manage token storage'); | ||
} | ||
return clientId; | ||
return { clientId: clientId, tokenStore: tokenStore }; | ||
}; | ||
TokenStorage.getResult = function (event) { | ||
if (!event || !event.target) { | ||
throw new Error('Missing storage event target'); | ||
} | ||
return event.target.result; | ||
}; | ||
return TokenStorage; | ||
@@ -176,0 +156,0 @@ }()); |
@@ -0,1 +1,2 @@ | ||
import { ConfigurablePaths, CustomPathConfig } from '../config/interfaces'; | ||
import { StringDict } from '../shared/interfaces'; | ||
@@ -7,5 +8,6 @@ /** | ||
declare function getBaseUrl(url: URL): string; | ||
declare function getEndpointPath(endpoint: ConfigurablePaths, realmPath?: string, customPaths?: CustomPathConfig): string; | ||
declare function resolve(baseUrl: string, path: string): string; | ||
declare function parseQuery(fullUrl: string): StringDict<string>; | ||
declare function stringify(data: StringDict<string | undefined>): string; | ||
export { getBaseUrl, parseQuery, resolve, stringify }; | ||
export { getBaseUrl, getEndpointPath, parseQuery, resolve, stringify }; |
@@ -10,2 +10,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var realm_1 = require("../util/realm"); | ||
/** | ||
@@ -23,2 +24,25 @@ * Returns the base URL including protocol, hostname and any non-standard port. | ||
exports.getBaseUrl = getBaseUrl; | ||
function getEndpointPath(endpoint, realmPath, customPaths) { | ||
var realmUrlPath = realm_1.getRealmUrlPath(realmPath); | ||
var defaultPaths = { | ||
authenticate: "json/" + realmUrlPath + "/authenticate", | ||
authorize: "oauth2/" + realmUrlPath + "/authorize", | ||
accessToken: "oauth2/" + realmUrlPath + "/access_token", | ||
endSession: "oauth2/" + realmUrlPath + "/connect/endSession", | ||
userInfo: "oauth2/" + realmUrlPath + "/userinfo", | ||
revoke: "oauth2/" + realmUrlPath + "/token/revoke", | ||
sessions: "json/" + realmUrlPath + "/sessions/", | ||
}; | ||
if (customPaths && customPaths[endpoint]) { | ||
// TypeScript is not correctly reading the condition above | ||
// It's thinking that customPaths[endpoint] may result in undefined | ||
// eslint-disable-next-line | ||
// @ts-ignore | ||
return customPaths[endpoint]; | ||
} | ||
else { | ||
return defaultPaths[endpoint]; | ||
} | ||
} | ||
exports.getEndpointPath = getEndpointPath; | ||
function resolve(baseUrl, path) { | ||
@@ -25,0 +49,0 @@ var url = new URL(baseUrl); |
{ | ||
"name": "@forgerock/javascript-sdk", | ||
"version": "1.0.5", | ||
"version": "2.0.0-alpha1", | ||
"description": "ForgeRock JavaScript SDK", | ||
@@ -16,3 +16,2 @@ "main": "./lib/", | ||
"build": "npm run clean && tsc && tsc -m es6 --outDir lib-esm && webpack --env.DEV=no", | ||
"build:test": "webpack --config tests/e2e/server/webpack.config.js", | ||
"clean": "shx rm -rf bundles lib lib-esm coverage", | ||
@@ -28,13 +27,13 @@ "clean:all": "npm run clean && shx rm -rf node_modules && git clean -fX --exclude='!.env'", | ||
"lint": "eslint --ignore-path .gitignore '**/*.ts' --fix", | ||
"server:iframe": "http-server tests/e2e/iframe -c1 -p 3000 --ssl --cert certs/samples.crt --key certs/samples.key", | ||
"server:samples": "http-server samples -c1 -p 3000 --ssl --cert certs/samples.crt --key certs/samples.key", | ||
"server:e2e": "http-server tests/e2e/test-site -c1 -p 3002 --ssl --cert certs/samples.crt --key certs/samples.key", | ||
"server:e2e:live": "http-server tests/e2e/test-site -c1 -p 3003 -e htm --ssl --cert certs/samples.crt --key certs/samples.key", | ||
"start": "webpack --env.DEV=yes", | ||
"test": "jest --config=./tests-plus.config.js", | ||
"test:e2e": "jest tests/e2e --config=./tests-plus.config.js", | ||
"test:e2e:live": "OAUTH_SERVER=live jest tests/e2e --config=./tests-plus.config.js", | ||
"test:integration": "jest tests/integration --config=./tests-basic.config.js", | ||
"test:unit": "jest src/** --config=./tests-basic.config.js", | ||
"test:coverage": "jest --config=./tests-plus.config.js --coverage=true" | ||
"start:e2e": "http-server tests/e2e/app -c1 -p 3002 --ssl --cert certs/samples.crt --key certs/samples.key", | ||
"start:e2e:insecure": "http-server tests/e2e/app -c1 -p 3002", | ||
"start:server": "APP_PORT=3002 SERVER_PORT=3001 node tests/e2e/server/index.mjs", | ||
"start:samples": "http-server samples -c1 -p 3000 --ssl --cert certs/samples.crt --key certs/samples.key", | ||
"test": "npm run test:unit && npm run test:integration && npm run test:e2e", | ||
"test:coverage": "jest --config=./tests/basic.config.js --coverage=true", | ||
"test:e2e": "jest --testMatch='<rootDir>/tests/e2e/**/*.test.ts' --config=./tests/e2e.config.js", | ||
"test:e2e:live": "OAUTH_SERVER=live jest --testMatch='<rootDir>/tests/e2e/**/*.test.ts' --config=./tests/e2e.config.js", | ||
"test:integration": "jest --testMatch='<rootDir>/tests/integration/**/*.test.ts' --config=./tests/basic.config.js", | ||
"test:unit": "jest --testMatch='<rootDir>/src/**/*.test.ts' --config=./tests/basic.config.js", | ||
"watch": "webpack -w --env.DEV=yes" | ||
}, | ||
@@ -60,3 +59,2 @@ "husky": { | ||
"@types/jest": "^24.0.15", | ||
"@types/puppeteer": "^1.20.1", | ||
"@typescript-eslint/eslint-plugin": "^2.4.0", | ||
@@ -66,3 +64,5 @@ "@typescript-eslint/parser": "^2.4.0", | ||
"awesome-typescript-loader": "^5.2.1", | ||
"cookie-parser": "^1.4.4", | ||
"copyfiles": "^2.1.1", | ||
"cors": "^2.8.5", | ||
"cpy-cli": "^2.0.0", | ||
@@ -73,12 +73,13 @@ "dotenv": "^8.0.0", | ||
"eslint-plugin-prettier": "^3.1.1", | ||
"express": "^4.17.1", | ||
"fake-indexeddb": "^2.1.1", | ||
"http-server": "^0.11.1", | ||
"http-server": "^0.12.1", | ||
"husky": "^3.0.9", | ||
"jest": "^24.8.0", | ||
"jest-puppeteer": "^4.3.0", | ||
"miragejs": "^0.1.32", | ||
"jest-canvas-mock": "^2.2.0", | ||
"jest-dev-server": "^4.4.0", | ||
"playwright": "^0.13.0", | ||
"prettier": "^1.18.2", | ||
"puppeteer": "^1.20.0", | ||
"ramda": "^0.26.1", | ||
"shx": "^0.3.2", | ||
"superagent": "^5.2.2", | ||
"ts-jest": "^24.1.0", | ||
@@ -88,7 +89,8 @@ "tsconfig-paths-webpack-plugin": "^3.2.0", | ||
"typescript": "^3.5.2", | ||
"uglifyjs-webpack-plugin": "^2.2.0", | ||
"watch": "^1.0.2", | ||
"webpack": "^4.41.2", | ||
"webpack-cli": "^3.3.10" | ||
"webpack": "^4.42.1", | ||
"webpack-cli": "^3.3.11" | ||
}, | ||
"dependencies": {} | ||
} |
@@ -133,9 +133,9 @@ # ForgeRock JavaScript SDK | ||
# (Pick any passphrase and use it whenever prompted) | ||
npm run make_certs | ||
npm run certs:make | ||
# Build the SDK and watch for changes | ||
npm start | ||
npm run watch | ||
# Start the sample webserver | ||
npm run server:samples | ||
npm run start:samples | ||
@@ -157,3 +157,3 @@ # Follow the next section to trust certificate | ||
# MacOS | ||
sudo npm run trust_certs | ||
sudo npm run certs:trust | ||
``` | ||
@@ -176,4 +176,8 @@ | ||
Some tests require an OpenAM instance with a public OAuth client configured. Specify your environment details in an `.env` file: | ||
### E2E Test Requirements | ||
Node v13.10 or higher is required to run the mock E2E server application. | ||
Testing against a live environment requires an OpenAM instance with a public OAuth client configured. Specify your environment details in an `.env` file: | ||
| Variable | Purpose | | ||
@@ -195,18 +199,8 @@ | ----------- | ------------------------------------------------------ | | ||
**Manually view test site** | ||
## Version History | ||
To replicate the e2e environment for troubleshooting, run: | ||
[Our version history can be viewed by visiting our CHANGELOG.md](https://github.com/ForgeRock/forgerock-javascript-sdk/blob/master/CHANGELOG.md). | ||
```bash | ||
npm run server:e2e | ||
``` | ||
Now browse to the following URL, replacing relevant tokens with values from your `.env` file: | ||
``` | ||
{BASE_URL}?amUrl={AM_URL}&clientId={CLIENT_ID}&scope={SCOPE}&un={USERNAME}&pw={PASSWORD} | ||
``` | ||
## License | ||
[MIT](http://opensource.org/licenses/MIT) |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
795392
461
13106
33
1
203
13