@oneblink/apps-react 11.0.0-beta.10 → 11.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,8 +2,8 @@ import { MiscTypes } from '@oneblink/types';
2
2
  import { getMfaSettings } from './services/cognito';
3
3
  export { getMfaSettings };
4
4
  export { updateUserPhoneNumber, removeUserPhoneNumber, verifyUserPhoneNumber, disableMfaMethod, setPreferredMfaMethod, setupMfaAuthenticatorApp, setupSmsMfa, generateMfaAuthenticatorAppQrCodeUrl, DEFAULT_MFA_SETTINGS, } from './services/cognito';
5
- export type { MfaMethod, MfaSettings } from './services/cognito';
6
- export { isMfaRequired, mfaRequirementToSelectedMethods, mfaSelectedMethodsToMfaRequirement, formatMfaRequirementLabel, formatMfaRequirementMethodLabel, userMeetsMfaRequirement, formatMfaSetupRequiredMessage, formatMfaMethodNotAcceptedMessage, } from '../utils/mfa-requirement';
5
+ export type { MfaMethod, MfaSettings, LoggedInMfaMethod } from './services/cognito';
6
+ export { isMfaRequired, mfaRequirementToSelectedMethods, mfaSelectedMethodsToMfaRequirement, formatMfaRequirementLabel, userMeetsMfaRequirement, formatMfaSetupRequiredMessage, formatMfaMethodRequirementMessage, isMfaMethodUsedForLogin, } from '../utils/mfa-requirement';
7
7
  export type { MfaRequirementMethod } from '../utils/mfa-requirement';
8
8
  export type MfaRequirementCheckResult = {
9
9
  mfaSettings: Awaited<ReturnType<typeof getMfaSettings>>;
@@ -2,7 +2,7 @@ import { getMfaSettings } from './services/cognito';
2
2
  import { userMeetsMfaRequirement } from '../utils/mfa-requirement';
3
3
  export { getMfaSettings };
4
4
  export { updateUserPhoneNumber, removeUserPhoneNumber, verifyUserPhoneNumber, disableMfaMethod, setPreferredMfaMethod, setupMfaAuthenticatorApp, setupSmsMfa, generateMfaAuthenticatorAppQrCodeUrl, DEFAULT_MFA_SETTINGS, } from './services/cognito';
5
- export { isMfaRequired, mfaRequirementToSelectedMethods, mfaSelectedMethodsToMfaRequirement, formatMfaRequirementLabel, formatMfaRequirementMethodLabel, userMeetsMfaRequirement, formatMfaSetupRequiredMessage, formatMfaMethodNotAcceptedMessage, } from '../utils/mfa-requirement';
5
+ export { isMfaRequired, mfaRequirementToSelectedMethods, mfaSelectedMethodsToMfaRequirement, formatMfaRequirementLabel, userMeetsMfaRequirement, formatMfaSetupRequiredMessage, formatMfaMethodRequirementMessage, isMfaMethodUsedForLogin, } from '../utils/mfa-requirement';
6
6
  /**
7
7
  * Check if the current user meets an MFA requirement.
8
8
  *
@@ -1 +1 @@
1
- {"version":3,"file":"mfa-service.js","sourceRoot":"","sources":["../../src/apps/mfa-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAElE,OAAO,EAAE,cAAc,EAAE,CAAA;AACzB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,WAAW,EACX,oCAAoC,EACpC,oBAAoB,GACrB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EACL,aAAa,EACb,+BAA+B,EAC/B,kCAAkC,EAClC,yBAAyB,EACzB,+BAA+B,EAC/B,uBAAuB,EACvB,6BAA6B,EAC7B,iCAAiC,GAClC,MAAM,0BAA0B,CAAA;AAQjC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,cAAoD;IAEpD,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAA;IAE1C,OAAO;QACL,WAAW;QACX,uBAAuB,EAAE,uBAAuB,CAC9C,cAAc,EACd,WAAW,CACZ;KACF,CAAA;AACH,CAAC","sourcesContent":["import { MiscTypes } from '@oneblink/types'\r\nimport { getMfaSettings } from './services/cognito'\r\nimport { userMeetsMfaRequirement } from '../utils/mfa-requirement'\r\n\r\nexport { getMfaSettings }\r\nexport {\r\n updateUserPhoneNumber,\r\n removeUserPhoneNumber,\r\n verifyUserPhoneNumber,\r\n disableMfaMethod,\r\n setPreferredMfaMethod,\r\n setupMfaAuthenticatorApp,\r\n setupSmsMfa,\r\n generateMfaAuthenticatorAppQrCodeUrl,\r\n DEFAULT_MFA_SETTINGS,\r\n} from './services/cognito'\r\nexport type { MfaMethod, MfaSettings } from './services/cognito'\r\nexport {\r\n isMfaRequired,\r\n mfaRequirementToSelectedMethods,\r\n mfaSelectedMethodsToMfaRequirement,\r\n formatMfaRequirementLabel,\r\n formatMfaRequirementMethodLabel,\r\n userMeetsMfaRequirement,\r\n formatMfaSetupRequiredMessage,\r\n formatMfaMethodNotAcceptedMessage,\r\n} from '../utils/mfa-requirement'\r\nexport type { MfaRequirementMethod } from '../utils/mfa-requirement'\r\n\r\nexport type MfaRequirementCheckResult = {\r\n mfaSettings: Awaited<ReturnType<typeof getMfaSettings>>\r\n userMeetsMfaRequirement: boolean\r\n}\r\n\r\n/**\r\n * Check if the current user meets an MFA requirement.\r\n *\r\n * #### Example\r\n *\r\n * ```js\r\n * const { mfaSettings, userMeetsMfaRequirement } =\r\n * await mfaService.checkIsMfaEnabled('any')\r\n * if (userMeetsMfaRequirement) {\r\n * // User has met the MFA requirement\r\n * } else {\r\n * // Prompt user to set up MFA\r\n * }\r\n * ```\r\n *\r\n * @returns\r\n */\r\nexport async function checkIsMfaEnabled(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n): Promise<MfaRequirementCheckResult> {\r\n const mfaSettings = await getMfaSettings()\r\n\r\n return {\r\n mfaSettings,\r\n userMeetsMfaRequirement: userMeetsMfaRequirement(\r\n mfaRequirement,\r\n mfaSettings,\r\n ),\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"mfa-service.js","sourceRoot":"","sources":["../../src/apps/mfa-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAElE,OAAO,EAAE,cAAc,EAAE,CAAA;AACzB,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACxB,WAAW,EACX,oCAAoC,EACpC,oBAAoB,GACrB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EACL,aAAa,EACb,+BAA+B,EAC/B,kCAAkC,EAClC,yBAAyB,EACzB,uBAAuB,EACvB,6BAA6B,EAC7B,iCAAiC,EACjC,uBAAuB,GACxB,MAAM,0BAA0B,CAAA;AAQjC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,cAAoD;IAEpD,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAA;IAE1C,OAAO;QACL,WAAW;QACX,uBAAuB,EAAE,uBAAuB,CAC9C,cAAc,EACd,WAAW,CACZ;KACF,CAAA;AACH,CAAC","sourcesContent":["import { MiscTypes } from '@oneblink/types'\r\nimport { getMfaSettings } from './services/cognito'\r\nimport { userMeetsMfaRequirement } from '../utils/mfa-requirement'\r\n\r\nexport { getMfaSettings }\r\nexport {\r\n updateUserPhoneNumber,\r\n removeUserPhoneNumber,\r\n verifyUserPhoneNumber,\r\n disableMfaMethod,\r\n setPreferredMfaMethod,\r\n setupMfaAuthenticatorApp,\r\n setupSmsMfa,\r\n generateMfaAuthenticatorAppQrCodeUrl,\r\n DEFAULT_MFA_SETTINGS,\r\n} from './services/cognito'\r\nexport type { MfaMethod, MfaSettings, LoggedInMfaMethod } from './services/cognito'\r\nexport {\r\n isMfaRequired,\r\n mfaRequirementToSelectedMethods,\r\n mfaSelectedMethodsToMfaRequirement,\r\n formatMfaRequirementLabel,\r\n userMeetsMfaRequirement,\r\n formatMfaSetupRequiredMessage,\r\n formatMfaMethodRequirementMessage,\r\n isMfaMethodUsedForLogin,\r\n} from '../utils/mfa-requirement'\r\nexport type { MfaRequirementMethod } from '../utils/mfa-requirement'\r\n\r\nexport type MfaRequirementCheckResult = {\r\n mfaSettings: Awaited<ReturnType<typeof getMfaSettings>>\r\n userMeetsMfaRequirement: boolean\r\n}\r\n\r\n/**\r\n * Check if the current user meets an MFA requirement.\r\n *\r\n * #### Example\r\n *\r\n * ```js\r\n * const { mfaSettings, userMeetsMfaRequirement } =\r\n * await mfaService.checkIsMfaEnabled('any')\r\n * if (userMeetsMfaRequirement) {\r\n * // User has met the MFA requirement\r\n * } else {\r\n * // Prompt user to set up MFA\r\n * }\r\n * ```\r\n *\r\n * @returns\r\n */\r\nexport async function checkIsMfaEnabled(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n): Promise<MfaRequirementCheckResult> {\r\n const mfaSettings = await getMfaSettings()\r\n\r\n return {\r\n mfaSettings,\r\n userMeetsMfaRequirement: userMeetsMfaRequirement(\r\n mfaRequirement,\r\n mfaSettings,\r\n ),\r\n }\r\n}\r\n"]}
@@ -1,6 +1,8 @@
1
1
  import { AuthenticationResultType, CognitoIdentityProviderClient, InitiateAuthResponse } from '@aws-sdk/client-cognito-identity-provider';
2
2
  export type MfaMethod = 'authenticator' | 'sms';
3
+ export type LoggedInMfaMethod = 'SOFTWARE_TOKEN_MFA' | 'SMS_MFA' | 'NO_MFA_ENABLED';
3
4
  export type MfaSettings = {
5
+ loggedInWithMfaMethod: LoggedInMfaMethod;
4
6
  authenticator: {
5
7
  enabled: boolean;
6
8
  preferred: boolean;
@@ -13,6 +15,7 @@ export type MfaSettings = {
13
15
  };
14
16
  };
15
17
  export declare const DEFAULT_MFA_SETTINGS: MfaSettings;
18
+ export declare function resolveLoggedInMfaMethod(idToken: string | undefined): LoggedInMfaMethod;
16
19
  export declare function resolveMfaPreferredFlags({ authenticatorEnabled, smsEnabled, preferredMfaSetting, }: {
17
20
  authenticatorEnabled: boolean;
18
21
  smsEnabled: boolean;
@@ -1,7 +1,9 @@
1
1
  import { AssociateSoftwareTokenCommand, ChangePasswordCommand, CognitoIdentityProviderClient, ConfirmForgotPasswordCommand, DeleteUserAttributesCommand, GetUserCommand, GlobalSignOutCommand, InitiateAuthCommand, RespondToAuthChallengeCommand, SetUserMFAPreferenceCommand, UpdateUserAttributesCommand, VerifySoftwareTokenCommand, VerifyUserAttributeCommand, } from '@aws-sdk/client-cognito-identity-provider';
2
+ import { jwtDecode } from 'jwt-decode';
2
3
  import Sentry from '../Sentry';
3
4
  import { OneBlinkAppsError } from '..';
4
5
  export const DEFAULT_MFA_SETTINGS = {
6
+ loggedInWithMfaMethod: 'NO_MFA_ENABLED',
5
7
  authenticator: { enabled: false, preferred: false },
6
8
  sms: {
7
9
  enabled: false,
@@ -10,6 +12,23 @@ export const DEFAULT_MFA_SETTINGS = {
10
12
  isPhoneNumberVerified: false,
11
13
  },
12
14
  };
15
+ export function resolveLoggedInMfaMethod(idToken) {
16
+ if (idToken) {
17
+ try {
18
+ const payload = jwtDecode(idToken);
19
+ switch (payload.mfa_method) {
20
+ case 'SOFTWARE_TOKEN_MFA':
21
+ case 'SMS_MFA':
22
+ return payload.mfa_method;
23
+ }
24
+ }
25
+ catch (error) {
26
+ console.warn('Error while decoding id token for logged in MFA method', error);
27
+ Sentry.captureException(error);
28
+ }
29
+ }
30
+ return 'NO_MFA_ENABLED';
31
+ }
13
32
  export function resolveMfaPreferredFlags({ authenticatorEnabled, smsEnabled, preferredMfaSetting, }) {
14
33
  const cognitoAuthenticatorPreferred = preferredMfaSetting === 'SOFTWARE_TOKEN_MFA';
15
34
  const cognitoSmsPreferred = preferredMfaSetting === 'SMS_MFA';
@@ -401,7 +420,9 @@ export default class AWSCognitoClient {
401
420
  smsEnabled,
402
421
  preferredMfaSetting,
403
422
  });
423
+ const loggedInWithMfaMethod = resolveLoggedInMfaMethod(this._getIdToken());
404
424
  return {
425
+ loggedInWithMfaMethod,
405
426
  authenticator: {
406
427
  enabled: authenticatorEnabled,
407
428
  preferred: authenticatorPreferred,
@@ -1 +1 @@
1
- {"version":3,"file":"AWSCognitoClient.js","sourceRoot":"","sources":["../../../src/apps/services/AWSCognitoClient.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AssociateSoftwareTokenCommand,\n AuthenticationResultType,\n ChangePasswordCommand,\n CognitoIdentityProviderClient,\n ConfirmForgotPasswordCommand,\n DeleteUserAttributesCommand,\n GetUserCommand,\n GlobalSignOutCommand,\n InitiateAuthCommand,\n InitiateAuthResponse,\n RespondToAuthChallengeCommand,\n SetUserMFAPreferenceCommand,\n UpdateUserAttributesCommand,\n VerifySoftwareTokenCommand,\n VerifyUserAttributeCommand,\n} from '@aws-sdk/client-cognito-identity-provider'\nimport Sentry from '../Sentry'\nimport { OneBlinkAppsError } from '..'\n\nexport type MfaMethod = 'authenticator' | 'sms'\n\nexport type MfaSettings = {\n authenticator: {\n enabled: boolean\n preferred: boolean\n }\n sms: {\n enabled: boolean\n preferred: boolean\n phoneNumber: string | undefined\n isPhoneNumberVerified: boolean\n }\n}\n\nexport const DEFAULT_MFA_SETTINGS: MfaSettings = {\n authenticator: { enabled: false, preferred: false },\n sms: {\n enabled: false,\n preferred: false,\n phoneNumber: undefined,\n isPhoneNumberVerified: false,\n },\n}\n\nexport function resolveMfaPreferredFlags({\n authenticatorEnabled,\n smsEnabled,\n preferredMfaSetting,\n}: {\n authenticatorEnabled: boolean\n smsEnabled: boolean\n preferredMfaSetting: string | undefined\n}): {\n authenticatorPreferred: boolean\n smsPreferred: boolean\n} {\n const cognitoAuthenticatorPreferred =\n preferredMfaSetting === 'SOFTWARE_TOKEN_MFA'\n const cognitoSmsPreferred = preferredMfaSetting === 'SMS_MFA'\n\n if (cognitoAuthenticatorPreferred && authenticatorEnabled) {\n return { authenticatorPreferred: true, smsPreferred: false }\n }\n\n if (cognitoSmsPreferred && smsEnabled) {\n return { authenticatorPreferred: false, smsPreferred: true }\n }\n\n if (authenticatorEnabled && smsEnabled) {\n return { authenticatorPreferred: true, smsPreferred: false }\n }\n\n return {\n authenticatorPreferred: authenticatorEnabled,\n smsPreferred: smsEnabled,\n }\n}\n\nexport type LoginAttemptMfa = {\n method: MfaMethod\n codeCallback: (code: string) => Promise<LoginAttemptResponse>\n resendCodeCallback?: () => Promise<LoginAttemptResponse>\n}\n\nexport type LoginAttemptResponse = {\n resetPasswordCallback?: (newPassword: string) => Promise<LoginAttemptResponse>\n mfa?: LoginAttemptMfa\n}\n\nexport default class AWSCognitoClient {\n clientId: string\n cognitoIdentityProviderClient: CognitoIdentityProviderClient\n loginDomain: string | void\n redirectUri: string | void\n logoutUri: string | void\n listeners: Array<() => unknown>\n\n constructor({\n clientId,\n region,\n loginDomain,\n redirectUri,\n logoutUri,\n }: {\n clientId: string\n region: string\n redirectUri?: string\n logoutUri?: string\n loginDomain?: string\n }) {\n if (!clientId) {\n throw new TypeError('\"clientId\" is required in constructor')\n }\n if (!region) {\n throw new TypeError('\"region\" is required in constructor')\n }\n\n this.listeners = []\n this.redirectUri = redirectUri\n this.logoutUri = logoutUri\n this.loginDomain = loginDomain\n this.clientId = clientId\n this.cognitoIdentityProviderClient = new CognitoIdentityProviderClient({\n region,\n })\n }\n\n // Local Storage Keys\n get EXPIRES_AT() {\n return `COGNITO_${this.clientId}_EXPIRES_AT`\n }\n get ACCESS_TOKEN() {\n return `COGNITO_${this.clientId}_ACCESS_TOKEN`\n }\n get ID_TOKEN() {\n return `COGNITO_${this.clientId}_ID_TOKEN`\n }\n get REFRESH_TOKEN() {\n return `COGNITO_${this.clientId}_REFRESH_TOKEN`\n }\n get STATE() {\n return `COGNITO_${this.clientId}_STATE`\n }\n get PKCE_CODE_VERIFIER() {\n return `COGNITO_${this.clientId}_PKCE_CODE_VERIFIER`\n }\n\n _executeListeners() {\n for (const listener of this.listeners) {\n try {\n listener()\n } catch (error) {\n Sentry.captureException(error)\n // Ignore error from listeners\n console.warn('AWSCognitoClient listener error', error)\n }\n }\n }\n\n _storeAuthenticationResult(authenticationResult: AuthenticationResultType) {\n // Take off 5 seconds to ensure a request does not become unauthenticated mid request\n const expiresAt =\n (authenticationResult.ExpiresIn as number) * 1000 + Date.now() - 5000\n localStorage.setItem(this.EXPIRES_AT, expiresAt.toString())\n localStorage.setItem(\n this.ACCESS_TOKEN,\n authenticationResult.AccessToken as string,\n )\n localStorage.setItem(this.ID_TOKEN, authenticationResult.IdToken as string)\n if (authenticationResult.RefreshToken) {\n localStorage.setItem(\n this.REFRESH_TOKEN,\n authenticationResult.RefreshToken,\n )\n }\n\n this._executeListeners()\n }\n\n _removeAuthenticationResult() {\n localStorage.removeItem(this.EXPIRES_AT)\n localStorage.removeItem(this.ACCESS_TOKEN)\n localStorage.removeItem(this.ID_TOKEN)\n localStorage.removeItem(this.REFRESH_TOKEN)\n\n this._executeListeners()\n }\n\n _getAccessToken(): string | undefined {\n return localStorage.getItem(this.ACCESS_TOKEN) || undefined\n }\n\n _getIdToken(): string | undefined {\n return localStorage.getItem(this.ID_TOKEN) || undefined\n }\n\n _getRefreshToken(): string | undefined {\n return localStorage.getItem(this.REFRESH_TOKEN) || undefined\n }\n\n _isSessionValid(): boolean {\n const expiresAt = localStorage.getItem(this.EXPIRES_AT)\n if (!expiresAt) {\n return false\n }\n return parseInt(expiresAt, 10) > Date.now()\n }\n\n async _refreshSession(): Promise<void> {\n if (this._isSessionValid()) {\n return\n }\n\n const refreshToken = this._getRefreshToken()\n if (!refreshToken) {\n return\n }\n\n try {\n const result = await this.cognitoIdentityProviderClient.send(\n new InitiateAuthCommand({\n AuthFlow: 'REFRESH_TOKEN_AUTH',\n ClientId: this.clientId,\n AuthParameters: {\n REFRESH_TOKEN: refreshToken,\n },\n }),\n )\n if (result.AuthenticationResult) {\n this._storeAuthenticationResult(result.AuthenticationResult)\n }\n } catch (error) {\n console.warn('Error while attempting to refresh session', error)\n this._removeAuthenticationResult()\n throw new OneBlinkAppsError(\n 'Your session has expired. Please login again to continue to use the application.',\n {\n requiresLogin: true,\n originalError: error as Error,\n },\n )\n }\n }\n\n registerListener(listener: () => unknown): () => void {\n this.listeners.push(listener)\n\n return () => {\n const index = this.listeners.indexOf(listener)\n if (index !== -1) {\n this.listeners.splice(index, 1)\n }\n }\n }\n\n async responseToAuthChallenge(\n username: string,\n initiateAuthResponse: InitiateAuthResponse,\n password?: string,\n ): Promise<LoginAttemptResponse> {\n if (initiateAuthResponse.AuthenticationResult) {\n this._storeAuthenticationResult(initiateAuthResponse.AuthenticationResult)\n return {}\n }\n\n const ChallengeName = initiateAuthResponse.ChallengeName\n switch (ChallengeName) {\n case 'NEW_PASSWORD_REQUIRED': {\n return {\n resetPasswordCallback: async (newPassword) => {\n const resetPasswordResult =\n await this.cognitoIdentityProviderClient.send(\n new RespondToAuthChallengeCommand({\n ChallengeName,\n ClientId: this.clientId,\n Session: initiateAuthResponse.Session,\n ChallengeResponses: {\n USERNAME: username,\n NEW_PASSWORD: newPassword,\n },\n }),\n )\n return await this.responseToAuthChallenge(\n username,\n resetPasswordResult,\n newPassword,\n )\n },\n }\n }\n case 'SOFTWARE_TOKEN_MFA': {\n return {\n mfa: {\n method: 'authenticator',\n codeCallback: async (code) => {\n const resetPasswordResult =\n await this.cognitoIdentityProviderClient.send(\n new RespondToAuthChallengeCommand({\n ChallengeName,\n ClientId: this.clientId,\n Session: initiateAuthResponse.Session,\n ChallengeResponses: {\n USERNAME: username,\n SOFTWARE_TOKEN_MFA_CODE: code,\n },\n }),\n )\n return await this.responseToAuthChallenge(\n username,\n resetPasswordResult,\n password,\n )\n },\n resendCodeCallback: undefined,\n },\n }\n }\n case 'EMAIL_OTP': {\n throw new Error('Email OTP is not supported')\n }\n case 'SMS_MFA': {\n if (!initiateAuthResponse.Session) {\n throw new Error(\n 'An unexpected error occurred while attempting to process your login. Please try again or contact support if the problem persists.',\n )\n }\n\n return {\n mfa: {\n method: 'sms',\n codeCallback: async (code) => {\n const smsChallengeResult =\n await this.cognitoIdentityProviderClient.send(\n new RespondToAuthChallengeCommand({\n ChallengeName,\n ClientId: this.clientId,\n Session: initiateAuthResponse.Session,\n ChallengeResponses: {\n USERNAME: username,\n SMS_MFA_CODE: code,\n },\n }),\n )\n return await this.responseToAuthChallenge(\n username,\n smsChallengeResult,\n password,\n )\n },\n resendCodeCallback: async () => {\n if (!password) {\n throw new Error(\n 'Unable to resend the SMS verification code. Please try signing in again.',\n )\n }\n\n const loginAttemptResponse = await this.loginUsernamePassword(\n username,\n password,\n )\n\n if (loginAttemptResponse.mfa?.method !== 'sms') {\n throw new Error(\n 'Unable to resend the SMS verification code. Please try signing in again.',\n )\n }\n\n return loginAttemptResponse\n },\n },\n }\n }\n }\n\n console.warn(\n '\"CognitoIdentityServiceProvider.InitiateAuthResponse\" challenge has not been catered.',\n initiateAuthResponse,\n )\n throw new Error(\n 'An unexpected error occurred while attempting to process your login. Please try again or contact support if the problem persists.',\n )\n }\n\n async loginUsernamePassword(\n username: string,\n password: string,\n ): Promise<LoginAttemptResponse> {\n const loginResult = await this.cognitoIdentityProviderClient.send(\n new InitiateAuthCommand({\n AuthFlow: 'USER_PASSWORD_AUTH',\n ClientId: this.clientId,\n AuthParameters: {\n USERNAME: username,\n PASSWORD: password,\n },\n }),\n )\n\n return await this.responseToAuthChallenge(username, loginResult, password)\n }\n\n async loginHostedUI(identityProviderName?: string): Promise<void> {\n const loginDomain = this.loginDomain\n const redirectUri = this.redirectUri\n if (!loginDomain || !redirectUri) {\n throw new TypeError(\n '\"loginDomain\" or \"redirectUri\" was not passed to constructor. Both are required before attempting to login.',\n )\n }\n\n // Create and store a random \"state\" value\n const state = generateRandomString()\n localStorage.setItem(this.STATE, state)\n\n // Create and store a new PKCE code_verifier (the plaintext random secret)\n const codeVerifier = generateRandomString()\n localStorage.setItem(this.PKCE_CODE_VERIFIER, codeVerifier)\n\n // Hash and base64-urlencode the secret to use as the challenge\n const code_challenge = await pkceChallengeFromVerifier(codeVerifier)\n\n window.location.href =\n `https://${loginDomain}/oauth2/authorize` +\n '?response_type=code' +\n '&client_id=' +\n encodeURIComponent(this.clientId) +\n '&state=' +\n encodeURIComponent(state) +\n '&scope=' +\n encodeURIComponent('openid email profile aws.cognito.signin.user.admin') +\n '&redirect_uri=' +\n encodeURIComponent(redirectUri) +\n '&code_challenge=' +\n encodeURIComponent(code_challenge) +\n '&code_challenge_method=S256' +\n (identityProviderName\n ? '&identity_provider=' + encodeURIComponent(identityProviderName)\n : '')\n }\n\n async handleAuthentication(): Promise<void> {\n const loginDomain = this.loginDomain\n const redirectUri = this.redirectUri\n if (!loginDomain || !redirectUri) {\n throw new TypeError(\n '\"loginDomain\" or \"redirectUri\" was not passed to constructor. Both are required before attempting to handle a login.',\n )\n }\n\n const query = new URLSearchParams(window.location.search)\n const queryError = query.get('error')\n const queryErrorDescription = query.get('error_description')\n\n // Check if the server returned an error string\n if (typeof queryError === 'string') {\n throw new Error(\n `${queryError} - ${\n typeof queryErrorDescription === 'string'\n ? queryErrorDescription\n : 'An unknown error has occurred.'\n }`,\n )\n }\n\n const code = query.get('code')\n if (typeof code !== 'string') {\n throw new Error('\"code\" was not including in query string to parse')\n }\n\n if (localStorage.getItem(this.STATE) !== query.get('state')) {\n throw new Error('Invalid login')\n }\n\n const code_verifier = localStorage.getItem(this.PKCE_CODE_VERIFIER)\n\n // Clean these up since we don't need them anymore\n localStorage.removeItem(this.STATE)\n localStorage.removeItem(this.PKCE_CODE_VERIFIER)\n\n // Exchange the authorization code for an access token\n const result: Record<string, unknown> = await new Promise(\n (resolve, reject) => {\n sendPostRequest(\n `https://${loginDomain}/oauth2/token`,\n {\n grant_type: 'authorization_code',\n code,\n client_id: this.clientId,\n redirect_uri: redirectUri,\n code_verifier,\n },\n resolve,\n (error) => {\n reject(\n new Error(\n error.error_description ||\n error.message ||\n 'An unknown error has occurred while processing authentication code',\n ),\n )\n },\n )\n },\n )\n\n this._storeAuthenticationResult({\n AccessToken: result.access_token as string,\n ExpiresIn: result.expires_in as number,\n IdToken: result.id_token as string,\n TokenType: result.token_type as string,\n RefreshToken: result.refresh_token as string,\n })\n }\n\n async changePassword(\n existingPassword: string,\n newPassword: string,\n ): Promise<void> {\n const accessToken = await this.getAccessToken()\n await this.cognitoIdentityProviderClient.send(\n new ChangePasswordCommand({\n AccessToken: accessToken || '',\n PreviousPassword: existingPassword,\n ProposedPassword: newPassword,\n }),\n )\n }\n async confirmForgotPassword({\n username,\n code,\n password,\n }: {\n username: string\n code: string\n password: string\n }) {\n await this.cognitoIdentityProviderClient.send(\n new ConfirmForgotPasswordCommand({\n ClientId: this.clientId,\n ConfirmationCode: code,\n Password: password,\n Username: username,\n }),\n )\n }\n\n logoutHostedUI(): void {\n const loginDomain = this.loginDomain\n const logoutUri = this.logoutUri\n if (!loginDomain || !logoutUri) {\n throw new TypeError(\n '\"loginDomain\" or \"logoutUri\" was not passed to constructor. Both are required before attempting to logout.',\n )\n }\n\n window.location.href =\n `https://${loginDomain}/logout` +\n '?client_id=' +\n encodeURIComponent(this.clientId) +\n '&logout_uri=' +\n encodeURIComponent(logoutUri)\n }\n\n async logout(): Promise<void> {\n try {\n const refreshToken = this._getRefreshToken()\n // Refresh session to allow access token to perform sign out\n if (refreshToken) {\n await this._refreshSession()\n }\n\n const accessToken = this._getAccessToken()\n if (accessToken) {\n await this.cognitoIdentityProviderClient.send(\n new GlobalSignOutCommand({\n AccessToken: accessToken,\n }),\n )\n }\n } catch (error) {\n if (!(error as OneBlinkAppsError).requiresLogin) {\n throw error\n }\n } finally {\n this._removeAuthenticationResult()\n }\n }\n\n async getIdToken(): Promise<string | undefined> {\n await this._refreshSession()\n\n return this._getIdToken()\n }\n\n async getAccessToken(): Promise<string | undefined> {\n await this._refreshSession()\n\n return this._getAccessToken()\n }\n\n async getMfaSettings(abortSignal?: AbortSignal): Promise<MfaSettings> {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return DEFAULT_MFA_SETTINGS\n }\n\n const user = await this.cognitoIdentityProviderClient.send(\n new GetUserCommand({\n AccessToken: accessToken,\n }),\n { abortSignal },\n )\n\n const mfaList = user.UserMFASettingList || []\n const preferredMfaSetting = user.PreferredMfaSetting\n const phoneNumber = user.UserAttributes?.find(\n (attribute) => attribute.Name === 'phone_number',\n )?.Value\n const isPhoneNumberVerified =\n user.UserAttributes?.find(\n (attribute) => attribute.Name === 'phone_number_verified',\n )?.Value === 'true'\n\n const authenticatorEnabled = mfaList.includes('SOFTWARE_TOKEN_MFA')\n const smsEnabled = mfaList.includes('SMS_MFA')\n const { authenticatorPreferred, smsPreferred } = resolveMfaPreferredFlags({\n authenticatorEnabled,\n smsEnabled,\n preferredMfaSetting,\n })\n\n return {\n authenticator: {\n enabled: authenticatorEnabled,\n preferred: authenticatorPreferred,\n },\n sms: {\n enabled: smsEnabled,\n preferred: smsPreferred,\n phoneNumber,\n isPhoneNumberVerified,\n },\n }\n }\n\n async updateUserPhoneNumber(\n phoneNumber: string,\n ): Promise<{ isPhoneNumberVerified: boolean }> {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return { isPhoneNumberVerified: false }\n }\n\n await this.cognitoIdentityProviderClient.send(\n new UpdateUserAttributesCommand({\n AccessToken: accessToken,\n UserAttributes: [\n {\n Name: 'phone_number',\n Value: phoneNumber,\n },\n ],\n }),\n )\n\n const mfaSettings = await this.getMfaSettings()\n return { isPhoneNumberVerified: mfaSettings.sms.isPhoneNumberVerified }\n }\n\n async removeUserPhoneNumber() {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n await this.cognitoIdentityProviderClient.send(\n new DeleteUserAttributesCommand({\n AccessToken: accessToken,\n UserAttributeNames: ['phone_number'],\n }),\n )\n }\n\n async verifyUserPhoneNumber(code: string) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n await this.cognitoIdentityProviderClient.send(\n new VerifyUserAttributeCommand({\n AccessToken: accessToken,\n AttributeName: 'phone_number',\n Code: code,\n }),\n )\n }\n\n async setPreferredMfaMethod(method: MfaMethod) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n const currentSettings = await this.getMfaSettings()\n\n await this.cognitoIdentityProviderClient.send(\n new SetUserMFAPreferenceCommand({\n AccessToken: accessToken,\n ...(currentSettings.authenticator.enabled\n ? {\n SoftwareTokenMfaSettings: {\n Enabled: true,\n PreferredMfa: method === 'authenticator',\n },\n }\n : {}),\n ...(currentSettings.sms.enabled\n ? {\n SMSMfaSettings: {\n Enabled: true,\n PreferredMfa: method === 'sms',\n },\n }\n : {}),\n }),\n )\n }\n\n async disableMfaMethod(method: MfaMethod) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n const currentSettings = await this.getMfaSettings()\n const wasPreferred =\n method === 'authenticator'\n ? currentSettings.authenticator.preferred\n : currentSettings.sms.preferred\n const otherMethod: MfaMethod =\n method === 'authenticator' ? 'sms' : 'authenticator'\n const otherSettings =\n method === 'authenticator'\n ? currentSettings.sms\n : currentSettings.authenticator\n\n await this.cognitoIdentityProviderClient.send(\n new SetUserMFAPreferenceCommand({\n AccessToken: accessToken,\n ...(method === 'authenticator'\n ? {\n SoftwareTokenMfaSettings: {\n Enabled: false,\n PreferredMfa: false,\n },\n }\n : {\n SMSMfaSettings: {\n Enabled: false,\n PreferredMfa: false,\n },\n }),\n ...(wasPreferred && otherSettings.enabled\n ? otherMethod === 'authenticator'\n ? {\n SoftwareTokenMfaSettings: {\n Enabled: true,\n PreferredMfa: true,\n },\n }\n : {\n SMSMfaSettings: {\n Enabled: true,\n PreferredMfa: true,\n },\n }\n : {}),\n }),\n )\n }\n\n async setupSmsMfa({ preferred }: { preferred?: boolean } = {}) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n const currentSettings = await this.getMfaSettings()\n const hasPreferredMethod =\n (currentSettings.authenticator.enabled &&\n currentSettings.authenticator.preferred) ||\n (currentSettings.sms.enabled && currentSettings.sms.preferred)\n const shouldBePreferred =\n preferred ?? (!hasPreferredMethod && !currentSettings.sms.enabled)\n\n await this.cognitoIdentityProviderClient.send(\n new SetUserMFAPreferenceCommand({\n AccessToken: accessToken,\n SMSMfaSettings: {\n Enabled: true,\n PreferredMfa: shouldBePreferred,\n },\n ...(shouldBePreferred && currentSettings.authenticator.enabled\n ? {\n SoftwareTokenMfaSettings: {\n Enabled: true,\n PreferredMfa: false,\n },\n }\n : {}),\n }),\n )\n }\n\n async setupMfaAuthenticatorApp({ preferred }: { preferred?: boolean } = {}) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n const { SecretCode } = await this.cognitoIdentityProviderClient.send(\n new AssociateSoftwareTokenCommand({\n AccessToken: accessToken,\n }),\n )\n\n return {\n secretCode: SecretCode,\n mfaCodeCallback: async (code: string) => {\n await this.cognitoIdentityProviderClient.send(\n new VerifySoftwareTokenCommand({\n AccessToken: accessToken,\n UserCode: code,\n }),\n )\n\n const currentSettings = await this.getMfaSettings()\n const hasPreferredMethod =\n (currentSettings.authenticator.enabled &&\n currentSettings.authenticator.preferred) ||\n (currentSettings.sms.enabled && currentSettings.sms.preferred)\n const shouldBePreferred =\n preferred ??\n (!hasPreferredMethod && !currentSettings.authenticator.enabled)\n\n await this.cognitoIdentityProviderClient.send(\n new SetUserMFAPreferenceCommand({\n SoftwareTokenMfaSettings: {\n Enabled: true,\n PreferredMfa: shouldBePreferred,\n },\n ...(shouldBePreferred && currentSettings.sms.enabled\n ? {\n SMSMfaSettings: {\n Enabled: true,\n PreferredMfa: false,\n },\n }\n : {}),\n AccessToken: accessToken,\n }),\n )\n },\n }\n }\n}\n\n//////////////////////////////////////////////////////////////////////\n// GENERAL HELPER FUNCTIONS\n\n// Make a POST request and parse the response as JSON\nfunction sendPostRequest(\n url: string,\n params: Record<string, unknown>,\n success: (value: Record<string, unknown>) => void,\n error: (err: { message?: string; error_description?: string }) => void,\n) {\n const request = new XMLHttpRequest()\n request.open('POST', url, true)\n request.setRequestHeader(\n 'Content-Type',\n 'application/x-www-form-urlencoded; charset=UTF-8',\n )\n request.onload = function () {\n let body = {}\n try {\n body = JSON.parse(request.response)\n } catch (e) {\n Sentry.captureException(e)\n // Do nothing\n }\n\n if (request.status == 200) {\n success(body)\n } else {\n error(body)\n }\n }\n request.onerror = function () {\n error({})\n }\n const body = Object.keys(params)\n .reduce((keys: string[], key) => {\n if (params[key]) {\n keys.push(key + '=' + params[key])\n }\n return keys\n }, [])\n .join('&')\n request.send(body)\n}\n\n//////////////////////////////////////////////////////////////////////\n// PKCE HELPER FUNCTIONS\n\n// Generate a secure random string using the browser crypto functions\nfunction generateRandomString() {\n const array = new Uint32Array(28)\n window.crypto.getRandomValues(array)\n return Array.from(array, (dec) => ('0' + dec.toString(16)).substr(-2)).join(\n '',\n )\n}\n\n// Calculate the SHA256 hash of the input text.\n// Returns a promise that resolves to an ArrayBuffer\nfunction sha256(plain: string) {\n const encoder = new TextEncoder()\n const data = encoder.encode(plain)\n return window.crypto.subtle.digest('SHA-256', data)\n}\n\n// Base64-urlencodes the input string\nfunction base64urlencode(str: ArrayBuffer) {\n // Convert the ArrayBuffer to string using Uint8 array to conver to what btoa accepts.\n // btoa accepts chars only within ascii 0-255 and base64 encodes them.\n // Then convert the base64 encoded to base64url encoded\n // (replace + with -, replace / with _, trim trailing =)\n // @ts-expect-error\n return btoa(String.fromCharCode.apply(null, new Uint8Array(str)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '')\n}\n\n// Return the base64-urlencoded sha256 hash for the PKCE challenge\nasync function pkceChallengeFromVerifier(v: string) {\n const hashed = await sha256(v)\n return base64urlencode(hashed)\n}\n"]}
1
+ {"version":3,"file":"AWSCognitoClient.js","sourceRoot":"","sources":["../../../src/apps/services/AWSCognitoClient.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AssociateSoftwareTokenCommand,\n AuthenticationResultType,\n ChangePasswordCommand,\n CognitoIdentityProviderClient,\n ConfirmForgotPasswordCommand,\n DeleteUserAttributesCommand,\n GetUserCommand,\n GlobalSignOutCommand,\n InitiateAuthCommand,\n InitiateAuthResponse,\n RespondToAuthChallengeCommand,\n SetUserMFAPreferenceCommand,\n UpdateUserAttributesCommand,\n VerifySoftwareTokenCommand,\n VerifyUserAttributeCommand,\n} from '@aws-sdk/client-cognito-identity-provider'\nimport { jwtDecode } from 'jwt-decode'\nimport Sentry from '../Sentry'\nimport { OneBlinkAppsError } from '..'\n\nexport type MfaMethod = 'authenticator' | 'sms'\n\nexport type LoggedInMfaMethod =\n | 'SOFTWARE_TOKEN_MFA'\n | 'SMS_MFA'\n | 'NO_MFA_ENABLED'\n\nexport type MfaSettings = {\n loggedInWithMfaMethod: LoggedInMfaMethod\n authenticator: {\n enabled: boolean\n preferred: boolean\n }\n sms: {\n enabled: boolean\n preferred: boolean\n phoneNumber: string | undefined\n isPhoneNumberVerified: boolean\n }\n}\n\nexport const DEFAULT_MFA_SETTINGS: MfaSettings = {\n loggedInWithMfaMethod: 'NO_MFA_ENABLED',\n authenticator: { enabled: false, preferred: false },\n sms: {\n enabled: false,\n preferred: false,\n phoneNumber: undefined,\n isPhoneNumberVerified: false,\n },\n}\n\nexport function resolveLoggedInMfaMethod(\n idToken: string | undefined,\n): LoggedInMfaMethod {\n if (idToken) {\n try {\n const payload = jwtDecode<{ mfa_method?: unknown }>(idToken)\n switch (payload.mfa_method) {\n case 'SOFTWARE_TOKEN_MFA':\n case 'SMS_MFA':\n return payload.mfa_method\n }\n } catch (error) {\n console.warn(\n 'Error while decoding id token for logged in MFA method',\n error,\n )\n Sentry.captureException(error)\n }\n }\n return 'NO_MFA_ENABLED'\n}\n\nexport function resolveMfaPreferredFlags({\n authenticatorEnabled,\n smsEnabled,\n preferredMfaSetting,\n}: {\n authenticatorEnabled: boolean\n smsEnabled: boolean\n preferredMfaSetting: string | undefined\n}): {\n authenticatorPreferred: boolean\n smsPreferred: boolean\n} {\n const cognitoAuthenticatorPreferred =\n preferredMfaSetting === 'SOFTWARE_TOKEN_MFA'\n const cognitoSmsPreferred = preferredMfaSetting === 'SMS_MFA'\n\n if (cognitoAuthenticatorPreferred && authenticatorEnabled) {\n return { authenticatorPreferred: true, smsPreferred: false }\n }\n\n if (cognitoSmsPreferred && smsEnabled) {\n return { authenticatorPreferred: false, smsPreferred: true }\n }\n\n if (authenticatorEnabled && smsEnabled) {\n return { authenticatorPreferred: true, smsPreferred: false }\n }\n\n return {\n authenticatorPreferred: authenticatorEnabled,\n smsPreferred: smsEnabled,\n }\n}\n\nexport type LoginAttemptMfa = {\n method: MfaMethod\n codeCallback: (code: string) => Promise<LoginAttemptResponse>\n resendCodeCallback?: () => Promise<LoginAttemptResponse>\n}\n\nexport type LoginAttemptResponse = {\n resetPasswordCallback?: (newPassword: string) => Promise<LoginAttemptResponse>\n mfa?: LoginAttemptMfa\n}\n\nexport default class AWSCognitoClient {\n clientId: string\n cognitoIdentityProviderClient: CognitoIdentityProviderClient\n loginDomain: string | void\n redirectUri: string | void\n logoutUri: string | void\n listeners: Array<() => unknown>\n\n constructor({\n clientId,\n region,\n loginDomain,\n redirectUri,\n logoutUri,\n }: {\n clientId: string\n region: string\n redirectUri?: string\n logoutUri?: string\n loginDomain?: string\n }) {\n if (!clientId) {\n throw new TypeError('\"clientId\" is required in constructor')\n }\n if (!region) {\n throw new TypeError('\"region\" is required in constructor')\n }\n\n this.listeners = []\n this.redirectUri = redirectUri\n this.logoutUri = logoutUri\n this.loginDomain = loginDomain\n this.clientId = clientId\n this.cognitoIdentityProviderClient = new CognitoIdentityProviderClient({\n region,\n })\n }\n\n // Local Storage Keys\n get EXPIRES_AT() {\n return `COGNITO_${this.clientId}_EXPIRES_AT`\n }\n get ACCESS_TOKEN() {\n return `COGNITO_${this.clientId}_ACCESS_TOKEN`\n }\n get ID_TOKEN() {\n return `COGNITO_${this.clientId}_ID_TOKEN`\n }\n get REFRESH_TOKEN() {\n return `COGNITO_${this.clientId}_REFRESH_TOKEN`\n }\n get STATE() {\n return `COGNITO_${this.clientId}_STATE`\n }\n get PKCE_CODE_VERIFIER() {\n return `COGNITO_${this.clientId}_PKCE_CODE_VERIFIER`\n }\n\n _executeListeners() {\n for (const listener of this.listeners) {\n try {\n listener()\n } catch (error) {\n Sentry.captureException(error)\n // Ignore error from listeners\n console.warn('AWSCognitoClient listener error', error)\n }\n }\n }\n\n _storeAuthenticationResult(authenticationResult: AuthenticationResultType) {\n // Take off 5 seconds to ensure a request does not become unauthenticated mid request\n const expiresAt =\n (authenticationResult.ExpiresIn as number) * 1000 + Date.now() - 5000\n localStorage.setItem(this.EXPIRES_AT, expiresAt.toString())\n localStorage.setItem(\n this.ACCESS_TOKEN,\n authenticationResult.AccessToken as string,\n )\n localStorage.setItem(this.ID_TOKEN, authenticationResult.IdToken as string)\n if (authenticationResult.RefreshToken) {\n localStorage.setItem(\n this.REFRESH_TOKEN,\n authenticationResult.RefreshToken,\n )\n }\n\n this._executeListeners()\n }\n\n _removeAuthenticationResult() {\n localStorage.removeItem(this.EXPIRES_AT)\n localStorage.removeItem(this.ACCESS_TOKEN)\n localStorage.removeItem(this.ID_TOKEN)\n localStorage.removeItem(this.REFRESH_TOKEN)\n\n this._executeListeners()\n }\n\n _getAccessToken(): string | undefined {\n return localStorage.getItem(this.ACCESS_TOKEN) || undefined\n }\n\n _getIdToken(): string | undefined {\n return localStorage.getItem(this.ID_TOKEN) || undefined\n }\n\n _getRefreshToken(): string | undefined {\n return localStorage.getItem(this.REFRESH_TOKEN) || undefined\n }\n\n _isSessionValid(): boolean {\n const expiresAt = localStorage.getItem(this.EXPIRES_AT)\n if (!expiresAt) {\n return false\n }\n return parseInt(expiresAt, 10) > Date.now()\n }\n\n async _refreshSession(): Promise<void> {\n if (this._isSessionValid()) {\n return\n }\n\n const refreshToken = this._getRefreshToken()\n if (!refreshToken) {\n return\n }\n\n try {\n const result = await this.cognitoIdentityProviderClient.send(\n new InitiateAuthCommand({\n AuthFlow: 'REFRESH_TOKEN_AUTH',\n ClientId: this.clientId,\n AuthParameters: {\n REFRESH_TOKEN: refreshToken,\n },\n }),\n )\n if (result.AuthenticationResult) {\n this._storeAuthenticationResult(result.AuthenticationResult)\n }\n } catch (error) {\n console.warn('Error while attempting to refresh session', error)\n this._removeAuthenticationResult()\n throw new OneBlinkAppsError(\n 'Your session has expired. Please login again to continue to use the application.',\n {\n requiresLogin: true,\n originalError: error as Error,\n },\n )\n }\n }\n\n registerListener(listener: () => unknown): () => void {\n this.listeners.push(listener)\n\n return () => {\n const index = this.listeners.indexOf(listener)\n if (index !== -1) {\n this.listeners.splice(index, 1)\n }\n }\n }\n\n async responseToAuthChallenge(\n username: string,\n initiateAuthResponse: InitiateAuthResponse,\n password?: string,\n ): Promise<LoginAttemptResponse> {\n if (initiateAuthResponse.AuthenticationResult) {\n this._storeAuthenticationResult(initiateAuthResponse.AuthenticationResult)\n return {}\n }\n\n const ChallengeName = initiateAuthResponse.ChallengeName\n switch (ChallengeName) {\n case 'NEW_PASSWORD_REQUIRED': {\n return {\n resetPasswordCallback: async (newPassword) => {\n const resetPasswordResult =\n await this.cognitoIdentityProviderClient.send(\n new RespondToAuthChallengeCommand({\n ChallengeName,\n ClientId: this.clientId,\n Session: initiateAuthResponse.Session,\n ChallengeResponses: {\n USERNAME: username,\n NEW_PASSWORD: newPassword,\n },\n }),\n )\n return await this.responseToAuthChallenge(\n username,\n resetPasswordResult,\n newPassword,\n )\n },\n }\n }\n case 'SOFTWARE_TOKEN_MFA': {\n return {\n mfa: {\n method: 'authenticator',\n codeCallback: async (code) => {\n const resetPasswordResult =\n await this.cognitoIdentityProviderClient.send(\n new RespondToAuthChallengeCommand({\n ChallengeName,\n ClientId: this.clientId,\n Session: initiateAuthResponse.Session,\n ChallengeResponses: {\n USERNAME: username,\n SOFTWARE_TOKEN_MFA_CODE: code,\n },\n }),\n )\n return await this.responseToAuthChallenge(\n username,\n resetPasswordResult,\n password,\n )\n },\n resendCodeCallback: undefined,\n },\n }\n }\n case 'EMAIL_OTP': {\n throw new Error('Email OTP is not supported')\n }\n case 'SMS_MFA': {\n if (!initiateAuthResponse.Session) {\n throw new Error(\n 'An unexpected error occurred while attempting to process your login. Please try again or contact support if the problem persists.',\n )\n }\n\n return {\n mfa: {\n method: 'sms',\n codeCallback: async (code) => {\n const smsChallengeResult =\n await this.cognitoIdentityProviderClient.send(\n new RespondToAuthChallengeCommand({\n ChallengeName,\n ClientId: this.clientId,\n Session: initiateAuthResponse.Session,\n ChallengeResponses: {\n USERNAME: username,\n SMS_MFA_CODE: code,\n },\n }),\n )\n return await this.responseToAuthChallenge(\n username,\n smsChallengeResult,\n password,\n )\n },\n resendCodeCallback: async () => {\n if (!password) {\n throw new Error(\n 'Unable to resend the SMS verification code. Please try signing in again.',\n )\n }\n\n const loginAttemptResponse = await this.loginUsernamePassword(\n username,\n password,\n )\n\n if (loginAttemptResponse.mfa?.method !== 'sms') {\n throw new Error(\n 'Unable to resend the SMS verification code. Please try signing in again.',\n )\n }\n\n return loginAttemptResponse\n },\n },\n }\n }\n }\n\n console.warn(\n '\"CognitoIdentityServiceProvider.InitiateAuthResponse\" challenge has not been catered.',\n initiateAuthResponse,\n )\n throw new Error(\n 'An unexpected error occurred while attempting to process your login. Please try again or contact support if the problem persists.',\n )\n }\n\n async loginUsernamePassword(\n username: string,\n password: string,\n ): Promise<LoginAttemptResponse> {\n const loginResult = await this.cognitoIdentityProviderClient.send(\n new InitiateAuthCommand({\n AuthFlow: 'USER_PASSWORD_AUTH',\n ClientId: this.clientId,\n AuthParameters: {\n USERNAME: username,\n PASSWORD: password,\n },\n }),\n )\n\n return await this.responseToAuthChallenge(username, loginResult, password)\n }\n\n async loginHostedUI(identityProviderName?: string): Promise<void> {\n const loginDomain = this.loginDomain\n const redirectUri = this.redirectUri\n if (!loginDomain || !redirectUri) {\n throw new TypeError(\n '\"loginDomain\" or \"redirectUri\" was not passed to constructor. Both are required before attempting to login.',\n )\n }\n\n // Create and store a random \"state\" value\n const state = generateRandomString()\n localStorage.setItem(this.STATE, state)\n\n // Create and store a new PKCE code_verifier (the plaintext random secret)\n const codeVerifier = generateRandomString()\n localStorage.setItem(this.PKCE_CODE_VERIFIER, codeVerifier)\n\n // Hash and base64-urlencode the secret to use as the challenge\n const code_challenge = await pkceChallengeFromVerifier(codeVerifier)\n\n window.location.href =\n `https://${loginDomain}/oauth2/authorize` +\n '?response_type=code' +\n '&client_id=' +\n encodeURIComponent(this.clientId) +\n '&state=' +\n encodeURIComponent(state) +\n '&scope=' +\n encodeURIComponent('openid email profile aws.cognito.signin.user.admin') +\n '&redirect_uri=' +\n encodeURIComponent(redirectUri) +\n '&code_challenge=' +\n encodeURIComponent(code_challenge) +\n '&code_challenge_method=S256' +\n (identityProviderName\n ? '&identity_provider=' + encodeURIComponent(identityProviderName)\n : '')\n }\n\n async handleAuthentication(): Promise<void> {\n const loginDomain = this.loginDomain\n const redirectUri = this.redirectUri\n if (!loginDomain || !redirectUri) {\n throw new TypeError(\n '\"loginDomain\" or \"redirectUri\" was not passed to constructor. Both are required before attempting to handle a login.',\n )\n }\n\n const query = new URLSearchParams(window.location.search)\n const queryError = query.get('error')\n const queryErrorDescription = query.get('error_description')\n\n // Check if the server returned an error string\n if (typeof queryError === 'string') {\n throw new Error(\n `${queryError} - ${\n typeof queryErrorDescription === 'string'\n ? queryErrorDescription\n : 'An unknown error has occurred.'\n }`,\n )\n }\n\n const code = query.get('code')\n if (typeof code !== 'string') {\n throw new Error('\"code\" was not including in query string to parse')\n }\n\n if (localStorage.getItem(this.STATE) !== query.get('state')) {\n throw new Error('Invalid login')\n }\n\n const code_verifier = localStorage.getItem(this.PKCE_CODE_VERIFIER)\n\n // Clean these up since we don't need them anymore\n localStorage.removeItem(this.STATE)\n localStorage.removeItem(this.PKCE_CODE_VERIFIER)\n\n // Exchange the authorization code for an access token\n const result: Record<string, unknown> = await new Promise(\n (resolve, reject) => {\n sendPostRequest(\n `https://${loginDomain}/oauth2/token`,\n {\n grant_type: 'authorization_code',\n code,\n client_id: this.clientId,\n redirect_uri: redirectUri,\n code_verifier,\n },\n resolve,\n (error) => {\n reject(\n new Error(\n error.error_description ||\n error.message ||\n 'An unknown error has occurred while processing authentication code',\n ),\n )\n },\n )\n },\n )\n\n this._storeAuthenticationResult({\n AccessToken: result.access_token as string,\n ExpiresIn: result.expires_in as number,\n IdToken: result.id_token as string,\n TokenType: result.token_type as string,\n RefreshToken: result.refresh_token as string,\n })\n }\n\n async changePassword(\n existingPassword: string,\n newPassword: string,\n ): Promise<void> {\n const accessToken = await this.getAccessToken()\n await this.cognitoIdentityProviderClient.send(\n new ChangePasswordCommand({\n AccessToken: accessToken || '',\n PreviousPassword: existingPassword,\n ProposedPassword: newPassword,\n }),\n )\n }\n async confirmForgotPassword({\n username,\n code,\n password,\n }: {\n username: string\n code: string\n password: string\n }) {\n await this.cognitoIdentityProviderClient.send(\n new ConfirmForgotPasswordCommand({\n ClientId: this.clientId,\n ConfirmationCode: code,\n Password: password,\n Username: username,\n }),\n )\n }\n\n logoutHostedUI(): void {\n const loginDomain = this.loginDomain\n const logoutUri = this.logoutUri\n if (!loginDomain || !logoutUri) {\n throw new TypeError(\n '\"loginDomain\" or \"logoutUri\" was not passed to constructor. Both are required before attempting to logout.',\n )\n }\n\n window.location.href =\n `https://${loginDomain}/logout` +\n '?client_id=' +\n encodeURIComponent(this.clientId) +\n '&logout_uri=' +\n encodeURIComponent(logoutUri)\n }\n\n async logout(): Promise<void> {\n try {\n const refreshToken = this._getRefreshToken()\n // Refresh session to allow access token to perform sign out\n if (refreshToken) {\n await this._refreshSession()\n }\n\n const accessToken = this._getAccessToken()\n if (accessToken) {\n await this.cognitoIdentityProviderClient.send(\n new GlobalSignOutCommand({\n AccessToken: accessToken,\n }),\n )\n }\n } catch (error) {\n if (!(error as OneBlinkAppsError).requiresLogin) {\n throw error\n }\n } finally {\n this._removeAuthenticationResult()\n }\n }\n\n async getIdToken(): Promise<string | undefined> {\n await this._refreshSession()\n\n return this._getIdToken()\n }\n\n async getAccessToken(): Promise<string | undefined> {\n await this._refreshSession()\n\n return this._getAccessToken()\n }\n\n async getMfaSettings(abortSignal?: AbortSignal): Promise<MfaSettings> {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return DEFAULT_MFA_SETTINGS\n }\n\n const user = await this.cognitoIdentityProviderClient.send(\n new GetUserCommand({\n AccessToken: accessToken,\n }),\n { abortSignal },\n )\n\n const mfaList = user.UserMFASettingList || []\n const preferredMfaSetting = user.PreferredMfaSetting\n const phoneNumber = user.UserAttributes?.find(\n (attribute) => attribute.Name === 'phone_number',\n )?.Value\n const isPhoneNumberVerified =\n user.UserAttributes?.find(\n (attribute) => attribute.Name === 'phone_number_verified',\n )?.Value === 'true'\n\n const authenticatorEnabled = mfaList.includes('SOFTWARE_TOKEN_MFA')\n const smsEnabled = mfaList.includes('SMS_MFA')\n const { authenticatorPreferred, smsPreferred } = resolveMfaPreferredFlags({\n authenticatorEnabled,\n smsEnabled,\n preferredMfaSetting,\n })\n\n const loggedInWithMfaMethod = resolveLoggedInMfaMethod(this._getIdToken())\n\n return {\n loggedInWithMfaMethod,\n authenticator: {\n enabled: authenticatorEnabled,\n preferred: authenticatorPreferred,\n },\n sms: {\n enabled: smsEnabled,\n preferred: smsPreferred,\n phoneNumber,\n isPhoneNumberVerified,\n },\n }\n }\n\n async updateUserPhoneNumber(\n phoneNumber: string,\n ): Promise<{ isPhoneNumberVerified: boolean }> {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return { isPhoneNumberVerified: false }\n }\n\n await this.cognitoIdentityProviderClient.send(\n new UpdateUserAttributesCommand({\n AccessToken: accessToken,\n UserAttributes: [\n {\n Name: 'phone_number',\n Value: phoneNumber,\n },\n ],\n }),\n )\n\n const mfaSettings = await this.getMfaSettings()\n return { isPhoneNumberVerified: mfaSettings.sms.isPhoneNumberVerified }\n }\n\n async removeUserPhoneNumber() {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n await this.cognitoIdentityProviderClient.send(\n new DeleteUserAttributesCommand({\n AccessToken: accessToken,\n UserAttributeNames: ['phone_number'],\n }),\n )\n }\n\n async verifyUserPhoneNumber(code: string) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n await this.cognitoIdentityProviderClient.send(\n new VerifyUserAttributeCommand({\n AccessToken: accessToken,\n AttributeName: 'phone_number',\n Code: code,\n }),\n )\n }\n\n async setPreferredMfaMethod(method: MfaMethod) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n const currentSettings = await this.getMfaSettings()\n\n await this.cognitoIdentityProviderClient.send(\n new SetUserMFAPreferenceCommand({\n AccessToken: accessToken,\n ...(currentSettings.authenticator.enabled\n ? {\n SoftwareTokenMfaSettings: {\n Enabled: true,\n PreferredMfa: method === 'authenticator',\n },\n }\n : {}),\n ...(currentSettings.sms.enabled\n ? {\n SMSMfaSettings: {\n Enabled: true,\n PreferredMfa: method === 'sms',\n },\n }\n : {}),\n }),\n )\n }\n\n async disableMfaMethod(method: MfaMethod) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n const currentSettings = await this.getMfaSettings()\n const wasPreferred =\n method === 'authenticator'\n ? currentSettings.authenticator.preferred\n : currentSettings.sms.preferred\n const otherMethod: MfaMethod =\n method === 'authenticator' ? 'sms' : 'authenticator'\n const otherSettings =\n method === 'authenticator'\n ? currentSettings.sms\n : currentSettings.authenticator\n\n await this.cognitoIdentityProviderClient.send(\n new SetUserMFAPreferenceCommand({\n AccessToken: accessToken,\n ...(method === 'authenticator'\n ? {\n SoftwareTokenMfaSettings: {\n Enabled: false,\n PreferredMfa: false,\n },\n }\n : {\n SMSMfaSettings: {\n Enabled: false,\n PreferredMfa: false,\n },\n }),\n ...(wasPreferred && otherSettings.enabled\n ? otherMethod === 'authenticator'\n ? {\n SoftwareTokenMfaSettings: {\n Enabled: true,\n PreferredMfa: true,\n },\n }\n : {\n SMSMfaSettings: {\n Enabled: true,\n PreferredMfa: true,\n },\n }\n : {}),\n }),\n )\n }\n\n async setupSmsMfa({ preferred }: { preferred?: boolean } = {}) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n const currentSettings = await this.getMfaSettings()\n const hasPreferredMethod =\n (currentSettings.authenticator.enabled &&\n currentSettings.authenticator.preferred) ||\n (currentSettings.sms.enabled && currentSettings.sms.preferred)\n const shouldBePreferred =\n preferred ?? (!hasPreferredMethod && !currentSettings.sms.enabled)\n\n await this.cognitoIdentityProviderClient.send(\n new SetUserMFAPreferenceCommand({\n AccessToken: accessToken,\n SMSMfaSettings: {\n Enabled: true,\n PreferredMfa: shouldBePreferred,\n },\n ...(shouldBePreferred && currentSettings.authenticator.enabled\n ? {\n SoftwareTokenMfaSettings: {\n Enabled: true,\n PreferredMfa: false,\n },\n }\n : {}),\n }),\n )\n }\n\n async setupMfaAuthenticatorApp({ preferred }: { preferred?: boolean } = {}) {\n const accessToken = await this.getAccessToken()\n if (!accessToken) {\n return\n }\n\n const { SecretCode } = await this.cognitoIdentityProviderClient.send(\n new AssociateSoftwareTokenCommand({\n AccessToken: accessToken,\n }),\n )\n\n return {\n secretCode: SecretCode,\n mfaCodeCallback: async (code: string) => {\n await this.cognitoIdentityProviderClient.send(\n new VerifySoftwareTokenCommand({\n AccessToken: accessToken,\n UserCode: code,\n }),\n )\n\n const currentSettings = await this.getMfaSettings()\n const hasPreferredMethod =\n (currentSettings.authenticator.enabled &&\n currentSettings.authenticator.preferred) ||\n (currentSettings.sms.enabled && currentSettings.sms.preferred)\n const shouldBePreferred =\n preferred ??\n (!hasPreferredMethod && !currentSettings.authenticator.enabled)\n\n await this.cognitoIdentityProviderClient.send(\n new SetUserMFAPreferenceCommand({\n SoftwareTokenMfaSettings: {\n Enabled: true,\n PreferredMfa: shouldBePreferred,\n },\n ...(shouldBePreferred && currentSettings.sms.enabled\n ? {\n SMSMfaSettings: {\n Enabled: true,\n PreferredMfa: false,\n },\n }\n : {}),\n AccessToken: accessToken,\n }),\n )\n },\n }\n }\n}\n\n//////////////////////////////////////////////////////////////////////\n// GENERAL HELPER FUNCTIONS\n\n// Make a POST request and parse the response as JSON\nfunction sendPostRequest(\n url: string,\n params: Record<string, unknown>,\n success: (value: Record<string, unknown>) => void,\n error: (err: { message?: string; error_description?: string }) => void,\n) {\n const request = new XMLHttpRequest()\n request.open('POST', url, true)\n request.setRequestHeader(\n 'Content-Type',\n 'application/x-www-form-urlencoded; charset=UTF-8',\n )\n request.onload = function () {\n let body = {}\n try {\n body = JSON.parse(request.response)\n } catch (e) {\n Sentry.captureException(e)\n // Do nothing\n }\n\n if (request.status == 200) {\n success(body)\n } else {\n error(body)\n }\n }\n request.onerror = function () {\n error({})\n }\n const body = Object.keys(params)\n .reduce((keys: string[], key) => {\n if (params[key]) {\n keys.push(key + '=' + params[key])\n }\n return keys\n }, [])\n .join('&')\n request.send(body)\n}\n\n//////////////////////////////////////////////////////////////////////\n// PKCE HELPER FUNCTIONS\n\n// Generate a secure random string using the browser crypto functions\nfunction generateRandomString() {\n const array = new Uint32Array(28)\n window.crypto.getRandomValues(array)\n return Array.from(array, (dec) => ('0' + dec.toString(16)).substr(-2)).join(\n '',\n )\n}\n\n// Calculate the SHA256 hash of the input text.\n// Returns a promise that resolves to an ArrayBuffer\nfunction sha256(plain: string) {\n const encoder = new TextEncoder()\n const data = encoder.encode(plain)\n return window.crypto.subtle.digest('SHA-256', data)\n}\n\n// Base64-urlencodes the input string\nfunction base64urlencode(str: ArrayBuffer) {\n // Convert the ArrayBuffer to string using Uint8 array to conver to what btoa accepts.\n // btoa accepts chars only within ascii 0-255 and base64 encodes them.\n // Then convert the base64 encoded to base64url encoded\n // (replace + with -, replace / with _, trim trailing =)\n // @ts-expect-error\n return btoa(String.fromCharCode.apply(null, new Uint8Array(str)))\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '')\n}\n\n// Return the base64-urlencoded sha256 hash for the PKCE challenge\nasync function pkceChallengeFromVerifier(v: string) {\n const hashed = await sha256(v)\n return base64urlencode(hashed)\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { DEFAULT_MFA_SETTINGS, LoginAttemptResponse, MfaMethod, MfaSettings } from './AWSCognitoClient';
1
+ import { DEFAULT_MFA_SETTINGS, LoginAttemptResponse, LoggedInMfaMethod, MfaMethod, MfaSettings } from './AWSCognitoClient';
2
2
  import { MiscTypes } from '@oneblink/types';
3
3
  interface CognitoServiceData {
4
4
  oAuthClientId: string;
@@ -289,4 +289,4 @@ declare function setupMfaAuthenticatorApp(options?: {
289
289
  mfaCodeCallback: (code: string) => Promise<void>;
290
290
  } | undefined>;
291
291
  export { init, registerAuthListener, loginUsernamePassword, loginHostedUI, handleAuthentication, changePassword, forgotPassword, logoutHostedUI, logout, isLoggedIn, getCognitoIdToken, getUserProfile, getUserFriendlyName, getMfaSettings, updateUserPhoneNumber, removeUserPhoneNumber, verifyUserPhoneNumber, disableMfaMethod, setPreferredMfaMethod, setupSmsMfa, setupMfaAuthenticatorApp, generateMfaAuthenticatorAppQrCodeUrl, DEFAULT_MFA_SETTINGS, };
292
- export type { LoginAttemptResponse, MfaMethod, MfaSettings };
292
+ export type { LoginAttemptResponse, LoggedInMfaMethod, MfaMethod, MfaSettings };
@@ -1 +1 @@
1
- {"version":3,"file":"cognito.js","sourceRoot":"","sources":["../../../src/apps/services/cognito.ts"],"names":[],"mappings":"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","sourcesContent":["import { jwtDecode } from 'jwt-decode'\n\nimport AWSCognitoClient, {\n DEFAULT_MFA_SETTINGS,\n LoginAttemptResponse,\n MfaMethod,\n MfaSettings,\n} from './AWSCognitoClient'\n\nimport * as offlineService from '../offline-service'\nimport { userService } from '@oneblink/sdk-core'\nimport { MiscTypes } from '@oneblink/types'\nimport { HTTPError, postRequest } from './fetch'\nimport tenants from '../tenants'\nimport OneBlinkAppsError from './errors/oneBlinkAppsError'\n\ninterface CognitoServiceData {\n oAuthClientId: string\n loginDomain: string\n region: string\n redirectUri: string\n logoutUri: string\n}\n\nconst CONTINUE_TO = 'continueTo'\n\nlet awsCognitoClient: null | AWSCognitoClient = null\n\nfunction init(cognitoServiceData: CognitoServiceData) {\n console.log('Initiating CognitoIdentityServiceProvider', cognitoServiceData)\n\n awsCognitoClient = new AWSCognitoClient({\n clientId: cognitoServiceData.oAuthClientId,\n region: cognitoServiceData.region,\n loginDomain: cognitoServiceData.loginDomain,\n redirectUri: cognitoServiceData.redirectUri,\n logoutUri: cognitoServiceData.logoutUri,\n })\n}\n\n/**\n * Register a listener function that will be call when authentication tokens are\n * updated or removed.\n *\n * #### Example\n *\n * ```js\n * const listener = async () => {\n * // Check if the user is logged in still\n * const isLoggedIn = authService.isLoggedIn()\n * }\n * const deregister = await authService.registerAuthListener(listener)\n *\n * // When no longer needed, remember to deregister the listener\n * deregister()\n * ```\n *\n * @param listener\n * @returns\n */\nfunction registerAuthListener(listener: () => unknown): () => void {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to register a listener.',\n )\n }\n return awsCognitoClient.registerListener(listener)\n}\n\n/**\n * Create a session for a user by entering a username and password. If the user\n * requires a password reset, the \"resetPasswordCallback\" property will be\n * returned. This function should be called with the new password once entered\n * by the user. If the user requires an MFA token, the \"mfa\" property will be\n * returned. Its \"codeCallback\" should be called with the one-time token. The\n * functions returned are recursive and the result from each of them is the same\n * result from the loginUsernamePassword() function. Each time the response\n * includes a callback, you will need to begin the process again until all\n * callbacks are handled.\n *\n * #### Example\n *\n * ```js\n * async function handleLoginAttemptResponse({\n * resetPasswordCallback,\n * mfa,\n * }) {\n * // \"resetPasswordCallback\" will be undefined if a password reset was not required.\n * if (resetPasswordCallback) {\n * // Prompt the user to enter a new password\n * const newPassword = prompt(\n * 'The password you entered was only temporary, and must be reset for security purposes. Please enter your new password below to continue.',\n * )\n * const resetPasswordResponse =\n * await resetPasswordCallback(newPassword)\n * return await handleLoginAttemptResponse(resetPasswordResponse)\n * }\n *\n * // \"mfa\" will be undefined if MFA is not setup.\n * if (mfa) {\n * // Prompt the user to enter an MFA code\n * const code = prompt(\n * mfa.method === 'email'\n * ? 'Please enter the one-time code sent to your email.'\n * : 'Please enter a one-time code from your MFA app.',\n * )\n * const mfaCodeResponse = await mfa.codeCallback(code)\n * return await handleLoginAttemptResponse(mfaCodeResponse)\n * }\n * }\n *\n * const username = 'user@email.io'\n * const password = 'P@$5w0rd'\n *\n * const loginAttemptResponse = await authService.loginUsernamePassword(\n * username,\n * password,\n * )\n *\n * await handleLoginAttemptResponse(loginAttemptResponse)\n * ```\n *\n * @param username\n * @param password\n * @returns\n */\nasync function loginUsernamePassword(username: string, password: string) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to login.',\n )\n }\n console.log('Attempting sign using username', username)\n return awsCognitoClient.loginUsernamePassword(\n username.toLowerCase(),\n password,\n )\n}\n\n/**\n * Redirect the user to the login screen. Passing an `identityProvider` is\n * optionally, it will allow users to skip the login page and be directed\n * straight to that providers login page\n *\n * #### Example\n *\n * ```js\n * // OPtionally pass a\n * const identityProvider = 'Google'\n * await authService.loginHostedUI(identityProvider)\n * // User will be redirected to login page or promise will resolve\n * ```\n *\n * @param identityProviderName\n * @returns\n */\nasync function loginHostedUI(identityProviderName?: string): Promise<void> {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to login.',\n )\n }\n const continueTo = `${window.location.pathname}${window.location.search}`\n localStorage.setItem(CONTINUE_TO, continueTo)\n\n return awsCognitoClient.loginHostedUI(identityProviderName)\n}\n\n/**\n * This function should be called when the user is redirected back to your app\n * after a login attempt. It will use the query string add the redirect URL to\n * create a session for the current user. It will return a URL as a `string`\n * that should be redirected to within your app.\n *\n * #### Example\n *\n * ```js\n * try {\n * const continueTo = await authService.handleAuthentication()\n * // Redirect the user back to where they were before attempting to login\n * window.location.href = continueTo\n * } catch (error) {\n * // handle failed login attempts here.\n * }\n * ```\n *\n * @returns\n */\nasync function handleAuthentication(): Promise<string> {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to handle authentication in URL.',\n )\n }\n\n const continueTo = localStorage.getItem(CONTINUE_TO) || '/'\n if (isLoggedIn()) {\n console.log('Already authenticated, redirecting to:', continueTo)\n } else {\n await awsCognitoClient.handleAuthentication()\n }\n\n localStorage.removeItem(CONTINUE_TO)\n\n return continueTo\n}\n\n/**\n * Allow the currently logged in user to change their password by passing their\n * existing password and a new password.\n *\n * #### Example\n *\n * ```js\n * const currentPassword = 'P@$5w0rd'\n * const newPassword = 'P@$5w0rD'\n * await authService.changePassword(currentPassword, newPassword)\n * ```\n *\n * @param existingPassword\n * @param newPassword\n * @returns\n */\nasync function changePassword(existingPassword: string, newPassword: string) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to change passwords.',\n )\n }\n\n return await awsCognitoClient.changePassword(existingPassword, newPassword)\n}\n\n/**\n * Allow a user to start the forgot password process. The user will be emailed a\n * temporary code that must be passed with a new password to the function\n * returned.\n *\n * #### Example\n *\n * ```js\n * const username = 'user@email.io'\n * const finishForgotPassword = await authService.forgotPassword(username)\n *\n * // Prompt the user to enter the code and a new password\n * const code = prompt(\n * 'You have been emailed a verification code, please enter it here.',\n * )\n * const newPassword = prompt('Please enter a new password to continue.')\n * await finishForgotPassword(code, newPassword)\n * ```\n *\n * @param username\n * @param formsAppId Used to give the resulting email sent to the user\n * associated forms app branding and sending address\n * @returns\n */\nasync function forgotPassword(\n username: string,\n /**\n * Used to give the resulting email sent to the user associated forms app\n * branding and sending address\n */\n formsAppId?: number,\n): Promise<(code: string, password: string) => Promise<void>> {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before starting the forgot password process.',\n )\n }\n\n try {\n const url = `${tenants.current.apiOrigin}/authentication/reset-password`\n await postRequest(url, {\n username,\n formsAppId,\n })\n } catch (err) {\n const error = err as HTTPError\n switch (error.status) {\n case 400: {\n throw new OneBlinkAppsError(error.message, {\n title: 'Invalid Request',\n httpStatusCode: error.status,\n })\n }\n default: {\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error,\n httpStatusCode: error.status,\n },\n )\n }\n }\n }\n\n return async (code, password) => {\n await awsCognitoClient?.confirmForgotPassword({\n username,\n code,\n password,\n })\n }\n}\n\n/**\n * Redirect the user to the logout screen to clear the users session on the\n * hosted login page. User will then be redirected to `/logout`. After being\n * redirected back to the application, the `logout()` function should be called\n * to clear the session data from browser storage.\n *\n * #### Example\n *\n * ```js\n * authService.logoutHostedUI()\n * ```\n */\nfunction logoutHostedUI(): void {\n if (awsCognitoClient) {\n awsCognitoClient.logoutHostedUI()\n }\n}\n\nasync function logout() {\n if (awsCognitoClient) {\n await awsCognitoClient.logout()\n }\n}\n\n/**\n * Check if the user is currently logged in\n *\n * #### Example\n *\n * ```js\n * const isLoggedIn = authService.isLoggedIn()\n * // handle user being logged in or not\n * ```\n *\n * @returns\n */\nfunction isLoggedIn(): boolean {\n return !!(awsCognitoClient && awsCognitoClient._getRefreshToken())\n}\n\nasync function getCognitoIdToken(): Promise<string | undefined> {\n if (!awsCognitoClient) {\n return\n }\n\n if (offlineService.isOffline()) {\n return awsCognitoClient._getIdToken()\n }\n\n return await awsCognitoClient.getIdToken()\n}\n\n/**\n * Get current users profile based on there Id Token payload. This will return\n * `null` if the the current user is not logged in.\n *\n * #### Example\n *\n * ```js\n * const profile = authService.getUserProfile()\n * if (profile) {\n * // Use profile here\n * }\n * ```\n *\n * @returns\n */\nfunction getUserProfile(): MiscTypes.UserProfile | null {\n if (!awsCognitoClient) {\n return null\n }\n const idToken = awsCognitoClient._getIdToken()\n if (!idToken) {\n return null\n }\n\n const jwtToken = jwtDecode(idToken)\n return userService.parseUserProfile(jwtToken) || null\n}\n\nexport function getUsername(): string | undefined {\n const profile = getUserProfile()\n if (!profile) {\n return undefined\n }\n\n return profile.username\n}\n\n/**\n * A friendly `string` that represents the current user. Uses first name, last\n * name, full name and username. This will return `null` the current user is not\n * logged in.\n *\n * #### Example\n *\n * ```js\n * const name = authService.getUserFriendlyName()\n * if (name) {\n * // Display current user's name\n * }\n * ```\n *\n * @returns\n */\nfunction getUserFriendlyName(): string | undefined {\n const profile = getUserProfile()\n if (!profile) {\n return\n }\n\n return userService.getUserFriendlyName(profile)\n}\n\n/**\n * Generate a QR code link to display to a user after they have initiated\n * authenticator app MFA setup.\n *\n * #### Example\n *\n * ```js\n * const mfaAuthenticatorAppSetupQrCodeUrl =\n * mfaService.generateMfaAuthenticatorAppQrCodeUrl()\n * if (mfaAuthenticatorAppSetupQrCodeUrl) {\n * // use mfaAuthenticatorAppSetupQrCodeUrl to display QR code to user\n * }\n * ```\n *\n * @returns\n */\nfunction generateMfaAuthenticatorAppQrCodeUrl(\n mfaAuthenticatorAppSetup: Awaited<\n ReturnType<typeof setupMfaAuthenticatorApp>\n >,\n): string | undefined {\n const profile = getUserProfile()\n if (!profile || !mfaAuthenticatorAppSetup) {\n return\n }\n\n return `otpauth://totp/${tenants.current.productShortName}:${profile.email}?secret=${mfaAuthenticatorAppSetup.secretCode}&issuer=${tenants.current.productShortName}`\n}\n\nasync function getMfaSettings(abortSignal?: AbortSignal) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before checking MFA settings.',\n )\n }\n\n return await awsCognitoClient.getMfaSettings(abortSignal)\n}\n\nasync function updateUserPhoneNumber(phoneNumber: string) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before updating the user phone number.',\n )\n }\n\n return await awsCognitoClient.updateUserPhoneNumber(phoneNumber)\n}\n\nasync function removeUserPhoneNumber() {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before removing the user phone number.',\n )\n }\n\n return await awsCognitoClient.removeUserPhoneNumber()\n}\n\nasync function verifyUserPhoneNumber(code: string) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before verifying the user phone number.',\n )\n }\n\n return await awsCognitoClient.verifyUserPhoneNumber(code)\n}\n\nasync function setupSmsMfa(options?: { preferred?: boolean }) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to setup SMS MFA.',\n )\n }\n\n return await awsCognitoClient.setupSmsMfa(options)\n}\n\nasync function disableMfaMethod(method: MfaMethod) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to disable an MFA method.',\n )\n }\n\n return await awsCognitoClient.disableMfaMethod(method)\n}\n\nasync function setPreferredMfaMethod(method: MfaMethod) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to set the preferred MFA method.',\n )\n }\n\n return await awsCognitoClient.setPreferredMfaMethod(method)\n}\n\n/**\n * Setup authenticator app MFA for the current user. The result will include a\n * callback that should be called with the valid TOTP from an authenticator\n * app.\n *\n * #### Example\n *\n * ```js\n * const { secretCode, mfaCodeCallback } =\n * await mfaService.setupMfaAuthenticatorApp()\n * // Prompt the user to enter an MFA code\n * const code = prompt(\n * `Please enter a one-time code from your MFA app after creating a new entry with secret: ${secretCode}.`,\n * )\n * await mfaCodeCallback(code)\n * ```\n *\n * @returns\n */\nasync function setupMfaAuthenticatorApp(options?: { preferred?: boolean }) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to setup authenticator app MFA.',\n )\n }\n\n return await awsCognitoClient.setupMfaAuthenticatorApp(options)\n}\n\nexport {\n init,\n registerAuthListener,\n loginUsernamePassword,\n loginHostedUI,\n handleAuthentication,\n changePassword,\n forgotPassword,\n logoutHostedUI,\n logout,\n isLoggedIn,\n getCognitoIdToken,\n getUserProfile,\n getUserFriendlyName,\n getMfaSettings,\n updateUserPhoneNumber,\n removeUserPhoneNumber,\n verifyUserPhoneNumber,\n disableMfaMethod,\n setPreferredMfaMethod,\n setupSmsMfa,\n setupMfaAuthenticatorApp,\n generateMfaAuthenticatorAppQrCodeUrl,\n DEFAULT_MFA_SETTINGS,\n}\nexport type { LoginAttemptResponse, MfaMethod, MfaSettings }\n"]}
1
+ {"version":3,"file":"cognito.js","sourceRoot":"","sources":["../../../src/apps/services/cognito.ts"],"names":[],"mappings":"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","sourcesContent":["import { jwtDecode } from 'jwt-decode'\n\nimport AWSCognitoClient, {\n DEFAULT_MFA_SETTINGS,\n LoginAttemptResponse,\n LoggedInMfaMethod,\n MfaMethod,\n MfaSettings,\n} from './AWSCognitoClient'\n\nimport * as offlineService from '../offline-service'\nimport { userService } from '@oneblink/sdk-core'\nimport { MiscTypes } from '@oneblink/types'\nimport { HTTPError, postRequest } from './fetch'\nimport tenants from '../tenants'\nimport OneBlinkAppsError from './errors/oneBlinkAppsError'\n\ninterface CognitoServiceData {\n oAuthClientId: string\n loginDomain: string\n region: string\n redirectUri: string\n logoutUri: string\n}\n\nconst CONTINUE_TO = 'continueTo'\n\nlet awsCognitoClient: null | AWSCognitoClient = null\n\nfunction init(cognitoServiceData: CognitoServiceData) {\n console.log('Initiating CognitoIdentityServiceProvider', cognitoServiceData)\n\n awsCognitoClient = new AWSCognitoClient({\n clientId: cognitoServiceData.oAuthClientId,\n region: cognitoServiceData.region,\n loginDomain: cognitoServiceData.loginDomain,\n redirectUri: cognitoServiceData.redirectUri,\n logoutUri: cognitoServiceData.logoutUri,\n })\n}\n\n/**\n * Register a listener function that will be call when authentication tokens are\n * updated or removed.\n *\n * #### Example\n *\n * ```js\n * const listener = async () => {\n * // Check if the user is logged in still\n * const isLoggedIn = authService.isLoggedIn()\n * }\n * const deregister = await authService.registerAuthListener(listener)\n *\n * // When no longer needed, remember to deregister the listener\n * deregister()\n * ```\n *\n * @param listener\n * @returns\n */\nfunction registerAuthListener(listener: () => unknown): () => void {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to register a listener.',\n )\n }\n return awsCognitoClient.registerListener(listener)\n}\n\n/**\n * Create a session for a user by entering a username and password. If the user\n * requires a password reset, the \"resetPasswordCallback\" property will be\n * returned. This function should be called with the new password once entered\n * by the user. If the user requires an MFA token, the \"mfa\" property will be\n * returned. Its \"codeCallback\" should be called with the one-time token. The\n * functions returned are recursive and the result from each of them is the same\n * result from the loginUsernamePassword() function. Each time the response\n * includes a callback, you will need to begin the process again until all\n * callbacks are handled.\n *\n * #### Example\n *\n * ```js\n * async function handleLoginAttemptResponse({\n * resetPasswordCallback,\n * mfa,\n * }) {\n * // \"resetPasswordCallback\" will be undefined if a password reset was not required.\n * if (resetPasswordCallback) {\n * // Prompt the user to enter a new password\n * const newPassword = prompt(\n * 'The password you entered was only temporary, and must be reset for security purposes. Please enter your new password below to continue.',\n * )\n * const resetPasswordResponse =\n * await resetPasswordCallback(newPassword)\n * return await handleLoginAttemptResponse(resetPasswordResponse)\n * }\n *\n * // \"mfa\" will be undefined if MFA is not setup.\n * if (mfa) {\n * // Prompt the user to enter an MFA code\n * const code = prompt(\n * mfa.method === 'email'\n * ? 'Please enter the one-time code sent to your email.'\n * : 'Please enter a one-time code from your MFA app.',\n * )\n * const mfaCodeResponse = await mfa.codeCallback(code)\n * return await handleLoginAttemptResponse(mfaCodeResponse)\n * }\n * }\n *\n * const username = 'user@email.io'\n * const password = 'P@$5w0rd'\n *\n * const loginAttemptResponse = await authService.loginUsernamePassword(\n * username,\n * password,\n * )\n *\n * await handleLoginAttemptResponse(loginAttemptResponse)\n * ```\n *\n * @param username\n * @param password\n * @returns\n */\nasync function loginUsernamePassword(username: string, password: string) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to login.',\n )\n }\n console.log('Attempting sign using username', username)\n return awsCognitoClient.loginUsernamePassword(\n username.toLowerCase(),\n password,\n )\n}\n\n/**\n * Redirect the user to the login screen. Passing an `identityProvider` is\n * optionally, it will allow users to skip the login page and be directed\n * straight to that providers login page\n *\n * #### Example\n *\n * ```js\n * // OPtionally pass a\n * const identityProvider = 'Google'\n * await authService.loginHostedUI(identityProvider)\n * // User will be redirected to login page or promise will resolve\n * ```\n *\n * @param identityProviderName\n * @returns\n */\nasync function loginHostedUI(identityProviderName?: string): Promise<void> {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to login.',\n )\n }\n const continueTo = `${window.location.pathname}${window.location.search}`\n localStorage.setItem(CONTINUE_TO, continueTo)\n\n return awsCognitoClient.loginHostedUI(identityProviderName)\n}\n\n/**\n * This function should be called when the user is redirected back to your app\n * after a login attempt. It will use the query string add the redirect URL to\n * create a session for the current user. It will return a URL as a `string`\n * that should be redirected to within your app.\n *\n * #### Example\n *\n * ```js\n * try {\n * const continueTo = await authService.handleAuthentication()\n * // Redirect the user back to where they were before attempting to login\n * window.location.href = continueTo\n * } catch (error) {\n * // handle failed login attempts here.\n * }\n * ```\n *\n * @returns\n */\nasync function handleAuthentication(): Promise<string> {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to handle authentication in URL.',\n )\n }\n\n const continueTo = localStorage.getItem(CONTINUE_TO) || '/'\n if (isLoggedIn()) {\n console.log('Already authenticated, redirecting to:', continueTo)\n } else {\n await awsCognitoClient.handleAuthentication()\n }\n\n localStorage.removeItem(CONTINUE_TO)\n\n return continueTo\n}\n\n/**\n * Allow the currently logged in user to change their password by passing their\n * existing password and a new password.\n *\n * #### Example\n *\n * ```js\n * const currentPassword = 'P@$5w0rd'\n * const newPassword = 'P@$5w0rD'\n * await authService.changePassword(currentPassword, newPassword)\n * ```\n *\n * @param existingPassword\n * @param newPassword\n * @returns\n */\nasync function changePassword(existingPassword: string, newPassword: string) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to change passwords.',\n )\n }\n\n return await awsCognitoClient.changePassword(existingPassword, newPassword)\n}\n\n/**\n * Allow a user to start the forgot password process. The user will be emailed a\n * temporary code that must be passed with a new password to the function\n * returned.\n *\n * #### Example\n *\n * ```js\n * const username = 'user@email.io'\n * const finishForgotPassword = await authService.forgotPassword(username)\n *\n * // Prompt the user to enter the code and a new password\n * const code = prompt(\n * 'You have been emailed a verification code, please enter it here.',\n * )\n * const newPassword = prompt('Please enter a new password to continue.')\n * await finishForgotPassword(code, newPassword)\n * ```\n *\n * @param username\n * @param formsAppId Used to give the resulting email sent to the user\n * associated forms app branding and sending address\n * @returns\n */\nasync function forgotPassword(\n username: string,\n /**\n * Used to give the resulting email sent to the user associated forms app\n * branding and sending address\n */\n formsAppId?: number,\n): Promise<(code: string, password: string) => Promise<void>> {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before starting the forgot password process.',\n )\n }\n\n try {\n const url = `${tenants.current.apiOrigin}/authentication/reset-password`\n await postRequest(url, {\n username,\n formsAppId,\n })\n } catch (err) {\n const error = err as HTTPError\n switch (error.status) {\n case 400: {\n throw new OneBlinkAppsError(error.message, {\n title: 'Invalid Request',\n httpStatusCode: error.status,\n })\n }\n default: {\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error,\n httpStatusCode: error.status,\n },\n )\n }\n }\n }\n\n return async (code, password) => {\n await awsCognitoClient?.confirmForgotPassword({\n username,\n code,\n password,\n })\n }\n}\n\n/**\n * Redirect the user to the logout screen to clear the users session on the\n * hosted login page. User will then be redirected to `/logout`. After being\n * redirected back to the application, the `logout()` function should be called\n * to clear the session data from browser storage.\n *\n * #### Example\n *\n * ```js\n * authService.logoutHostedUI()\n * ```\n */\nfunction logoutHostedUI(): void {\n if (awsCognitoClient) {\n awsCognitoClient.logoutHostedUI()\n }\n}\n\nasync function logout() {\n if (awsCognitoClient) {\n await awsCognitoClient.logout()\n }\n}\n\n/**\n * Check if the user is currently logged in\n *\n * #### Example\n *\n * ```js\n * const isLoggedIn = authService.isLoggedIn()\n * // handle user being logged in or not\n * ```\n *\n * @returns\n */\nfunction isLoggedIn(): boolean {\n return !!(awsCognitoClient && awsCognitoClient._getRefreshToken())\n}\n\nasync function getCognitoIdToken(): Promise<string | undefined> {\n if (!awsCognitoClient) {\n return\n }\n\n if (offlineService.isOffline()) {\n return awsCognitoClient._getIdToken()\n }\n\n return await awsCognitoClient.getIdToken()\n}\n\n/**\n * Get current users profile based on there Id Token payload. This will return\n * `null` if the the current user is not logged in.\n *\n * #### Example\n *\n * ```js\n * const profile = authService.getUserProfile()\n * if (profile) {\n * // Use profile here\n * }\n * ```\n *\n * @returns\n */\nfunction getUserProfile(): MiscTypes.UserProfile | null {\n if (!awsCognitoClient) {\n return null\n }\n const idToken = awsCognitoClient._getIdToken()\n if (!idToken) {\n return null\n }\n\n const jwtToken = jwtDecode(idToken)\n return userService.parseUserProfile(jwtToken) || null\n}\n\nexport function getUsername(): string | undefined {\n const profile = getUserProfile()\n if (!profile) {\n return undefined\n }\n\n return profile.username\n}\n\n/**\n * A friendly `string` that represents the current user. Uses first name, last\n * name, full name and username. This will return `null` the current user is not\n * logged in.\n *\n * #### Example\n *\n * ```js\n * const name = authService.getUserFriendlyName()\n * if (name) {\n * // Display current user's name\n * }\n * ```\n *\n * @returns\n */\nfunction getUserFriendlyName(): string | undefined {\n const profile = getUserProfile()\n if (!profile) {\n return\n }\n\n return userService.getUserFriendlyName(profile)\n}\n\n/**\n * Generate a QR code link to display to a user after they have initiated\n * authenticator app MFA setup.\n *\n * #### Example\n *\n * ```js\n * const mfaAuthenticatorAppSetupQrCodeUrl =\n * mfaService.generateMfaAuthenticatorAppQrCodeUrl()\n * if (mfaAuthenticatorAppSetupQrCodeUrl) {\n * // use mfaAuthenticatorAppSetupQrCodeUrl to display QR code to user\n * }\n * ```\n *\n * @returns\n */\nfunction generateMfaAuthenticatorAppQrCodeUrl(\n mfaAuthenticatorAppSetup: Awaited<\n ReturnType<typeof setupMfaAuthenticatorApp>\n >,\n): string | undefined {\n const profile = getUserProfile()\n if (!profile || !mfaAuthenticatorAppSetup) {\n return\n }\n\n return `otpauth://totp/${tenants.current.productShortName}:${profile.email}?secret=${mfaAuthenticatorAppSetup.secretCode}&issuer=${tenants.current.productShortName}`\n}\n\nasync function getMfaSettings(abortSignal?: AbortSignal) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before checking MFA settings.',\n )\n }\n\n return await awsCognitoClient.getMfaSettings(abortSignal)\n}\n\nasync function updateUserPhoneNumber(phoneNumber: string) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before updating the user phone number.',\n )\n }\n\n return await awsCognitoClient.updateUserPhoneNumber(phoneNumber)\n}\n\nasync function removeUserPhoneNumber() {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before removing the user phone number.',\n )\n }\n\n return await awsCognitoClient.removeUserPhoneNumber()\n}\n\nasync function verifyUserPhoneNumber(code: string) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before verifying the user phone number.',\n )\n }\n\n return await awsCognitoClient.verifyUserPhoneNumber(code)\n}\n\nasync function setupSmsMfa(options?: { preferred?: boolean }) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to setup SMS MFA.',\n )\n }\n\n return await awsCognitoClient.setupSmsMfa(options)\n}\n\nasync function disableMfaMethod(method: MfaMethod) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to disable an MFA method.',\n )\n }\n\n return await awsCognitoClient.disableMfaMethod(method)\n}\n\nasync function setPreferredMfaMethod(method: MfaMethod) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to set the preferred MFA method.',\n )\n }\n\n return await awsCognitoClient.setPreferredMfaMethod(method)\n}\n\n/**\n * Setup authenticator app MFA for the current user. The result will include a\n * callback that should be called with the valid TOTP from an authenticator\n * app.\n *\n * #### Example\n *\n * ```js\n * const { secretCode, mfaCodeCallback } =\n * await mfaService.setupMfaAuthenticatorApp()\n * // Prompt the user to enter an MFA code\n * const code = prompt(\n * `Please enter a one-time code from your MFA app after creating a new entry with secret: ${secretCode}.`,\n * )\n * await mfaCodeCallback(code)\n * ```\n *\n * @returns\n */\nasync function setupMfaAuthenticatorApp(options?: { preferred?: boolean }) {\n if (!awsCognitoClient) {\n throw new Error(\n '\"authService\" has not been initiated. You must call the init() function before attempting to setup authenticator app MFA.',\n )\n }\n\n return await awsCognitoClient.setupMfaAuthenticatorApp(options)\n}\n\nexport {\n init,\n registerAuthListener,\n loginUsernamePassword,\n loginHostedUI,\n handleAuthentication,\n changePassword,\n forgotPassword,\n logoutHostedUI,\n logout,\n isLoggedIn,\n getCognitoIdToken,\n getUserProfile,\n getUserFriendlyName,\n getMfaSettings,\n updateUserPhoneNumber,\n removeUserPhoneNumber,\n verifyUserPhoneNumber,\n disableMfaMethod,\n setPreferredMfaMethod,\n setupSmsMfa,\n setupMfaAuthenticatorApp,\n generateMfaAuthenticatorAppQrCodeUrl,\n DEFAULT_MFA_SETTINGS,\n}\nexport type { LoginAttemptResponse, LoggedInMfaMethod, MfaMethod, MfaSettings }\n"]}
@@ -1,6 +1,7 @@
1
1
  type Props = {
2
2
  isEnabled: boolean;
3
3
  isPreferred: boolean;
4
+ isUsedForLogin: boolean;
4
5
  isSettingUp: boolean;
5
6
  isSettingPreferredMfaMethod: boolean;
6
7
  isSetupDisabled: boolean;
@@ -9,12 +10,13 @@ type Props = {
9
10
  description: string;
10
11
  detail?: string;
11
12
  mfaRequirementMessage?: string;
13
+ mfaRequirementMessageIsWarning?: boolean;
12
14
  cypressPrefix: string;
13
15
  extraButtons?: React.ReactNode;
14
16
  onSetup: () => void;
15
17
  onDisable: () => void;
16
18
  onSetPreferred: () => void;
17
19
  };
18
- declare function MfaMethodRow({ isEnabled, isPreferred, isSettingUp, isSettingPreferredMfaMethod, isSetupDisabled, showSetupErrorTooltip, title, description, detail, mfaRequirementMessage, cypressPrefix, extraButtons, onSetup, onDisable, onSetPreferred, }: Props): import("react/jsx-runtime").JSX.Element;
20
+ declare function MfaMethodRow({ isEnabled, isPreferred, isUsedForLogin, isSettingUp, isSettingPreferredMfaMethod, isSetupDisabled, showSetupErrorTooltip, title, description, detail, mfaRequirementMessage, mfaRequirementMessageIsWarning, cypressPrefix, extraButtons, onSetup, onDisable, onSetPreferred, }: Props): import("react/jsx-runtime").JSX.Element;
19
21
  declare const _default: import("react").MemoExoticComponent<typeof MfaMethodRow>;
20
22
  export default _default;
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { memo } from 'react';
3
3
  import { Alert, Box, Button, Chip, Grid, Tooltip, Typography, } from '@mui/material';
4
- function MfaMethodRow({ isEnabled, isPreferred, isSettingUp, isSettingPreferredMfaMethod, isSetupDisabled, showSetupErrorTooltip, title, description, detail, mfaRequirementMessage, cypressPrefix, extraButtons, onSetup, onDisable, onSetPreferred, }) {
5
- return (_jsx(Box, { "data-cypress": `${cypressPrefix}-method-row`, children: _jsxs(Grid, { container: true, spacing: 2, alignItems: "center", children: [_jsxs(Grid, { size: { xs: 'grow' }, children: [_jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Typography, { variant: "subtitle1", component: "span", children: title }), isEnabled && (_jsx(Chip, { size: "small", label: "Enabled", color: "info", sx: { ml: 1 }, "data-cypress": `${cypressPrefix}-status-chip` })), isPreferred && (_jsx(Chip, { size: "small", label: "Preferred", color: "success", sx: { ml: 1 }, "data-cypress": `${cypressPrefix}-preferred-chip` }))] }), _jsx(Typography, { variant: "body2", color: "text.secondary", children: description }), !!detail && (_jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mt: 1 }, children: detail })), !!mfaRequirementMessage && (_jsx(Alert, { severity: isEnabled && isPreferred ? 'warning' : 'info', sx: { mt: 1 }, "data-cypress": `${cypressPrefix}-mfa-requirement-message`, children: mfaRequirementMessage }))] }), _jsx(Grid, { size: "auto", children: _jsxs(Box, { display: "flex", gap: 1, flexWrap: "wrap", justifyContent: "flex-end", children: [extraButtons, isEnabled ? (_jsxs(_Fragment, { children: [!isPreferred && (_jsx(Button, { size: "small", variant: "outlined", loading: isSettingPreferredMfaMethod, disabled: isSettingPreferredMfaMethod, onClick: onSetPreferred, "data-cypress": `${cypressPrefix}-set-preferred-button`, children: "Set as Preferred" })), _jsx(Button, { size: "small", variant: "outlined", onClick: onDisable, "data-cypress": `${cypressPrefix}-disable-button`, children: "Disable" })] })) : (_jsx(Tooltip, { title: showSetupErrorTooltip
6
- ? 'We are unable to load your MFA status. Please try again by clicking the reload button on the chip above.'
7
- : '', children: _jsx("span", { children: _jsx(Button, { size: "small", variant: "contained", loading: isSettingUp, disabled: isSetupDisabled, onClick: onSetup, "data-cypress": `${cypressPrefix}-setup-button`, children: "Setup" }) }) }))] }) })] }) }));
4
+ function MfaMethodRow({ isEnabled, isPreferred, isUsedForLogin, isSettingUp, isSettingPreferredMfaMethod, isSetupDisabled, showSetupErrorTooltip, title, description, detail, mfaRequirementMessage, mfaRequirementMessageIsWarning, cypressPrefix, extraButtons, onSetup, onDisable, onSetPreferred, }) {
5
+ return (_jsxs(Box, { "data-cypress": `${cypressPrefix}-method-row`, children: [_jsxs(Grid, { container: true, spacing: 2, alignItems: "center", children: [_jsxs(Grid, { size: { xs: 'grow' }, children: [_jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Typography, { variant: "subtitle1", component: "span", children: title }), isEnabled && (_jsx(Chip, { size: "small", label: "Enabled", color: "default", sx: { ml: 1 }, "data-cypress": `${cypressPrefix}-status-chip` })), isPreferred && (_jsx(Chip, { size: "small", label: "Preferred", color: "info", sx: { ml: 1 }, "data-cypress": `${cypressPrefix}-preferred-chip` })), isUsedForLogin && (_jsx(Chip, { size: "small", label: "Used for login", color: "success", sx: { ml: 1 }, "data-cypress": `${cypressPrefix}-used-for-login-chip` }))] }), _jsx(Typography, { variant: "body2", color: "text.secondary", children: description }), !!detail && (_jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mt: 1 }, children: detail }))] }), _jsx(Grid, { size: "auto", children: _jsxs(Box, { display: "flex", gap: 1, flexWrap: "wrap", justifyContent: "flex-end", children: [extraButtons, isEnabled ? (_jsxs(_Fragment, { children: [!isPreferred && (_jsx(Button, { size: "small", variant: "outlined", loading: isSettingPreferredMfaMethod, disabled: isSettingPreferredMfaMethod, onClick: onSetPreferred, "data-cypress": `${cypressPrefix}-set-preferred-button`, children: "Set as Preferred" })), _jsx(Button, { size: "small", variant: "outlined", onClick: onDisable, "data-cypress": `${cypressPrefix}-disable-button`, children: "Disable" })] })) : (_jsx(Tooltip, { title: showSetupErrorTooltip
6
+ ? 'We are unable to load your MFA status. Please try again by clicking the reload button on the chip above.'
7
+ : '', children: _jsx("span", { children: _jsx(Button, { size: "small", variant: "contained", loading: isSettingUp, disabled: isSetupDisabled, onClick: onSetup, "data-cypress": `${cypressPrefix}-setup-button`, children: "Setup" }) }) }))] }) })] }), !!mfaRequirementMessage && (_jsx(Alert, { severity: mfaRequirementMessageIsWarning ? 'warning' : 'info', "data-cypress": `${cypressPrefix}-mfa-requirement-message`, children: mfaRequirementMessage }))] }));
8
8
  }
9
9
  export default memo(MfaMethodRow);
10
10
  //# sourceMappingURL=MfaMethodRow.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MfaMethodRow.js","sourceRoot":"","sources":["../../../src/components/mfa/MfaMethodRow.tsx"],"names":[],"mappings":"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","sourcesContent":["import { memo } from 'react'\nimport {\n Alert,\n Box,\n Button,\n Chip,\n Grid,\n Tooltip,\n Typography,\n} from '@mui/material'\n\ntype Props = {\n isEnabled: boolean\n isPreferred: boolean\n isSettingUp: boolean\n isSettingPreferredMfaMethod: boolean\n isSetupDisabled: boolean\n showSetupErrorTooltip?: boolean\n title: string\n description: string\n detail?: string\n mfaRequirementMessage?: string\n cypressPrefix: string\n extraButtons?: React.ReactNode\n onSetup: () => void\n onDisable: () => void\n onSetPreferred: () => void\n}\n\nfunction MfaMethodRow({\n isEnabled,\n isPreferred,\n isSettingUp,\n isSettingPreferredMfaMethod,\n isSetupDisabled,\n showSetupErrorTooltip,\n title,\n description,\n detail,\n mfaRequirementMessage,\n cypressPrefix,\n extraButtons,\n onSetup,\n onDisable,\n onSetPreferred,\n}: Props) {\n return (\n <Box data-cypress={`${cypressPrefix}-method-row`}>\n <Grid container spacing={2} alignItems=\"center\">\n <Grid size={{ xs: 'grow' }}>\n <Box sx={{ mb: 1 }}>\n <Typography variant=\"subtitle1\" component=\"span\">\n {title}\n </Typography>\n {isEnabled && (\n <Chip\n size=\"small\"\n label=\"Enabled\"\n color=\"info\"\n sx={{ ml: 1 }}\n data-cypress={`${cypressPrefix}-status-chip`}\n />\n )}\n {isPreferred && (\n <Chip\n size=\"small\"\n label=\"Preferred\"\n color=\"success\"\n sx={{ ml: 1 }}\n data-cypress={`${cypressPrefix}-preferred-chip`}\n />\n )}\n </Box>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {description}\n </Typography>\n {!!detail && (\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 1 }}>\n {detail}\n </Typography>\n )}\n {!!mfaRequirementMessage && (\n <Alert\n severity={isEnabled && isPreferred ? 'warning' : 'info'}\n sx={{ mt: 1 }}\n data-cypress={`${cypressPrefix}-mfa-requirement-message`}\n >\n {mfaRequirementMessage}\n </Alert>\n )}\n </Grid>\n <Grid size=\"auto\">\n <Box display=\"flex\" gap={1} flexWrap=\"wrap\" justifyContent=\"flex-end\">\n {extraButtons}\n {isEnabled ? (\n <>\n {!isPreferred && (\n <Button\n size=\"small\"\n variant=\"outlined\"\n loading={isSettingPreferredMfaMethod}\n disabled={isSettingPreferredMfaMethod}\n onClick={onSetPreferred}\n data-cypress={`${cypressPrefix}-set-preferred-button`}\n >\n Set as Preferred\n </Button>\n )}\n <Button\n size=\"small\"\n variant=\"outlined\"\n onClick={onDisable}\n data-cypress={`${cypressPrefix}-disable-button`}\n >\n Disable\n </Button>\n </>\n ) : (\n <Tooltip\n title={\n showSetupErrorTooltip\n ? 'We are unable to load your MFA status. Please try again by clicking the reload button on the chip above.'\n : ''\n }\n >\n <span>\n <Button\n size=\"small\"\n variant=\"contained\"\n loading={isSettingUp}\n disabled={isSetupDisabled}\n onClick={onSetup}\n data-cypress={`${cypressPrefix}-setup-button`}\n >\n Setup\n </Button>\n </span>\n </Tooltip>\n )}\n </Box>\n </Grid>\n </Grid>\n </Box>\n )\n}\n\nexport default memo(MfaMethodRow)\n"]}
1
+ {"version":3,"file":"MfaMethodRow.js","sourceRoot":"","sources":["../../../src/components/mfa/MfaMethodRow.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAC5B,OAAO,EACL,KAAK,EACL,GAAG,EACH,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,OAAO,EACP,UAAU,GACX,MAAM,eAAe,CAAA;AAsBtB,SAAS,YAAY,CAAC,EACpB,SAAS,EACT,WAAW,EACX,cAAc,EACd,WAAW,EACX,2BAA2B,EAC3B,eAAe,EACf,qBAAqB,EACrB,KAAK,EACL,WAAW,EACX,MAAM,EACN,qBAAqB,EACrB,8BAA8B,EAC9B,aAAa,EACb,YAAY,EACZ,OAAO,EACP,SAAS,EACT,cAAc,GACR;IACN,OAAO,CACL,MAAC,GAAG,oBAAe,GAAG,aAAa,aAAa,aAC9C,MAAC,IAAI,IAAC,SAAS,QAAC,OAAO,EAAE,CAAC,EAAE,UAAU,EAAC,QAAQ,aAC7C,MAAC,IAAI,IAAC,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,aACxB,MAAC,GAAG,IAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,aAChB,KAAC,UAAU,IAAC,OAAO,EAAC,WAAW,EAAC,SAAS,EAAC,MAAM,YAC7C,KAAK,GACK,EACZ,SAAS,IAAI,CACZ,KAAC,IAAI,IACH,IAAI,EAAC,OAAO,EACZ,KAAK,EAAC,SAAS,EACf,KAAK,EAAC,SAAS,EACf,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,kBACC,GAAG,aAAa,cAAc,GAC5C,CACH,EACA,WAAW,IAAI,CACd,KAAC,IAAI,IACH,IAAI,EAAC,OAAO,EACZ,KAAK,EAAC,WAAW,EACjB,KAAK,EAAC,MAAM,EACZ,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,kBACC,GAAG,aAAa,iBAAiB,GAC/C,CACH,EACA,cAAc,IAAI,CACjB,KAAC,IAAI,IACH,IAAI,EAAC,OAAO,EACZ,KAAK,EAAC,gBAAgB,EACtB,KAAK,EAAC,SAAS,EACf,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,kBACC,GAAG,aAAa,sBAAsB,GACpD,CACH,IACG,EACN,KAAC,UAAU,IAAC,OAAO,EAAC,OAAO,EAAC,KAAK,EAAC,gBAAgB,YAC/C,WAAW,GACD,EACZ,CAAC,CAAC,MAAM,IAAI,CACX,KAAC,UAAU,IAAC,OAAO,EAAC,OAAO,EAAC,KAAK,EAAC,gBAAgB,EAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,YAC7D,MAAM,GACI,CACd,IACI,EACP,KAAC,IAAI,IAAC,IAAI,EAAC,MAAM,YACf,MAAC,GAAG,IAAC,OAAO,EAAC,MAAM,EAAC,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAC,MAAM,EAAC,cAAc,EAAC,UAAU,aAClE,YAAY,EACZ,SAAS,CAAC,CAAC,CAAC,CACX,8BACG,CAAC,WAAW,IAAI,CACf,KAAC,MAAM,IACL,IAAI,EAAC,OAAO,EACZ,OAAO,EAAC,UAAU,EAClB,OAAO,EAAE,2BAA2B,EACpC,QAAQ,EAAE,2BAA2B,EACrC,OAAO,EAAE,cAAc,kBACT,GAAG,aAAa,uBAAuB,iCAG9C,CACV,EACD,KAAC,MAAM,IACL,IAAI,EAAC,OAAO,EACZ,OAAO,EAAC,UAAU,EAClB,OAAO,EAAE,SAAS,kBACJ,GAAG,aAAa,iBAAiB,wBAGxC,IACR,CACJ,CAAC,CAAC,CAAC,CACF,KAAC,OAAO,IACN,KAAK,EACH,qBAAqB;wCACnB,CAAC,CAAC,0GAA0G;wCAC5G,CAAC,CAAC,EAAE,YAGR,yBACE,KAAC,MAAM,IACL,IAAI,EAAC,OAAO,EACZ,OAAO,EAAC,WAAW,EACnB,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,eAAe,EACzB,OAAO,EAAE,OAAO,kBACF,GAAG,aAAa,eAAe,sBAGtC,GACJ,GACC,CACX,IACG,GACD,IACF,EAEN,CAAC,CAAC,qBAAqB,IAAI,CAC1B,KAAC,KAAK,IACJ,QAAQ,EAAE,8BAA8B,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,kBAC/C,GAAG,aAAa,0BAA0B,YAEvD,qBAAqB,GAChB,CACT,IACG,CACP,CAAA;AACH,CAAC;AAED,eAAe,IAAI,CAAC,YAAY,CAAC,CAAA","sourcesContent":["import { memo } from 'react'\nimport {\n Alert,\n Box,\n Button,\n Chip,\n Grid,\n Tooltip,\n Typography,\n} from '@mui/material'\n\ntype Props = {\n isEnabled: boolean\n isPreferred: boolean\n isUsedForLogin: boolean\n isSettingUp: boolean\n isSettingPreferredMfaMethod: boolean\n isSetupDisabled: boolean\n showSetupErrorTooltip?: boolean\n title: string\n description: string\n detail?: string\n mfaRequirementMessage?: string\n mfaRequirementMessageIsWarning?: boolean\n cypressPrefix: string\n extraButtons?: React.ReactNode\n onSetup: () => void\n onDisable: () => void\n onSetPreferred: () => void\n}\n\nfunction MfaMethodRow({\n isEnabled,\n isPreferred,\n isUsedForLogin,\n isSettingUp,\n isSettingPreferredMfaMethod,\n isSetupDisabled,\n showSetupErrorTooltip,\n title,\n description,\n detail,\n mfaRequirementMessage,\n mfaRequirementMessageIsWarning,\n cypressPrefix,\n extraButtons,\n onSetup,\n onDisable,\n onSetPreferred,\n}: Props) {\n return (\n <Box data-cypress={`${cypressPrefix}-method-row`}>\n <Grid container spacing={2} alignItems=\"center\">\n <Grid size={{ xs: 'grow' }}>\n <Box sx={{ mb: 1 }}>\n <Typography variant=\"subtitle1\" component=\"span\">\n {title}\n </Typography>\n {isEnabled && (\n <Chip\n size=\"small\"\n label=\"Enabled\"\n color=\"default\"\n sx={{ ml: 1 }}\n data-cypress={`${cypressPrefix}-status-chip`}\n />\n )}\n {isPreferred && (\n <Chip\n size=\"small\"\n label=\"Preferred\"\n color=\"info\"\n sx={{ ml: 1 }}\n data-cypress={`${cypressPrefix}-preferred-chip`}\n />\n )}\n {isUsedForLogin && (\n <Chip\n size=\"small\"\n label=\"Used for login\"\n color=\"success\"\n sx={{ ml: 1 }}\n data-cypress={`${cypressPrefix}-used-for-login-chip`}\n />\n )}\n </Box>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {description}\n </Typography>\n {!!detail && (\n <Typography variant=\"body2\" color=\"text.secondary\" sx={{ mt: 1 }}>\n {detail}\n </Typography>\n )}\n </Grid>\n <Grid size=\"auto\">\n <Box display=\"flex\" gap={1} flexWrap=\"wrap\" justifyContent=\"flex-end\">\n {extraButtons}\n {isEnabled ? (\n <>\n {!isPreferred && (\n <Button\n size=\"small\"\n variant=\"outlined\"\n loading={isSettingPreferredMfaMethod}\n disabled={isSettingPreferredMfaMethod}\n onClick={onSetPreferred}\n data-cypress={`${cypressPrefix}-set-preferred-button`}\n >\n Set as Preferred\n </Button>\n )}\n <Button\n size=\"small\"\n variant=\"outlined\"\n onClick={onDisable}\n data-cypress={`${cypressPrefix}-disable-button`}\n >\n Disable\n </Button>\n </>\n ) : (\n <Tooltip\n title={\n showSetupErrorTooltip\n ? 'We are unable to load your MFA status. Please try again by clicking the reload button on the chip above.'\n : ''\n }\n >\n <span>\n <Button\n size=\"small\"\n variant=\"contained\"\n loading={isSettingUp}\n disabled={isSetupDisabled}\n onClick={onSetup}\n data-cypress={`${cypressPrefix}-setup-button`}\n >\n Setup\n </Button>\n </span>\n </Tooltip>\n )}\n </Box>\n </Grid>\n </Grid>\n\n {!!mfaRequirementMessage && (\n <Alert\n severity={mfaRequirementMessageIsWarning ? 'warning' : 'info'}\n data-cypress={`${cypressPrefix}-mfa-requirement-message`}\n >\n {mfaRequirementMessage}\n </Alert>\n )}\n </Box>\n )\n}\n\nexport default memo(MfaMethodRow)\n"]}
@@ -2,6 +2,7 @@ import { MiscTypes } from '@oneblink/types';
2
2
  type Props = {
3
3
  mfaRequirement: MiscTypes.MfaRequirement | undefined;
4
4
  ssoSetupUrl?: string;
5
+ accessScopeLabel?: string;
5
6
  };
6
7
  /**
7
8
  * React Component that provides a mechanism for app users to configure Multi
@@ -38,5 +39,5 @@ type Props = {
38
39
  * @returns
39
40
  * @group Components
40
41
  */
41
- export default function MultiFactorAuthentication({ mfaRequirement, ssoSetupUrl, }: Props): import("react/jsx-runtime").JSX.Element;
42
+ export default function MultiFactorAuthentication({ mfaRequirement, ssoSetupUrl, accessScopeLabel, }: Props): import("react/jsx-runtime").JSX.Element;
42
43
  export {};
@@ -10,8 +10,8 @@ import MfaMethodRow from './MfaMethodRow';
10
10
  import MfaSuccessSnackbar from './MfaSuccessSnackbar';
11
11
  import MfaErrorSnackbar from './MfaErrorSnackbar';
12
12
  import MfaStatusChip from './MfaStatusChip';
13
- import { formatMfaMethodNotAcceptedMessage } from '../../utils/mfa-requirement';
14
- function MfaMethodList({ mfaRequirement }) {
13
+ import { formatMfaMethodRequirementMessage, isMfaMethodUsedForLogin, } from '../../utils/mfa-requirement';
14
+ function MfaMethodList({ mfaRequirement, accessScopeLabel = 'app', }) {
15
15
  const { mfaSettings, loadingError, isLoading, isSettingUpMfa, settingUpMfaMethod, isSettingPreferredMfaMethod, beginMfaSetup, beginDisablingMfaMethod, setPreferredMfaMethod, beginRemovingPhoneNumber, } = useMfa();
16
16
  const phoneDetail = useMemo(() => {
17
17
  if (!mfaSettings.sms.phoneNumber) {
@@ -23,20 +23,21 @@ function MfaMethodList({ mfaRequirement }) {
23
23
  return `Phone number: ${mfaSettings.sms.phoneNumber}`;
24
24
  }, [mfaSettings]);
25
25
  const authenticatorMfaRequirementMessage = useMemo(() => {
26
- return formatMfaMethodNotAcceptedMessage('authenticatorApp', mfaRequirement);
27
- }, [mfaRequirement]);
26
+ return formatMfaMethodRequirementMessage('authenticatorApp', mfaRequirement, mfaSettings, accessScopeLabel);
27
+ }, [accessScopeLabel, mfaRequirement, mfaSettings]);
28
28
  const smsMfaRequirementMessage = useMemo(() => {
29
- return formatMfaMethodNotAcceptedMessage('sms', mfaRequirement);
30
- }, [mfaRequirement]);
29
+ return formatMfaMethodRequirementMessage('sms', mfaRequirement, mfaSettings, accessScopeLabel);
30
+ }, [accessScopeLabel, mfaRequirement, mfaSettings]);
31
31
  if (isLoading) {
32
32
  return (_jsx(Typography, { variant: "body2", color: "text.secondary", children: "Loading MFA methods..." }));
33
33
  }
34
34
  if (loadingError) {
35
35
  return (_jsx(Typography, { variant: "body2", color: "error", children: "We are unable to load your MFA methods. Please try again by clicking the reload button on the chip above." }));
36
36
  }
37
- return (_jsxs(_Fragment, { children: [_jsx(MfaMethodRow, { isEnabled: mfaSettings.authenticator.enabled, isPreferred: mfaSettings.authenticator.preferred, isSettingUp: isSettingUpMfa && settingUpMfaMethod === 'authenticator', isSettingPreferredMfaMethod: isSettingPreferredMfaMethod, isSetupDisabled: !!loadingError || isSettingUpMfa, showSetupErrorTooltip: !!loadingError, title: "Authenticator App", description: "Use an app like Google Authenticator or Microsoft Authenticator to generate 6-digit verification codes.", mfaRequirementMessage: authenticatorMfaRequirementMessage, cypressPrefix: "mfa-authenticator", onSetup: () => beginMfaSetup('authenticator'), onDisable: () => beginDisablingMfaMethod('authenticator'), onSetPreferred: () => setPreferredMfaMethod('authenticator') }), _jsx(Divider, { sx: { my: 2 } }), _jsx(MfaMethodRow, { isEnabled: mfaSettings.sms.enabled, isPreferred: mfaSettings.sms.preferred, isSettingUp: isSettingUpMfa && settingUpMfaMethod === 'sms', isSettingPreferredMfaMethod: isSettingPreferredMfaMethod, isSetupDisabled: !!loadingError || isSettingUpMfa, showSetupErrorTooltip: !!loadingError, title: "SMS", description: "Receive a one-time verification code via SMS each time MFA is required.", detail: phoneDetail, mfaRequirementMessage: smsMfaRequirementMessage, cypressPrefix: "mfa-sms", onSetup: () => beginMfaSetup('sms'), onDisable: () => beginDisablingMfaMethod('sms'), onSetPreferred: () => setPreferredMfaMethod('sms'), extraButtons: !!mfaSettings.sms.phoneNumber && !mfaSettings.sms.enabled ? (_jsx(Button, { size: "small", variant: "outlined", disabled: !!loadingError, onClick: beginRemovingPhoneNumber, "data-cypress": "mfa-sms-remove-phone-button", children: "Remove Phone" })) : undefined })] }));
37
+ return (_jsxs(_Fragment, { children: [_jsx(MfaMethodRow, { isEnabled: mfaSettings.authenticator.enabled, isPreferred: mfaSettings.authenticator.preferred, isUsedForLogin: isMfaMethodUsedForLogin(mfaSettings, 'authenticatorApp'), isSettingUp: isSettingUpMfa && settingUpMfaMethod === 'authenticator', isSettingPreferredMfaMethod: isSettingPreferredMfaMethod, isSetupDisabled: !!loadingError || isSettingUpMfa, showSetupErrorTooltip: !!loadingError, title: "Authenticator App", description: "Use an app like Google Authenticator or Microsoft Authenticator to generate 6-digit verification codes.", mfaRequirementMessage: authenticatorMfaRequirementMessage, mfaRequirementMessageIsWarning: !!(mfaRequirement === null || mfaRequirement === void 0 ? void 0 : mfaRequirement.authenticatorApp) &&
38
+ !!authenticatorMfaRequirementMessage, cypressPrefix: "mfa-authenticator", onSetup: () => beginMfaSetup('authenticator'), onDisable: () => beginDisablingMfaMethod('authenticator'), onSetPreferred: () => setPreferredMfaMethod('authenticator') }), _jsx(Divider, { sx: { my: 2 } }), _jsx(MfaMethodRow, { isEnabled: mfaSettings.sms.enabled, isPreferred: mfaSettings.sms.preferred, isUsedForLogin: isMfaMethodUsedForLogin(mfaSettings, 'sms'), isSettingUp: isSettingUpMfa && settingUpMfaMethod === 'sms', isSettingPreferredMfaMethod: isSettingPreferredMfaMethod, isSetupDisabled: !!loadingError || isSettingUpMfa, showSetupErrorTooltip: !!loadingError, title: "SMS", description: "Receive a one-time verification code via SMS each time MFA is required.", detail: phoneDetail, mfaRequirementMessage: smsMfaRequirementMessage, mfaRequirementMessageIsWarning: !!(mfaRequirement === null || mfaRequirement === void 0 ? void 0 : mfaRequirement.sms) && !!smsMfaRequirementMessage, cypressPrefix: "mfa-sms", onSetup: () => beginMfaSetup('sms'), onDisable: () => beginDisablingMfaMethod('sms'), onSetPreferred: () => setPreferredMfaMethod('sms'), extraButtons: !!mfaSettings.sms.phoneNumber && !mfaSettings.sms.enabled ? (_jsx(Button, { size: "small", variant: "outlined", disabled: !!loadingError, onClick: beginRemovingPhoneNumber, "data-cypress": "mfa-sms-remove-phone-button", children: "Remove Phone" })) : undefined })] }));
38
39
  }
39
- function MfaSetup({ ssoSetupUrl, mfaRequirement }) {
40
+ function MfaSetup({ ssoSetupUrl, mfaRequirement, accessScopeLabel }) {
40
41
  const { isExternalIdentityProviderUser } = useMfa();
41
42
  if (ssoSetupUrl) {
42
43
  return (_jsx(Button, { variant: "outlined", size: "small", component: "a", href: ssoSetupUrl, target: "_blank", rel: "noopener noreferrer", "data-cypress": "configure-mfa-button", children: "Configure MFA" }));
@@ -44,7 +45,7 @@ function MfaSetup({ ssoSetupUrl, mfaRequirement }) {
44
45
  if (isExternalIdentityProviderUser) {
45
46
  return (_jsx(Tooltip, { title: "MFA must be configured in your login provider.", children: _jsx("span", { children: _jsx(Button, { variant: "outlined", disabled: isExternalIdentityProviderUser, "data-cypress": "configure-mfa-button", children: "Configure MFA" }) }) }));
46
47
  }
47
- return (_jsxs(_Fragment, { children: [_jsx(MfaMethodList, { mfaRequirement: mfaRequirement }), _jsx(MfaDisableDialog, {}), _jsx(MfaRemovePhoneNumberDialog, {}), _jsx(MfaPhoneNumberDialog, {}), _jsx(MfaAuthenticatorAppDialog, {}), _jsx(MfaErrorSnackbar, {}), _jsx(MfaSuccessSnackbar, {})] }));
48
+ return (_jsxs(_Fragment, { children: [_jsx(MfaMethodList, { mfaRequirement: mfaRequirement, accessScopeLabel: accessScopeLabel }), _jsx(MfaDisableDialog, {}), _jsx(MfaRemovePhoneNumberDialog, {}), _jsx(MfaPhoneNumberDialog, {}), _jsx(MfaAuthenticatorAppDialog, {}), _jsx(MfaErrorSnackbar, {}), _jsx(MfaSuccessSnackbar, {})] }));
48
49
  }
49
50
  /**
50
51
  * React Component that provides a mechanism for app users to configure Multi
@@ -81,7 +82,7 @@ function MfaSetup({ ssoSetupUrl, mfaRequirement }) {
81
82
  * @returns
82
83
  * @group Components
83
84
  */
84
- export default function MultiFactorAuthentication({ mfaRequirement, ssoSetupUrl, }) {
85
- return (_jsx(Grid, { size: { xs: 'grow', lg: 8 }, children: _jsx(Box, { padding: 3, children: _jsx(Paper, { children: _jsx(Box, { padding: 3, children: _jsx(Grid, { container: true, spacing: 2, alignItems: "center", children: _jsxs(Grid, { size: { xs: 'grow' }, children: [_jsxs(Typography, { variant: "h4", fontWeight: "light", children: ["Multi Factor Authentication ", _jsx(MfaStatusChip, {})] }), _jsx(Box, { marginY: 1, children: _jsx(Divider, {}) }), _jsx(Typography, { variant: "body2", paragraph: true, children: "Multi factor authentication (MFA), also known as two factor authentication (2FA), is a best practice that requires a second authentication factor in addition to user name and password sign-in credentials. We strongly recommend enabling MFA to enhance your account security." }), _jsx(MfaSetup, { ssoSetupUrl: ssoSetupUrl, mfaRequirement: mfaRequirement })] }) }) }) }) }) }));
85
+ export default function MultiFactorAuthentication({ mfaRequirement, ssoSetupUrl, accessScopeLabel = 'App', }) {
86
+ return (_jsx(Grid, { size: { xs: 'grow', lg: 8 }, children: _jsx(Box, { padding: 3, children: _jsx(Paper, { children: _jsx(Box, { padding: 3, children: _jsx(Grid, { container: true, spacing: 2, alignItems: "center", children: _jsxs(Grid, { size: { xs: 'grow' }, children: [_jsxs(Typography, { variant: "h4", fontWeight: "light", children: ["Multi Factor Authentication", ' ', _jsx(MfaStatusChip, {})] }), _jsx(Box, { marginY: 1, children: _jsx(Divider, {}) }), _jsx(Typography, { variant: "body2", paragraph: true, children: "Multi factor authentication (MFA), also known as two factor authentication (2FA), is a best practice that requires a second authentication factor in addition to user name and password sign-in credentials. We strongly recommend enabling MFA to enhance your account security." }), _jsx(MfaSetup, { ssoSetupUrl: ssoSetupUrl, mfaRequirement: mfaRequirement, accessScopeLabel: accessScopeLabel })] }) }) }) }) }) }));
86
87
  }
87
88
  //# sourceMappingURL=MultiFactorAuthentication.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultiFactorAuthentication.js","sourceRoot":"","sources":["../../../src/components/mfa/MultiFactorAuthentication.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react'\nimport {\n Box,\n Button,\n Divider,\n Grid,\n Paper,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { MiscTypes } from '@oneblink/types'\nimport MfaAuthenticatorAppDialog from './MfaAuthenticatorAppDialog'\nimport useMfa from '../../hooks/useMfa'\nimport MfaDisableDialog from './MfaDisableDialog'\nimport MfaRemovePhoneNumberDialog from './MfaRemovePhoneNumberDialog'\nimport MfaPhoneNumberDialog from './MfaPhoneNumberDialog'\nimport MfaMethodRow from './MfaMethodRow'\nimport MfaSuccessSnackbar from './MfaSuccessSnackbar'\nimport MfaErrorSnackbar from './MfaErrorSnackbar'\nimport MfaStatusChip from './MfaStatusChip'\nimport { formatMfaMethodNotAcceptedMessage } from '../../utils/mfa-requirement'\n\ntype Props = {\n mfaRequirement: MiscTypes.MfaRequirement | undefined\n ssoSetupUrl?: string\n}\n\nfunction MfaMethodList({ mfaRequirement }: Pick<Props, 'mfaRequirement'>) {\n const {\n mfaSettings,\n loadingError,\n isLoading,\n isSettingUpMfa,\n settingUpMfaMethod,\n isSettingPreferredMfaMethod,\n beginMfaSetup,\n beginDisablingMfaMethod,\n setPreferredMfaMethod,\n beginRemovingPhoneNumber,\n } = useMfa()\n\n const phoneDetail = useMemo(() => {\n if (!mfaSettings.sms.phoneNumber) {\n return undefined\n }\n\n if (!mfaSettings.sms.isPhoneNumberVerified) {\n return `Phone number: ${mfaSettings.sms.phoneNumber} (not verified)`\n }\n\n return `Phone number: ${mfaSettings.sms.phoneNumber}`\n }, [mfaSettings])\n\n const authenticatorMfaRequirementMessage = useMemo(() => {\n return formatMfaMethodNotAcceptedMessage('authenticatorApp', mfaRequirement)\n }, [mfaRequirement])\n\n const smsMfaRequirementMessage = useMemo(() => {\n return formatMfaMethodNotAcceptedMessage('sms', mfaRequirement)\n }, [mfaRequirement])\n\n if (isLoading) {\n return (\n <Typography variant=\"body2\" color=\"text.secondary\">\n Loading MFA methods...\n </Typography>\n )\n }\n\n if (loadingError) {\n return (\n <Typography variant=\"body2\" color=\"error\">\n We are unable to load your MFA methods. Please try again by clicking the\n reload button on the chip above.\n </Typography>\n )\n }\n\n return (\n <>\n <MfaMethodRow\n isEnabled={mfaSettings.authenticator.enabled}\n isPreferred={mfaSettings.authenticator.preferred}\n isSettingUp={isSettingUpMfa && settingUpMfaMethod === 'authenticator'}\n isSettingPreferredMfaMethod={isSettingPreferredMfaMethod}\n isSetupDisabled={!!loadingError || isSettingUpMfa}\n showSetupErrorTooltip={!!loadingError}\n title=\"Authenticator App\"\n description=\"Use an app like Google Authenticator or Microsoft Authenticator to generate 6-digit verification codes.\"\n mfaRequirementMessage={authenticatorMfaRequirementMessage}\n cypressPrefix=\"mfa-authenticator\"\n onSetup={() => beginMfaSetup('authenticator')}\n onDisable={() => beginDisablingMfaMethod('authenticator')}\n onSetPreferred={() => setPreferredMfaMethod('authenticator')}\n />\n <Divider sx={{ my: 2 }} />\n <MfaMethodRow\n isEnabled={mfaSettings.sms.enabled}\n isPreferred={mfaSettings.sms.preferred}\n isSettingUp={isSettingUpMfa && settingUpMfaMethod === 'sms'}\n isSettingPreferredMfaMethod={isSettingPreferredMfaMethod}\n isSetupDisabled={!!loadingError || isSettingUpMfa}\n showSetupErrorTooltip={!!loadingError}\n title=\"SMS\"\n description=\"Receive a one-time verification code via SMS each time MFA is required.\"\n detail={phoneDetail}\n mfaRequirementMessage={smsMfaRequirementMessage}\n cypressPrefix=\"mfa-sms\"\n onSetup={() => beginMfaSetup('sms')}\n onDisable={() => beginDisablingMfaMethod('sms')}\n onSetPreferred={() => setPreferredMfaMethod('sms')}\n extraButtons={\n !!mfaSettings.sms.phoneNumber && !mfaSettings.sms.enabled ? (\n <Button\n size=\"small\"\n variant=\"outlined\"\n disabled={!!loadingError}\n onClick={beginRemovingPhoneNumber}\n data-cypress=\"mfa-sms-remove-phone-button\"\n >\n Remove Phone\n </Button>\n ) : undefined\n }\n />\n </>\n )\n}\n\nfunction MfaSetup({ ssoSetupUrl, mfaRequirement }: Props) {\n const { isExternalIdentityProviderUser } = useMfa()\n\n if (ssoSetupUrl) {\n return (\n <Button\n variant=\"outlined\"\n size=\"small\"\n component=\"a\"\n href={ssoSetupUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-cypress=\"configure-mfa-button\"\n >\n Configure MFA\n </Button>\n )\n }\n\n if (isExternalIdentityProviderUser) {\n return (\n <Tooltip title=\"MFA must be configured in your login provider.\">\n <span>\n <Button\n variant=\"outlined\"\n disabled={isExternalIdentityProviderUser}\n data-cypress=\"configure-mfa-button\"\n >\n Configure MFA\n </Button>\n </span>\n </Tooltip>\n )\n }\n\n return (\n <>\n <MfaMethodList mfaRequirement={mfaRequirement} />\n <MfaDisableDialog />\n <MfaRemovePhoneNumberDialog />\n <MfaPhoneNumberDialog />\n <MfaAuthenticatorAppDialog />\n <MfaErrorSnackbar />\n <MfaSuccessSnackbar />\n </>\n )\n}\n\n/**\n * React Component that provides a mechanism for app users to configure Multi\n * Factor Authentication. `<MfaProvider />` must be provided above this\n * component in the component tree.\n *\n * #### Example\n *\n * ```js\n * import * as React from 'react'\n * import {\n * MfaProvider,\n * MultiFactorAuthentication,\n * } from '@oneblink/apps-react'\n *\n * function Component() {\n * return <MultiFactorAuthentication mfaRequirement={undefined} />\n * }\n *\n * function AppWithMfaRequirement({ mfaRequirement }) {\n * return (\n * <MfaProvider>\n * <MultiFactorAuthentication mfaRequirement={mfaRequirement} />\n * </MfaProvider>\n * )\n * }\n * ```\n *\n * @param props\n * @param props.mfaRequirement - The MFA methods allowed by your administrator\n * for using this app. Pass `undefined` when the app has no MFA requirement.\n * Users can still enable other methods, but will be warned when their\n * configuration does not meet this requirement.\n * @returns\n * @group Components\n */\nexport default function MultiFactorAuthentication({\n mfaRequirement,\n ssoSetupUrl,\n}: Props) {\n return (\n <Grid size={{ xs: 'grow', lg: 8 }}>\n <Box padding={3}>\n <Paper>\n <Box padding={3}>\n <Grid container spacing={2} alignItems=\"center\">\n <Grid size={{ xs: 'grow' }}>\n <Typography variant=\"h4\" fontWeight=\"light\">\n Multi Factor Authentication <MfaStatusChip />\n </Typography>\n <Box marginY={1}>\n <Divider />\n </Box>\n <Typography variant=\"body2\" paragraph>\n Multi factor authentication (MFA), also known as two factor\n authentication (2FA), is a best practice that requires a\n second authentication factor in addition to user name and\n password sign-in credentials. We strongly recommend enabling\n MFA to enhance your account security.\n </Typography>\n <MfaSetup\n ssoSetupUrl={ssoSetupUrl}\n mfaRequirement={mfaRequirement}\n />\n </Grid>\n </Grid>\n </Box>\n </Paper>\n </Box>\n </Grid>\n )\n}\n"]}
1
+ {"version":3,"file":"MultiFactorAuthentication.js","sourceRoot":"","sources":["../../../src/components/mfa/MultiFactorAuthentication.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useMemo } from 'react'\nimport {\n Box,\n Button,\n Divider,\n Grid,\n Paper,\n Tooltip,\n Typography,\n} from '@mui/material'\nimport { MiscTypes } from '@oneblink/types'\nimport MfaAuthenticatorAppDialog from './MfaAuthenticatorAppDialog'\nimport useMfa from '../../hooks/useMfa'\nimport MfaDisableDialog from './MfaDisableDialog'\nimport MfaRemovePhoneNumberDialog from './MfaRemovePhoneNumberDialog'\nimport MfaPhoneNumberDialog from './MfaPhoneNumberDialog'\nimport MfaMethodRow from './MfaMethodRow'\nimport MfaSuccessSnackbar from './MfaSuccessSnackbar'\nimport MfaErrorSnackbar from './MfaErrorSnackbar'\nimport MfaStatusChip from './MfaStatusChip'\nimport {\n formatMfaMethodRequirementMessage,\n isMfaMethodUsedForLogin,\n} from '../../utils/mfa-requirement'\n\ntype Props = {\n mfaRequirement: MiscTypes.MfaRequirement | undefined\n ssoSetupUrl?: string\n accessScopeLabel?: string\n}\n\nfunction MfaMethodList({\n mfaRequirement,\n accessScopeLabel = 'app',\n}: Pick<Props, 'mfaRequirement' | 'accessScopeLabel'>) {\n const {\n mfaSettings,\n loadingError,\n isLoading,\n isSettingUpMfa,\n settingUpMfaMethod,\n isSettingPreferredMfaMethod,\n beginMfaSetup,\n beginDisablingMfaMethod,\n setPreferredMfaMethod,\n beginRemovingPhoneNumber,\n } = useMfa()\n\n const phoneDetail = useMemo(() => {\n if (!mfaSettings.sms.phoneNumber) {\n return undefined\n }\n\n if (!mfaSettings.sms.isPhoneNumberVerified) {\n return `Phone number: ${mfaSettings.sms.phoneNumber} (not verified)`\n }\n\n return `Phone number: ${mfaSettings.sms.phoneNumber}`\n }, [mfaSettings])\n\n const authenticatorMfaRequirementMessage = useMemo(() => {\n return formatMfaMethodRequirementMessage(\n 'authenticatorApp',\n mfaRequirement,\n mfaSettings,\n accessScopeLabel,\n )\n }, [accessScopeLabel, mfaRequirement, mfaSettings])\n\n const smsMfaRequirementMessage = useMemo(() => {\n return formatMfaMethodRequirementMessage(\n 'sms',\n mfaRequirement,\n mfaSettings,\n accessScopeLabel,\n )\n }, [accessScopeLabel, mfaRequirement, mfaSettings])\n\n if (isLoading) {\n return (\n <Typography variant=\"body2\" color=\"text.secondary\">\n Loading MFA methods...\n </Typography>\n )\n }\n\n if (loadingError) {\n return (\n <Typography variant=\"body2\" color=\"error\">\n We are unable to load your MFA methods. Please try again by clicking the\n reload button on the chip above.\n </Typography>\n )\n }\n\n return (\n <>\n <MfaMethodRow\n isEnabled={mfaSettings.authenticator.enabled}\n isPreferred={mfaSettings.authenticator.preferred}\n isUsedForLogin={isMfaMethodUsedForLogin(\n mfaSettings,\n 'authenticatorApp',\n )}\n isSettingUp={isSettingUpMfa && settingUpMfaMethod === 'authenticator'}\n isSettingPreferredMfaMethod={isSettingPreferredMfaMethod}\n isSetupDisabled={!!loadingError || isSettingUpMfa}\n showSetupErrorTooltip={!!loadingError}\n title=\"Authenticator App\"\n description=\"Use an app like Google Authenticator or Microsoft Authenticator to generate 6-digit verification codes.\"\n mfaRequirementMessage={authenticatorMfaRequirementMessage}\n mfaRequirementMessageIsWarning={\n !!mfaRequirement?.authenticatorApp &&\n !!authenticatorMfaRequirementMessage\n }\n cypressPrefix=\"mfa-authenticator\"\n onSetup={() => beginMfaSetup('authenticator')}\n onDisable={() => beginDisablingMfaMethod('authenticator')}\n onSetPreferred={() => setPreferredMfaMethod('authenticator')}\n />\n <Divider sx={{ my: 2 }} />\n <MfaMethodRow\n isEnabled={mfaSettings.sms.enabled}\n isPreferred={mfaSettings.sms.preferred}\n isUsedForLogin={isMfaMethodUsedForLogin(mfaSettings, 'sms')}\n isSettingUp={isSettingUpMfa && settingUpMfaMethod === 'sms'}\n isSettingPreferredMfaMethod={isSettingPreferredMfaMethod}\n isSetupDisabled={!!loadingError || isSettingUpMfa}\n showSetupErrorTooltip={!!loadingError}\n title=\"SMS\"\n description=\"Receive a one-time verification code via SMS each time MFA is required.\"\n detail={phoneDetail}\n mfaRequirementMessage={smsMfaRequirementMessage}\n mfaRequirementMessageIsWarning={\n !!mfaRequirement?.sms && !!smsMfaRequirementMessage\n }\n cypressPrefix=\"mfa-sms\"\n onSetup={() => beginMfaSetup('sms')}\n onDisable={() => beginDisablingMfaMethod('sms')}\n onSetPreferred={() => setPreferredMfaMethod('sms')}\n extraButtons={\n !!mfaSettings.sms.phoneNumber && !mfaSettings.sms.enabled ? (\n <Button\n size=\"small\"\n variant=\"outlined\"\n disabled={!!loadingError}\n onClick={beginRemovingPhoneNumber}\n data-cypress=\"mfa-sms-remove-phone-button\"\n >\n Remove Phone\n </Button>\n ) : undefined\n }\n />\n </>\n )\n}\n\nfunction MfaSetup({ ssoSetupUrl, mfaRequirement, accessScopeLabel }: Props) {\n const { isExternalIdentityProviderUser } = useMfa()\n\n if (ssoSetupUrl) {\n return (\n <Button\n variant=\"outlined\"\n size=\"small\"\n component=\"a\"\n href={ssoSetupUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n data-cypress=\"configure-mfa-button\"\n >\n Configure MFA\n </Button>\n )\n }\n\n if (isExternalIdentityProviderUser) {\n return (\n <Tooltip title=\"MFA must be configured in your login provider.\">\n <span>\n <Button\n variant=\"outlined\"\n disabled={isExternalIdentityProviderUser}\n data-cypress=\"configure-mfa-button\"\n >\n Configure MFA\n </Button>\n </span>\n </Tooltip>\n )\n }\n\n return (\n <>\n <MfaMethodList\n mfaRequirement={mfaRequirement}\n accessScopeLabel={accessScopeLabel}\n />\n <MfaDisableDialog />\n <MfaRemovePhoneNumberDialog />\n <MfaPhoneNumberDialog />\n <MfaAuthenticatorAppDialog />\n <MfaErrorSnackbar />\n <MfaSuccessSnackbar />\n </>\n )\n}\n\n/**\n * React Component that provides a mechanism for app users to configure Multi\n * Factor Authentication. `<MfaProvider />` must be provided above this\n * component in the component tree.\n *\n * #### Example\n *\n * ```js\n * import * as React from 'react'\n * import {\n * MfaProvider,\n * MultiFactorAuthentication,\n * } from '@oneblink/apps-react'\n *\n * function Component() {\n * return <MultiFactorAuthentication mfaRequirement={undefined} />\n * }\n *\n * function AppWithMfaRequirement({ mfaRequirement }) {\n * return (\n * <MfaProvider>\n * <MultiFactorAuthentication mfaRequirement={mfaRequirement} />\n * </MfaProvider>\n * )\n * }\n * ```\n *\n * @param props\n * @param props.mfaRequirement - The MFA methods allowed by your administrator\n * for using this app. Pass `undefined` when the app has no MFA requirement.\n * Users can still enable other methods, but will be warned when their\n * configuration does not meet this requirement.\n * @returns\n * @group Components\n */\nexport default function MultiFactorAuthentication({\n mfaRequirement,\n ssoSetupUrl,\n accessScopeLabel = 'App',\n}: Props) {\n return (\n <Grid size={{ xs: 'grow', lg: 8 }}>\n <Box padding={3}>\n <Paper>\n <Box padding={3}>\n <Grid container spacing={2} alignItems=\"center\">\n <Grid size={{ xs: 'grow' }}>\n <Typography variant=\"h4\" fontWeight=\"light\">\n Multi Factor Authentication{' '}\n <MfaStatusChip />\n </Typography>\n <Box marginY={1}>\n <Divider />\n </Box>\n <Typography variant=\"body2\" paragraph>\n Multi factor authentication (MFA), also known as two factor\n authentication (2FA), is a best practice that requires a\n second authentication factor in addition to user name and\n password sign-in credentials. We strongly recommend enabling\n MFA to enhance your account security.\n </Typography>\n <MfaSetup\n ssoSetupUrl={ssoSetupUrl}\n mfaRequirement={mfaRequirement}\n accessScopeLabel={accessScopeLabel}\n />\n </Grid>\n </Grid>\n </Box>\n </Paper>\n </Box>\n </Grid>\n )\n}\n"]}
@@ -1,12 +1,12 @@
1
1
  import { MiscTypes } from '@oneblink/types';
2
- import type { MfaSettings } from '../apps/services/AWSCognitoClient';
3
- export type { MfaSettings };
2
+ import type { LoggedInMfaMethod, MfaSettings } from '../apps/services/AWSCognitoClient';
3
+ export type { LoggedInMfaMethod, MfaSettings };
4
4
  export declare function isMfaRequired(mfaRequirement: MiscTypes.MfaRequirement | undefined): boolean;
5
5
  export type MfaRequirementMethod = keyof MiscTypes.MfaRequirement;
6
6
  export declare function mfaRequirementToSelectedMethods(mfaRequirement: MiscTypes.MfaRequirement | undefined): MfaRequirementMethod[];
7
7
  export declare function mfaSelectedMethodsToMfaRequirement(methods: MfaRequirementMethod[]): MiscTypes.MfaRequirement;
8
8
  export declare function formatMfaRequirementLabel(mfaRequirement: MiscTypes.MfaRequirement | undefined): string;
9
- export declare function formatMfaRequirementMethodLabel(method: MfaRequirementMethod): string;
9
+ export declare function isMfaMethodUsedForLogin(mfaSettings: MfaSettings, method: MfaRequirementMethod): boolean;
10
10
  export declare function userMeetsMfaRequirement(mfaRequirement: MiscTypes.MfaRequirement | undefined, mfaSettings: MfaSettings): boolean;
11
- export declare function formatMfaMethodNotAcceptedMessage(method: MfaRequirementMethod, mfaRequirement: MiscTypes.MfaRequirement | undefined, accessScopeLabel?: string): string | undefined;
12
11
  export declare function formatMfaSetupRequiredMessage(mfaRequirement: MiscTypes.MfaRequirement | undefined, mfaSettings: MfaSettings, accessScopeLabel?: string): string | undefined;
12
+ export declare function formatMfaMethodRequirementMessage(method: MfaRequirementMethod, mfaRequirement: MiscTypes.MfaRequirement | undefined, mfaSettings: MfaSettings, accessScopeLabel?: string): string | undefined;
@@ -38,7 +38,7 @@ export function formatMfaRequirementLabel(mfaRequirement) {
38
38
  const methodList = joinArray(selectedMethods.map(formatMfaRequirementMethodLabel), 'disjunction');
39
39
  return `MFA Required (${methodList} only)`;
40
40
  }
41
- export function formatMfaRequirementMethodLabel(method) {
41
+ function formatMfaRequirementMethodLabel(method) {
42
42
  switch (method) {
43
43
  case 'sms':
44
44
  return 'SMS';
@@ -50,23 +50,27 @@ export function formatMfaRequirementMethodLabel(method) {
50
50
  }
51
51
  }
52
52
  }
53
+ function mfaRequirementMethodToLoggedInMfaMethod(method) {
54
+ return method === 'sms' ? 'SMS_MFA' : 'SOFTWARE_TOKEN_MFA';
55
+ }
56
+ export function isMfaMethodUsedForLogin(mfaSettings, method) {
57
+ return (mfaSettings.loggedInWithMfaMethod ===
58
+ mfaRequirementMethodToLoggedInMfaMethod(method));
59
+ }
53
60
  export function userMeetsMfaRequirement(mfaRequirement, mfaSettings) {
54
61
  if (!isMfaRequired(mfaRequirement)) {
55
62
  return true;
56
63
  }
57
- if ((mfaRequirement === null || mfaRequirement === void 0 ? void 0 : mfaRequirement.sms) &&
58
- mfaSettings.sms.enabled &&
59
- mfaSettings.sms.preferred) {
64
+ if ((mfaRequirement === null || mfaRequirement === void 0 ? void 0 : mfaRequirement.sms) && mfaSettings.loggedInWithMfaMethod === 'SMS_MFA') {
60
65
  return true;
61
66
  }
62
67
  if ((mfaRequirement === null || mfaRequirement === void 0 ? void 0 : mfaRequirement.authenticatorApp) &&
63
- mfaSettings.authenticator.enabled &&
64
- mfaSettings.authenticator.preferred) {
68
+ mfaSettings.loggedInWithMfaMethod === 'SOFTWARE_TOKEN_MFA') {
65
69
  return true;
66
70
  }
67
71
  return false;
68
72
  }
69
- export function formatMfaMethodNotAcceptedMessage(method, mfaRequirement, accessScopeLabel = 'app') {
73
+ function formatMfaMethodNotAcceptedMessage(method, mfaRequirement, accessScopeLabel = 'app') {
70
74
  if (!mfaRequirement || !isMfaRequired(mfaRequirement)) {
71
75
  return undefined;
72
76
  }
@@ -77,24 +81,69 @@ export function formatMfaMethodNotAcceptedMessage(method, mfaRequirement, access
77
81
  const methodList = joinArray(requiredMethods.map(formatMfaRequirementMethodLabel), 'disjunction');
78
82
  return `This MFA method is not sufficient for using this ${accessScopeLabel.toLowerCase()}. Your administrator requires ${methodList} multi factor authentication.`;
79
83
  }
84
+ function isMfaMethodEnabled(mfaSettings, method) {
85
+ return method === 'sms'
86
+ ? mfaSettings.sms.enabled
87
+ : mfaSettings.authenticator.enabled;
88
+ }
89
+ function isMfaMethodPreferred(mfaSettings, method) {
90
+ return method === 'sms'
91
+ ? mfaSettings.sms.preferred
92
+ : mfaSettings.authenticator.preferred;
93
+ }
94
+ function hasPreferredEnabledRequiredMethod(mfaRequirement, mfaSettings) {
95
+ return mfaRequirementToSelectedMethods(mfaRequirement).some((method) => isMfaMethodEnabled(mfaSettings, method) &&
96
+ isMfaMethodPreferred(mfaSettings, method));
97
+ }
80
98
  export function formatMfaSetupRequiredMessage(mfaRequirement, mfaSettings, accessScopeLabel = 'Account') {
81
- if (!isMfaRequired(mfaRequirement) ||
99
+ if (!mfaRequirement ||
100
+ !isMfaRequired(mfaRequirement) ||
82
101
  userMeetsMfaRequirement(mfaRequirement, mfaSettings)) {
83
102
  return undefined;
84
103
  }
85
104
  const requiredMethods = mfaRequirementToSelectedMethods(mfaRequirement);
86
- const hasAnyMfaEnabled = mfaSettings.authenticator.enabled || mfaSettings.sms.enabled;
87
105
  if (requiredMethods.length === 1) {
88
- const methodLabel = formatMfaRequirementMethodLabel(requiredMethods[0]);
89
- if (hasAnyMfaEnabled) {
90
- return `requires ${methodLabel} multi factor authentication. You have a different MFA method configured, but that method is not accepted for this ${accessScopeLabel.toLowerCase()}.`;
106
+ const method = requiredMethods[0];
107
+ const methodLabel = formatMfaRequirementMethodLabel(method);
108
+ if (!isMfaMethodEnabled(mfaSettings, method)) {
109
+ return `requires ${methodLabel} multi factor authentication to be configured before accessing this ${accessScopeLabel}.`;
110
+ }
111
+ if (!isMfaMethodPreferred(mfaSettings, method)) {
112
+ return `requires ${methodLabel} multi factor authentication. Please change your preferred MFA method to ${methodLabel} to access this ${accessScopeLabel}.`;
91
113
  }
92
- return `requires ${methodLabel} multi factor authentication to be configured before accessing this ${accessScopeLabel}.`;
114
+ return `requires ${methodLabel} multi factor authentication. Now that ${methodLabel} is your preferred MFA method, you must log out and log back in to access this ${accessScopeLabel}.`;
93
115
  }
94
116
  const methodList = joinArray(requiredMethods.map(formatMfaRequirementMethodLabel), 'disjunction');
95
- if (hasAnyMfaEnabled) {
96
- return `requires ${methodList} multi factor authentication. Your current MFA method is not accepted for this ${accessScopeLabel.toLowerCase()}.`;
117
+ const hasAnyMfaEnabled = mfaSettings.authenticator.enabled || mfaSettings.sms.enabled;
118
+ if (!hasAnyMfaEnabled) {
119
+ return `requires ${methodList} multi factor authentication to be configured before accessing this ${accessScopeLabel}.`;
120
+ }
121
+ if (!hasPreferredEnabledRequiredMethod(mfaRequirement, mfaSettings)) {
122
+ return `requires ${methodList} multi factor authentication. Please change your preferred MFA method to one of the accepted methods to access this ${accessScopeLabel}.`;
123
+ }
124
+ return `requires ${methodList} multi factor authentication. Now that your preferred MFA method meets this requirement, you must log out and log back in to access this ${accessScopeLabel}.`;
125
+ }
126
+ export function formatMfaMethodRequirementMessage(method, mfaRequirement, mfaSettings, accessScopeLabel = 'app') {
127
+ if (!mfaRequirement || !isMfaRequired(mfaRequirement)) {
128
+ return undefined;
129
+ }
130
+ const scope = accessScopeLabel.toLowerCase();
131
+ if (!mfaRequirement[method]) {
132
+ return formatMfaMethodNotAcceptedMessage(method, mfaRequirement, accessScopeLabel);
133
+ }
134
+ if (userMeetsMfaRequirement(mfaRequirement, mfaSettings)) {
135
+ return;
136
+ }
137
+ const methodLabel = formatMfaRequirementMethodLabel(method);
138
+ const isMethodEnabled = isMfaMethodEnabled(mfaSettings, method);
139
+ const isMethodPreferred = isMfaMethodPreferred(mfaSettings, method);
140
+ const firstSentence = `Your administrator requires ${methodLabel} multi factor authentication.`;
141
+ if (!isMethodEnabled) {
142
+ return `${firstSentence} Setup ${methodLabel} to access this ${scope}`;
143
+ }
144
+ if (!isMethodPreferred) {
145
+ return `${firstSentence} Set ${methodLabel} as your preferred MFA method to access this ${scope}.`;
97
146
  }
98
- return `requires ${methodList} multi factor authentication to be configured before accessing this ${accessScopeLabel}.`;
147
+ return `${firstSentence} Now that ${methodLabel} is your preferred MFA method, you must log out and log back in to access this ${scope}.`;
99
148
  }
100
149
  //# sourceMappingURL=mfa-requirement.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mfa-requirement.js","sourceRoot":"","sources":["../../src/utils/mfa-requirement.ts"],"names":[],"mappings":"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","sourcesContent":["import { MiscTypes } from '@oneblink/types'\r\nimport type { MfaSettings } from '../apps/services/AWSCognitoClient'\r\nimport { joinArray } from './joinArray'\r\n\r\nexport type { MfaSettings }\r\n\r\nexport function isMfaRequired(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n): boolean {\r\n return (\r\n !!mfaRequirement && (mfaRequirement.sms || mfaRequirement.authenticatorApp)\r\n )\r\n}\r\n\r\nexport type MfaRequirementMethod = keyof MiscTypes.MfaRequirement\r\n\r\nconst MFA_REQUIREMENT_METHOD_KEYS = Object.keys({\r\n sms: false,\r\n authenticatorApp: false,\r\n} satisfies MiscTypes.MfaRequirement) as MfaRequirementMethod[]\r\n\r\nexport function mfaRequirementToSelectedMethods(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n): MfaRequirementMethod[] {\r\n const checkboxState = {\r\n sms: mfaRequirement?.sms ?? false,\r\n authenticatorApp: mfaRequirement?.authenticatorApp ?? false,\r\n }\r\n const methods: MfaRequirementMethod[] = []\r\n\r\n if (checkboxState.authenticatorApp) {\r\n methods.push('authenticatorApp')\r\n }\r\n\r\n if (checkboxState.sms) {\r\n methods.push('sms')\r\n }\r\n\r\n return methods\r\n}\r\n\r\nexport function mfaSelectedMethodsToMfaRequirement(\r\n methods: MfaRequirementMethod[],\r\n): MiscTypes.MfaRequirement {\r\n return {\r\n sms: methods.includes('sms'),\r\n authenticatorApp: methods.includes('authenticatorApp'),\r\n }\r\n}\r\n\r\nexport function formatMfaRequirementLabel(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n): string {\r\n if (!isMfaRequired(mfaRequirement)) {\r\n return 'MFA Optional'\r\n }\r\n\r\n const selectedMethods = mfaRequirementToSelectedMethods(mfaRequirement)\r\n\r\n if (selectedMethods.length === MFA_REQUIREMENT_METHOD_KEYS.length) {\r\n return 'MFA Required'\r\n }\r\n\r\n const methodList = joinArray(\r\n selectedMethods.map(formatMfaRequirementMethodLabel),\r\n 'disjunction',\r\n )\r\n\r\n return `MFA Required (${methodList} only)`\r\n}\r\n\r\nexport function formatMfaRequirementMethodLabel(\r\n method: MfaRequirementMethod,\r\n): string {\r\n switch (method) {\r\n case 'sms':\r\n return 'SMS'\r\n case 'authenticatorApp':\r\n return 'Authenticator App'\r\n default: {\r\n const n: never = method\r\n return n\r\n }\r\n }\r\n}\r\n\r\nexport function userMeetsMfaRequirement(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n mfaSettings: MfaSettings,\r\n): boolean {\r\n if (!isMfaRequired(mfaRequirement)) {\r\n return true\r\n }\r\n\r\n if (\r\n mfaRequirement?.sms &&\r\n mfaSettings.sms.enabled &&\r\n mfaSettings.sms.preferred\r\n ) {\r\n return true\r\n }\r\n\r\n if (\r\n mfaRequirement?.authenticatorApp &&\r\n mfaSettings.authenticator.enabled &&\r\n mfaSettings.authenticator.preferred\r\n ) {\r\n return true\r\n }\r\n\r\n return false\r\n}\r\n\r\nexport function formatMfaMethodNotAcceptedMessage(\r\n method: MfaRequirementMethod,\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n accessScopeLabel = 'app',\r\n): string | undefined {\r\n if (!mfaRequirement || !isMfaRequired(mfaRequirement)) {\r\n return undefined\r\n }\r\n\r\n if (mfaRequirement[method]) {\r\n return undefined\r\n }\r\n\r\n const requiredMethods = mfaRequirementToSelectedMethods(mfaRequirement)\r\n\r\n const methodList = joinArray(\r\n requiredMethods.map(formatMfaRequirementMethodLabel),\r\n 'disjunction',\r\n )\r\n\r\n return `This MFA method is not sufficient for using this ${accessScopeLabel.toLowerCase()}. Your administrator requires ${methodList} multi factor authentication.`\r\n}\r\n\r\nexport function formatMfaSetupRequiredMessage(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n mfaSettings: MfaSettings,\r\n accessScopeLabel = 'Account',\r\n): string | undefined {\r\n if (\r\n !isMfaRequired(mfaRequirement) ||\r\n userMeetsMfaRequirement(mfaRequirement, mfaSettings)\r\n ) {\r\n return undefined\r\n }\r\n\r\n const requiredMethods = mfaRequirementToSelectedMethods(mfaRequirement)\r\n const hasAnyMfaEnabled =\r\n mfaSettings.authenticator.enabled || mfaSettings.sms.enabled\r\n\r\n if (requiredMethods.length === 1) {\r\n const methodLabel = formatMfaRequirementMethodLabel(requiredMethods[0])\r\n\r\n if (hasAnyMfaEnabled) {\r\n return `requires ${methodLabel} multi factor authentication. You have a different MFA method configured, but that method is not accepted for this ${accessScopeLabel.toLowerCase()}.`\r\n }\r\n\r\n return `requires ${methodLabel} multi factor authentication to be configured before accessing this ${accessScopeLabel}.`\r\n }\r\n\r\n const methodList = joinArray(\r\n requiredMethods.map(formatMfaRequirementMethodLabel),\r\n 'disjunction',\r\n )\r\n\r\n if (hasAnyMfaEnabled) {\r\n return `requires ${methodList} multi factor authentication. Your current MFA method is not accepted for this ${accessScopeLabel.toLowerCase()}.`\r\n }\r\n\r\n return `requires ${methodList} multi factor authentication to be configured before accessing this ${accessScopeLabel}.`\r\n}\r\n"]}
1
+ {"version":3,"file":"mfa-requirement.js","sourceRoot":"","sources":["../../src/utils/mfa-requirement.ts"],"names":[],"mappings":"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","sourcesContent":["import { MiscTypes } from '@oneblink/types'\r\nimport type {\r\n LoggedInMfaMethod,\r\n MfaSettings,\r\n} from '../apps/services/AWSCognitoClient'\r\nimport { joinArray } from './joinArray'\r\n\r\nexport type { LoggedInMfaMethod, MfaSettings }\r\n\r\nexport function isMfaRequired(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n): boolean {\r\n return (\r\n !!mfaRequirement && (mfaRequirement.sms || mfaRequirement.authenticatorApp)\r\n )\r\n}\r\n\r\nexport type MfaRequirementMethod = keyof MiscTypes.MfaRequirement\r\n\r\nconst MFA_REQUIREMENT_METHOD_KEYS = Object.keys({\r\n sms: false,\r\n authenticatorApp: false,\r\n} satisfies MiscTypes.MfaRequirement) as MfaRequirementMethod[]\r\n\r\nexport function mfaRequirementToSelectedMethods(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n): MfaRequirementMethod[] {\r\n const checkboxState = {\r\n sms: mfaRequirement?.sms ?? false,\r\n authenticatorApp: mfaRequirement?.authenticatorApp ?? false,\r\n }\r\n const methods: MfaRequirementMethod[] = []\r\n\r\n if (checkboxState.authenticatorApp) {\r\n methods.push('authenticatorApp')\r\n }\r\n\r\n if (checkboxState.sms) {\r\n methods.push('sms')\r\n }\r\n\r\n return methods\r\n}\r\n\r\nexport function mfaSelectedMethodsToMfaRequirement(\r\n methods: MfaRequirementMethod[],\r\n): MiscTypes.MfaRequirement {\r\n return {\r\n sms: methods.includes('sms'),\r\n authenticatorApp: methods.includes('authenticatorApp'),\r\n }\r\n}\r\n\r\nexport function formatMfaRequirementLabel(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n): string {\r\n if (!isMfaRequired(mfaRequirement)) {\r\n return 'MFA Optional'\r\n }\r\n\r\n const selectedMethods = mfaRequirementToSelectedMethods(mfaRequirement)\r\n\r\n if (selectedMethods.length === MFA_REQUIREMENT_METHOD_KEYS.length) {\r\n return 'MFA Required'\r\n }\r\n\r\n const methodList = joinArray(\r\n selectedMethods.map(formatMfaRequirementMethodLabel),\r\n 'disjunction',\r\n )\r\n\r\n return `MFA Required (${methodList} only)`\r\n}\r\n\r\nfunction formatMfaRequirementMethodLabel(method: MfaRequirementMethod): string {\r\n switch (method) {\r\n case 'sms':\r\n return 'SMS'\r\n case 'authenticatorApp':\r\n return 'Authenticator App'\r\n default: {\r\n const n: never = method\r\n return n\r\n }\r\n }\r\n}\r\n\r\nfunction mfaRequirementMethodToLoggedInMfaMethod(\r\n method: MfaRequirementMethod,\r\n): Exclude<LoggedInMfaMethod, 'NO_MFA_ENABLED'> {\r\n return method === 'sms' ? 'SMS_MFA' : 'SOFTWARE_TOKEN_MFA'\r\n}\r\n\r\nexport function isMfaMethodUsedForLogin(\r\n mfaSettings: MfaSettings,\r\n method: MfaRequirementMethod,\r\n): boolean {\r\n return (\r\n mfaSettings.loggedInWithMfaMethod ===\r\n mfaRequirementMethodToLoggedInMfaMethod(method)\r\n )\r\n}\r\n\r\nexport function userMeetsMfaRequirement(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n mfaSettings: MfaSettings,\r\n): boolean {\r\n if (!isMfaRequired(mfaRequirement)) {\r\n return true\r\n }\r\n\r\n if (mfaRequirement?.sms && mfaSettings.loggedInWithMfaMethod === 'SMS_MFA') {\r\n return true\r\n }\r\n\r\n if (\r\n mfaRequirement?.authenticatorApp &&\r\n mfaSettings.loggedInWithMfaMethod === 'SOFTWARE_TOKEN_MFA'\r\n ) {\r\n return true\r\n }\r\n\r\n return false\r\n}\r\n\r\nfunction formatMfaMethodNotAcceptedMessage(\r\n method: MfaRequirementMethod,\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n accessScopeLabel = 'app',\r\n): string | undefined {\r\n if (!mfaRequirement || !isMfaRequired(mfaRequirement)) {\r\n return undefined\r\n }\r\n\r\n if (mfaRequirement[method]) {\r\n return undefined\r\n }\r\n\r\n const requiredMethods = mfaRequirementToSelectedMethods(mfaRequirement)\r\n\r\n const methodList = joinArray(\r\n requiredMethods.map(formatMfaRequirementMethodLabel),\r\n 'disjunction',\r\n )\r\n\r\n return `This MFA method is not sufficient for using this ${accessScopeLabel.toLowerCase()}. Your administrator requires ${methodList} multi factor authentication.`\r\n}\r\n\r\nfunction isMfaMethodEnabled(\r\n mfaSettings: MfaSettings,\r\n method: MfaRequirementMethod,\r\n): boolean {\r\n return method === 'sms'\r\n ? mfaSettings.sms.enabled\r\n : mfaSettings.authenticator.enabled\r\n}\r\n\r\nfunction isMfaMethodPreferred(\r\n mfaSettings: MfaSettings,\r\n method: MfaRequirementMethod,\r\n): boolean {\r\n return method === 'sms'\r\n ? mfaSettings.sms.preferred\r\n : mfaSettings.authenticator.preferred\r\n}\r\n\r\nfunction hasPreferredEnabledRequiredMethod(\r\n mfaRequirement: MiscTypes.MfaRequirement,\r\n mfaSettings: MfaSettings,\r\n): boolean {\r\n return mfaRequirementToSelectedMethods(mfaRequirement).some(\r\n (method) =>\r\n isMfaMethodEnabled(mfaSettings, method) &&\r\n isMfaMethodPreferred(mfaSettings, method),\r\n )\r\n}\r\n\r\nexport function formatMfaSetupRequiredMessage(\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n mfaSettings: MfaSettings,\r\n accessScopeLabel = 'Account',\r\n): string | undefined {\r\n if (\r\n !mfaRequirement ||\r\n !isMfaRequired(mfaRequirement) ||\r\n userMeetsMfaRequirement(mfaRequirement, mfaSettings)\r\n ) {\r\n return undefined\r\n }\r\n\r\n const requiredMethods = mfaRequirementToSelectedMethods(mfaRequirement)\r\n\r\n if (requiredMethods.length === 1) {\r\n const method = requiredMethods[0]\r\n const methodLabel = formatMfaRequirementMethodLabel(method)\r\n\r\n if (!isMfaMethodEnabled(mfaSettings, method)) {\r\n return `requires ${methodLabel} multi factor authentication to be configured before accessing this ${accessScopeLabel}.`\r\n }\r\n\r\n if (!isMfaMethodPreferred(mfaSettings, method)) {\r\n return `requires ${methodLabel} multi factor authentication. Please change your preferred MFA method to ${methodLabel} to access this ${accessScopeLabel}.`\r\n }\r\n\r\n return `requires ${methodLabel} multi factor authentication. Now that ${methodLabel} is your preferred MFA method, you must log out and log back in to access this ${accessScopeLabel}.`\r\n }\r\n\r\n const methodList = joinArray(\r\n requiredMethods.map(formatMfaRequirementMethodLabel),\r\n 'disjunction',\r\n )\r\n const hasAnyMfaEnabled =\r\n mfaSettings.authenticator.enabled || mfaSettings.sms.enabled\r\n\r\n if (!hasAnyMfaEnabled) {\r\n return `requires ${methodList} multi factor authentication to be configured before accessing this ${accessScopeLabel}.`\r\n }\r\n\r\n if (!hasPreferredEnabledRequiredMethod(mfaRequirement, mfaSettings)) {\r\n return `requires ${methodList} multi factor authentication. Please change your preferred MFA method to one of the accepted methods to access this ${accessScopeLabel}.`\r\n }\r\n\r\n return `requires ${methodList} multi factor authentication. Now that your preferred MFA method meets this requirement, you must log out and log back in to access this ${accessScopeLabel}.`\r\n}\r\n\r\nexport function formatMfaMethodRequirementMessage(\r\n method: MfaRequirementMethod,\r\n mfaRequirement: MiscTypes.MfaRequirement | undefined,\r\n mfaSettings: MfaSettings,\r\n accessScopeLabel = 'app',\r\n): string | undefined {\r\n if (!mfaRequirement || !isMfaRequired(mfaRequirement)) {\r\n return undefined\r\n }\r\n\r\n const scope = accessScopeLabel.toLowerCase()\r\n\r\n if (!mfaRequirement[method]) {\r\n return formatMfaMethodNotAcceptedMessage(\r\n method,\r\n mfaRequirement,\r\n accessScopeLabel,\r\n )\r\n }\r\n\r\n if (userMeetsMfaRequirement(mfaRequirement, mfaSettings)) {\r\n return\r\n }\r\n\r\n const methodLabel = formatMfaRequirementMethodLabel(method)\r\n const isMethodEnabled = isMfaMethodEnabled(mfaSettings, method)\r\n const isMethodPreferred = isMfaMethodPreferred(mfaSettings, method)\r\n\r\n const firstSentence = `Your administrator requires ${methodLabel} multi factor authentication.`\r\n\r\n if (!isMethodEnabled) {\r\n return `${firstSentence} Setup ${methodLabel} to access this ${scope}`\r\n }\r\n\r\n if (!isMethodPreferred) {\r\n return `${firstSentence} Set ${methodLabel} as your preferred MFA method to access this ${scope}.`\r\n }\r\n\r\n return `${firstSentence} Now that ${methodLabel} is your preferred MFA method, you must log out and log back in to access this ${scope}.`\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oneblink/apps-react",
3
3
  "description": "Helper functions for OneBlink apps in ReactJS.",
4
- "version": "11.0.0-beta.10",
4
+ "version": "11.0.0-beta.11",
5
5
  "author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/oneblink/apps-react/issues"