From 3b04bea7d1274b0403b4e6c1daceb95c32d54a6c Mon Sep 17 00:00:00 2001 From: Jared Perreault Date: Tue, 15 Mar 2022 13:03:53 -0400 Subject: [PATCH 1/3] chore: added missing type --- lib/idx/types/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/idx/types/index.ts b/lib/idx/types/index.ts index cf2d7bb03..dde771b56 100644 --- a/lib/idx/types/index.ts +++ b/lib/idx/types/index.ts @@ -61,6 +61,7 @@ export enum AuthenticatorKey { export type Input = { name: string; + key?: string; type?: string; label?: string; value?: string | {form: IdxForm}; From 7aaa9063af04dc56c8a6fd64f94dd6f08c898521 Mon Sep 17 00:00:00 2001 From: Jared Perreault Date: Wed, 16 Mar 2022 10:51:12 -0400 Subject: [PATCH 2/3] refactored idx to class-based client --- lib/OktaAuth.ts | 71 +---------------- lib/idx/index.ts | 196 +++++++++++++++++++++++++++++++++++++++++++---- lib/types/api.ts | 61 +-------------- 3 files changed, 188 insertions(+), 140 deletions(-) diff --git a/lib/OktaAuth.ts b/lib/OktaAuth.ts index c6baac62f..1b603c35e 100644 --- a/lib/OktaAuth.ts +++ b/lib/OktaAuth.ts @@ -84,8 +84,6 @@ import { verifyToken, prepareTokenParams, exchangeCodeForTokens, - isInteractionRequiredError, - isInteractionRequired, } from './oidc'; import { isBrowser } from './features'; import * as features from './features'; @@ -106,35 +104,10 @@ import { AuthStateManager } from './AuthStateManager'; import { StorageManager } from './StorageManager'; import TransactionManager from './TransactionManager'; import { buildOptions } from './options'; -import { - interact, - introspect, - authenticate, - cancel, - poll, - proceed, - register, - recoverPassword, - unlockAccount, - startTransaction, - handleInteractionCodeRedirect, - canProceed, - handleEmailVerifyCallback, - isEmailVerifyCallback, - parseEmailVerifyCallback, - isEmailVerifyCallbackError -} from './idx'; +import { IdxClient } from './idx'; import { createGlobalRequestInterceptor, setGlobalRequestInterceptor } from './idx/headers'; import { OktaUserAgent } from './OktaUserAgent'; import { parseOAuthResponseFromUrl } from './oidc/parseFromUrl'; -import { - getSavedTransactionMeta, - createTransactionMeta, - getTransactionMeta, - saveTransactionMeta, - clearTransactionMeta, - isTransactionMetaValid -} from './idx/transactionMeta'; // @ts-ignore // Do not use this type in code, so it won't be emitted in the declaration output import Emitter from 'tiny-emitter'; @@ -294,47 +267,7 @@ class OktaAuth implements OktaAuthInterface, SigninAPI, SignoutAPI { }); // IDX - const boundStartTransaction = startTransaction.bind(null, this); - this.idx = { - interact: interact.bind(null, this), - introspect: introspect.bind(null, this), - authenticate: authenticate.bind(null, this), - register: register.bind(null, this), - start: boundStartTransaction, - startTransaction: boundStartTransaction, // Use `start` instead. `startTransaction` will be removed in 7.0 - poll: poll.bind(null, this), - proceed: proceed.bind(null, this), - cancel: cancel.bind(null, this), - recoverPassword: recoverPassword.bind(null, this), - - // oauth redirect callback - handleInteractionCodeRedirect: handleInteractionCodeRedirect.bind(null, this), - - // interaction required callback - isInteractionRequired: isInteractionRequired.bind(null, this), - isInteractionRequiredError, - - // email verify callback - handleEmailVerifyCallback: handleEmailVerifyCallback.bind(null, this), - isEmailVerifyCallback, - parseEmailVerifyCallback, - isEmailVerifyCallbackError, - - getSavedTransactionMeta: getSavedTransactionMeta.bind(null, this), - createTransactionMeta: createTransactionMeta.bind(null, this), - getTransactionMeta: getTransactionMeta.bind(null, this), - saveTransactionMeta: saveTransactionMeta.bind(null, this), - clearTransactionMeta: clearTransactionMeta.bind(null, this), - isTransactionMetaValid, - setFlow: (flow: FlowIdentifier) => { - this.options.flow = flow; - }, - getFlow: (): FlowIdentifier | undefined => { - return this.options.flow; - }, - canProceed: canProceed.bind(null, this), - unlockAccount: unlockAccount.bind(null, this), - }; + this.idx = new IdxClient(this); setGlobalRequestInterceptor(createGlobalRequestInterceptor(this)); // to pass custom headers to IDX endpoints diff --git a/lib/idx/index.ts b/lib/idx/index.ts index ba5e855a5..7bd52b0b3 100644 --- a/lib/idx/index.ts +++ b/lib/idx/index.ts @@ -11,21 +11,191 @@ */ -export { authenticate } from './authenticate'; -export { cancel } from './cancel'; -export { +import { OktaAuth } from '..'; +import { httpRequest } from '../http'; +import { authenticate } from './authenticate'; +import { cancel } from './cancel'; +import { handleEmailVerifyCallback, isEmailVerifyCallback, parseEmailVerifyCallback, isEmailVerifyCallbackError, } from './emailVerify'; -export { interact } from './interact'; -export { introspect } from './introspect'; -export { poll } from './poll'; -export { proceed, canProceed } from './proceed'; -export { register } from './register'; -export { recoverPassword } from './recoverPassword'; -export { handleInteractionCodeRedirect } from './handleInteractionCodeRedirect'; -export { startTransaction } from './startTransaction'; -export { unlockAccount } from './unlockAccount'; -export * from './transactionMeta'; +import { interact, InteractOptions, InteractResponse } from './interact'; +import { introspect, IntrospectOptions } from './introspect'; +import { poll } from './poll'; +import { proceed, canProceed } from './proceed'; +import { register } from './register'; +import { recoverPassword } from './recoverPassword'; +import { handleInteractionCodeRedirect } from './handleInteractionCodeRedirect'; +import { startTransaction } from './startTransaction'; +import { unlockAccount } from './unlockAccount'; +import { isInteractionRequired, isInteractionRequiredError } from '../oidc'; +import { + getSavedTransactionMeta, + createTransactionMeta, + getTransactionMeta, + saveTransactionMeta, + clearTransactionMeta, + isTransactionMetaValid +} from './transactionMeta'; +import { + AuthenticationOptions, + RegistrationOptions as IdxRegistrationOptions, + PasswordRecoveryOptions, + AccountUnlockOptions, + ProceedOptions, + CancelOptions, + IdxOptions, + IdxTransaction, + IdxTransactionMeta, + EmailVerifyCallbackResponse, + FlowIdentifier, + IdxPollOptions +} from './types'; +import { IdxResponse } from './types/idx-js'; +import { TransactionMetaOptions } from '../types' + +export interface IdxClientInterface { + // lowest level api + interact: (options?: InteractOptions) => Promise; + introspect: (options?: IntrospectOptions) => Promise; + + // flow entrypoints + authenticate: (options?: AuthenticationOptions) => Promise; + register: (options?: IdxRegistrationOptions) => Promise; + recoverPassword: (options?: PasswordRecoveryOptions) => Promise; + unlockAccount: (options?: AccountUnlockOptions) => Promise; + poll: (options?: IdxPollOptions) => Promise; + + // flow control + start: (options?: IdxOptions) => Promise; + canProceed(options?: { state?: string }): boolean; + proceed: (options?: ProceedOptions) => Promise; + cancel: (options?: CancelOptions) => Promise; + getFlow(): FlowIdentifier | undefined; + setFlow(flow: FlowIdentifier): void; + + // call `start` instead of `startTransaction`. `startTransaction` will be removed in next major version (7.0) + startTransaction: (options?: IdxOptions) => Promise; + + // redirect callbacks + isInteractionRequired: (hashOrSearch?: string) => boolean; + isInteractionRequiredError: (error: Error) => boolean; + handleInteractionCodeRedirect: (url: string) => Promise; + isEmailVerifyCallback: (search: string) => boolean; + parseEmailVerifyCallback: (search: string) => EmailVerifyCallbackResponse; + handleEmailVerifyCallback: (search: string) => Promise; + isEmailVerifyCallbackError: (error: Error) => boolean; + + // transaction meta + getSavedTransactionMeta: (options?: TransactionMetaOptions) => IdxTransactionMeta | undefined; + createTransactionMeta: (options?: TransactionMetaOptions) => Promise; + getTransactionMeta: (options?: TransactionMetaOptions) => Promise; + saveTransactionMeta: (meta: unknown) => void; + clearTransactionMeta: () => void; + isTransactionMetaValid: (meta: unknown) => boolean; +} + +export class IdxClient implements IdxClientInterface { + private sdk: OktaAuth; + private httpClient: Function; + + constructor(sdk: OktaAuth) { + this.sdk = sdk; + this.httpClient = httpRequest.bind(this, this.sdk); + } + + // lowest level api + interact (options?: InteractOptions) { + return interact(this.sdk, options); + } + introspect (options?: IntrospectOptions) { + return introspect(this.sdk, options); + } + + // flow entrypoints + authenticate (options?: AuthenticationOptions) { + return authenticate(this.sdk, options); + } + register (options?: IdxRegistrationOptions) { + return register(this.sdk, options); + } + recoverPassword (options?: PasswordRecoveryOptions) { + return recoverPassword(this.sdk, options); + } + unlockAccount (options?: AccountUnlockOptions) { + return unlockAccount(this.sdk, options); + } + poll (options?: IdxPollOptions) { + return poll(this.sdk, options); + } + + // flow control + start (options?: IdxOptions) { + return startTransaction(this.sdk, options); + } + canProceed(options?: { state?: string }) { + return canProceed(this.sdk, options); + } + proceed (options?: ProceedOptions) { + return proceed(this.sdk, options); + } + cancel (options?: CancelOptions) { + return cancel(this.sdk, options); + } + getFlow () { + return this.sdk.options.flow; + } + setFlow (flow: FlowIdentifier) { + this.sdk.options.flow = flow; + } + + // call `start` instead of `startTransaction`. `startTransaction` will be removed in next major version (7.0) + startTransaction (options?: IdxOptions) { return this.start(options); } + + // redirect callbacks + isInteractionRequired (hashOrSearch?: string) { + return isInteractionRequired(this.sdk, hashOrSearch); + } + isInteractionRequiredError (error: Error) { + return isInteractionRequiredError(error); + } + handleInteractionCodeRedirect (url: string) { + return handleInteractionCodeRedirect(this.sdk, url); + } + + // email verify callbacks + isEmailVerifyCallback (search: string) { + return isEmailVerifyCallback(search); + } + parseEmailVerifyCallback (search: string) { + return parseEmailVerifyCallback(search); + } + handleEmailVerifyCallback (search: string) { + return handleEmailVerifyCallback(this.sdk, search); + } + isEmailVerifyCallbackError (error: Error) { + return isEmailVerifyCallbackError(error); + } + + // transaction meta + getSavedTransactionMeta (options?: TransactionMetaOptions) { + return getSavedTransactionMeta(this.sdk, options); + } + createTransactionMeta (options?: TransactionMetaOptions) { + return createTransactionMeta(this.sdk, options); + } + getTransactionMeta (options?: TransactionMetaOptions) { + return getTransactionMeta(this.sdk, options); + } + saveTransactionMeta (meta: unknown) { + return saveTransactionMeta(this.sdk, meta); + } + clearTransactionMeta () { + return clearTransactionMeta(this.sdk); + } + isTransactionMetaValid (meta: unknown) { + return isTransactionMetaValid(meta); + } +} \ No newline at end of file diff --git a/lib/types/api.ts b/lib/types/api.ts index de4f29e65..e2dc54eb7 100644 --- a/lib/types/api.ts +++ b/lib/types/api.ts @@ -22,27 +22,14 @@ import { ServiceManagerInterface } from './Service'; import { OktaUserAgent } from '../OktaUserAgent'; import { AuthenticationOptions, - RegistrationOptions as IdxRegistrationOptions, - PasswordRecoveryOptions, - AccountUnlockOptions, - ProceedOptions, - CancelOptions, - IdxOptions, - IdxTransaction, - IdxTransactionMeta, - EmailVerifyCallbackResponse, IdxAuthenticator, ChallengeData, ActivationData, WebauthnEnrollValues, WebauthnVerificationValues, - FlowIdentifier, - IdxPollOptions } from '../idx/types'; -import { InteractOptions, InteractResponse } from '../idx/interact'; -import { IntrospectOptions } from '../idx/introspect'; -import { IdxResponse } from '../idx/types/idx-js'; -import { TransactionMetaOptions } from './Transaction'; +import { IdxClientInterface } from '../idx'; + export interface OktaAuthInterface { options: OktaAuthOptions; getIssuerOrigin(): string; @@ -54,7 +41,7 @@ export interface OktaAuthInterface { tokenManager: TokenManagerInterface; serviceManager: ServiceManagerInterface; - idx: IdxAPI; + idx: IdxClientInterface; // Browser only features: FeaturesAPI; @@ -291,45 +278,3 @@ export interface PkceAPI { generateVerifier(prefix: string): string; computeChallenge(str: string): PromiseLike; } - - -export interface IdxAPI { - // lowest level api - interact: (options?: InteractOptions) => Promise; - introspect: (options?: IntrospectOptions) => Promise; - - // flow entrypoints - authenticate: (options?: AuthenticationOptions) => Promise; - register: (options?: IdxRegistrationOptions) => Promise; - recoverPassword: (options?: PasswordRecoveryOptions) => Promise; - unlockAccount: (options?: AccountUnlockOptions) => Promise; - poll: (options?: IdxPollOptions) => Promise; - - // flow control - start: (options?: IdxOptions) => Promise; - canProceed(options?: { state?: string }): boolean; - proceed: (options?: ProceedOptions) => Promise; - cancel: (options?: CancelOptions) => Promise; - getFlow(): FlowIdentifier | undefined; - setFlow(flow: FlowIdentifier): void; - - // call `start` instead of `startTransaction`. `startTransaction` will be removed in next major version (7.0) - startTransaction: (options?: IdxOptions) => Promise; - - // redirect callbacks - isInteractionRequired: (hashOrSearch?: string) => boolean; - isInteractionRequiredError: (error: Error) => boolean; - handleInteractionCodeRedirect: (url: string) => Promise; - isEmailVerifyCallback: (search: string) => boolean; - parseEmailVerifyCallback: (search: string) => EmailVerifyCallbackResponse; - handleEmailVerifyCallback: (search: string) => Promise; - isEmailVerifyCallbackError: (error: Error) => boolean; - - // transaction meta - getSavedTransactionMeta: (options?: TransactionMetaOptions) => IdxTransactionMeta | undefined; - createTransactionMeta: (options?: TransactionMetaOptions) => Promise; - getTransactionMeta: (options?: TransactionMetaOptions) => Promise; - saveTransactionMeta: (meta: unknown) => void; - clearTransactionMeta: () => void; - isTransactionMetaValid: (meta: unknown) => boolean; -} From 78524aa2ed5828e1afffb4f86c875787ada044d2 Mon Sep 17 00:00:00 2001 From: Jared Perreault Date: Wed, 16 Mar 2022 11:43:44 -0400 Subject: [PATCH 3/3] fixes unit tests --- lib/OktaAuth.ts | 1 - lib/idx/index.ts | 3 +++ lib/types/api.ts | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/OktaAuth.ts b/lib/OktaAuth.ts index 1b603c35e..3e524c996 100644 --- a/lib/OktaAuth.ts +++ b/lib/OktaAuth.ts @@ -45,7 +45,6 @@ import { IdxAPI, SignoutRedirectUrlOptions, HttpAPI, - FlowIdentifier, GetWithRedirectAPI, ParseFromUrlInterface, GetWithRedirectFunction, diff --git a/lib/idx/index.ts b/lib/idx/index.ts index 7bd52b0b3..c1770655d 100644 --- a/lib/idx/index.ts +++ b/lib/idx/index.ts @@ -56,6 +56,9 @@ import { import { IdxResponse } from './types/idx-js'; import { TransactionMetaOptions } from '../types' +export * from './transactionMeta'; +export { poll } from './poll'; + export interface IdxClientInterface { // lowest level api interact: (options?: InteractOptions) => Promise; diff --git a/lib/types/api.ts b/lib/types/api.ts index e2dc54eb7..73300107e 100644 --- a/lib/types/api.ts +++ b/lib/types/api.ts @@ -278,3 +278,6 @@ export interface PkceAPI { generateVerifier(prefix: string): string; computeChallenge(str: string): PromiseLike; } + +export interface IdxAPI extends IdxClientInterface { +};