@oneblink/apps-react 10.3.1 → 11.0.0-beta.1
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.
- package/dist/apps/auth-service.d.ts +3 -2
- package/dist/apps/auth-service.js +2 -2
- package/dist/apps/auth-service.js.map +1 -1
- package/dist/apps/services/AWSCognitoClient.d.ts +39 -4
- package/dist/apps/services/AWSCognitoClient.js +238 -23
- package/dist/apps/services/AWSCognitoClient.js.map +1 -1
- package/dist/apps/services/cognito.d.ts +50 -41
- package/dist/apps/services/cognito.js +85 -48
- package/dist/apps/services/cognito.js.map +1 -1
- package/dist/components/mfa/MfaAuthenticatorAppDialog.d.ts +12 -0
- package/dist/components/mfa/MfaAuthenticatorAppDialog.js +64 -0
- package/dist/components/mfa/MfaAuthenticatorAppDialog.js.map +1 -0
- package/dist/components/mfa/MfaDisableDialog.d.ts +10 -0
- package/dist/components/mfa/MfaDisableDialog.js +31 -0
- package/dist/components/mfa/MfaDisableDialog.js.map +1 -0
- package/dist/components/mfa/MfaErrorSnackbar.d.ts +10 -0
- package/dist/components/mfa/MfaErrorSnackbar.js +17 -0
- package/dist/components/mfa/MfaErrorSnackbar.js.map +1 -0
- package/dist/components/mfa/MfaMethodRow.d.ts +19 -0
- package/dist/components/mfa/MfaMethodRow.js +10 -0
- package/dist/components/mfa/MfaMethodRow.js.map +1 -0
- package/dist/components/mfa/MfaPhoneNumberDialog.d.ts +11 -0
- package/dist/components/mfa/MfaPhoneNumberDialog.js +120 -0
- package/dist/components/mfa/MfaPhoneNumberDialog.js.map +1 -0
- package/dist/components/mfa/MfaRemovePhoneNumberDialog.d.ts +10 -0
- package/dist/components/mfa/MfaRemovePhoneNumberDialog.js +24 -0
- package/dist/components/mfa/MfaRemovePhoneNumberDialog.js.map +1 -0
- package/dist/components/mfa/MfaStatusChip.d.ts +10 -0
- package/dist/components/mfa/MfaStatusChip.js +29 -0
- package/dist/components/mfa/MfaStatusChip.js.map +1 -0
- package/dist/components/mfa/MfaSuccessSnackbar.d.ts +10 -0
- package/dist/components/mfa/MfaSuccessSnackbar.js +17 -0
- package/dist/components/mfa/MfaSuccessSnackbar.js.map +1 -0
- package/dist/components/mfa/MultiFactorAuthentication.d.ts +1 -2
- package/dist/components/mfa/MultiFactorAuthentication.js +30 -30
- package/dist/components/mfa/MultiFactorAuthentication.js.map +1 -1
- package/dist/hooks/useLogin.d.ts +14 -8
- package/dist/hooks/useLogin.js +16 -6
- package/dist/hooks/useLogin.js.map +1 -1
- package/dist/hooks/useMfa.d.ts +46 -14
- package/dist/hooks/useMfa.js +388 -43
- package/dist/hooks/useMfa.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/components/mfa/MfaDialog.d.ts +0 -9
- package/dist/components/mfa/MfaDialog.js +0 -47
- package/dist/components/mfa/MfaDialog.js.map +0 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { MiscTypes } from '@oneblink/types';
|
|
2
2
|
import { getIdToken, getFormsKeyId, setFormsKeyToken } from './services/forms-key';
|
|
3
|
-
import { registerAuthListener, isLoggedIn, loginHostedUI, loginUsernamePassword, changePassword, forgotPassword, handleAuthentication, logoutHostedUI, getUserProfile, getUserFriendlyName, LoginAttemptResponse, checkIsMfaEnabled,
|
|
3
|
+
import { registerAuthListener, isLoggedIn, loginHostedUI, loginUsernamePassword, changePassword, forgotPassword, handleAuthentication, logoutHostedUI, getUserProfile, getUserFriendlyName, LoginAttemptResponse, MfaMethod, MfaRequirementCheckResult, MfaSettings, checkIsMfaEnabled, getMfaSettings, updateUserPhoneNumber, removeUserPhoneNumber, sendPhoneNumberVerificationCode, verifyUserPhoneNumber, disableMfaMethod, setPreferredMfaMethod, setupMfaAuthenticatorApp, setupSmsMfa, generateMfaAuthenticatorAppQrCodeUrl, DEFAULT_MFA_SETTINGS } from './services/cognito';
|
|
4
4
|
import { getUserToken, setUserToken } from './services/user-token';
|
|
5
|
-
export { registerAuthListener, loginHostedUI, loginUsernamePassword, handleAuthentication, logoutHostedUI, changePassword, forgotPassword, isLoggedIn, getIdToken, getUserProfile, getFormsKeyId, setFormsKeyToken, getUserToken, setUserToken, getUserFriendlyName,
|
|
5
|
+
export { registerAuthListener, loginHostedUI, loginUsernamePassword, handleAuthentication, logoutHostedUI, changePassword, forgotPassword, isLoggedIn, getIdToken, getUserProfile, getFormsKeyId, setFormsKeyToken, getUserToken, setUserToken, getUserFriendlyName, checkIsMfaEnabled, getMfaSettings, updateUserPhoneNumber, removeUserPhoneNumber, sendPhoneNumberVerificationCode, verifyUserPhoneNumber, disableMfaMethod, setPreferredMfaMethod, setupMfaAuthenticatorApp, setupSmsMfa, generateMfaAuthenticatorAppQrCodeUrl, DEFAULT_MFA_SETTINGS, };
|
|
6
|
+
export type { LoginAttemptResponse, MfaMethod, MfaRequirementCheckResult, MfaSettings, };
|
|
6
7
|
/**
|
|
7
8
|
* Log the current user out and remove an data stored locally by the user e.g.
|
|
8
9
|
* drafts.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import OneBlinkAppsError from './services/errors/oneBlinkAppsError';
|
|
2
2
|
import { getIdToken, getFormsKeyId, setFormsKeyToken, } from './services/forms-key';
|
|
3
|
-
import { init as initCognito, registerAuthListener, isLoggedIn, loginHostedUI, loginUsernamePassword, changePassword, forgotPassword, handleAuthentication, logoutHostedUI, logout as logoutCognito, getUserProfile, getUsername, getUserFriendlyName, checkIsMfaEnabled,
|
|
3
|
+
import { init as initCognito, registerAuthListener, isLoggedIn, loginHostedUI, loginUsernamePassword, changePassword, forgotPassword, handleAuthentication, logoutHostedUI, logout as logoutCognito, getUserProfile, getUsername, getUserFriendlyName, checkIsMfaEnabled, getMfaSettings, updateUserPhoneNumber, removeUserPhoneNumber, sendPhoneNumberVerificationCode, verifyUserPhoneNumber, disableMfaMethod, setPreferredMfaMethod, setupMfaAuthenticatorApp, setupSmsMfa, generateMfaAuthenticatorAppQrCodeUrl, DEFAULT_MFA_SETTINGS, } from './services/cognito';
|
|
4
4
|
import { getRequest, postRequest } from './services/fetch';
|
|
5
5
|
import tenants from './tenants';
|
|
6
6
|
import { getUserToken, setUserToken } from './services/user-token';
|
|
7
7
|
import utilsService from './services/utils';
|
|
8
|
-
export { registerAuthListener, loginHostedUI, loginUsernamePassword, handleAuthentication, logoutHostedUI, changePassword, forgotPassword, isLoggedIn, getIdToken, getUserProfile, getFormsKeyId, setFormsKeyToken, getUserToken, setUserToken, getUserFriendlyName, checkIsMfaEnabled,
|
|
8
|
+
export { registerAuthListener, loginHostedUI, loginUsernamePassword, handleAuthentication, logoutHostedUI, changePassword, forgotPassword, isLoggedIn, getIdToken, getUserProfile, getFormsKeyId, setFormsKeyToken, getUserToken, setUserToken, getUserFriendlyName, checkIsMfaEnabled, getMfaSettings, updateUserPhoneNumber, removeUserPhoneNumber, sendPhoneNumberVerificationCode, verifyUserPhoneNumber, disableMfaMethod, setPreferredMfaMethod, setupMfaAuthenticatorApp, setupSmsMfa, generateMfaAuthenticatorAppQrCodeUrl, DEFAULT_MFA_SETTINGS, };
|
|
9
9
|
import Sentry from './Sentry';
|
|
10
10
|
/**
|
|
11
11
|
* Log the current user out and remove an data stored locally by the user e.g.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-service.js","sourceRoot":"","sources":["../../src/apps/auth-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { MiscTypes } from '@oneblink/types'\nimport OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport {\n getIdToken,\n getFormsKeyId,\n setFormsKeyToken,\n} from './services/forms-key'\nimport {\n init as initCognito,\n registerAuthListener,\n isLoggedIn,\n loginHostedUI,\n loginUsernamePassword,\n changePassword,\n forgotPassword,\n handleAuthentication,\n logoutHostedUI,\n logout as logoutCognito,\n getUserProfile,\n getUsername,\n getUserFriendlyName,\n LoginAttemptResponse,\n checkIsMfaEnabled,\n disableMfa,\n setupMfa,\n generateMfaQrCodeUrl,\n} from './services/cognito'\nimport { getRequest, postRequest, HTTPError } from './services/fetch'\nimport tenants from './tenants'\nimport { getUserToken, setUserToken } from './services/user-token'\nimport utilsService from './services/utils'\n\nexport {\n registerAuthListener,\n loginHostedUI,\n loginUsernamePassword,\n handleAuthentication,\n logoutHostedUI,\n changePassword,\n forgotPassword,\n isLoggedIn,\n getIdToken,\n getUserProfile,\n getFormsKeyId,\n setFormsKeyToken,\n getUserToken,\n setUserToken,\n getUserFriendlyName,\n LoginAttemptResponse,\n checkIsMfaEnabled,\n disableMfa,\n setupMfa,\n generateMfaQrCodeUrl,\n}\nimport Sentry from './Sentry'\n\n/**\n * Log the current user out and remove an data stored locally by the user e.g.\n * drafts.\n *\n * #### Example\n *\n * ```js\n * await authService.logout()\n * ```\n */\nexport async function logout() {\n console.log('Logging out...')\n\n try {\n await utilsService.localForage.clear()\n } catch (error) {\n Sentry.captureException(error)\n console.warn('Could not clear localForage before logging out', error)\n }\n\n await logoutCognito()\n}\n\n/**\n * Initialize the service with required configuration. **This must be done\n * before using before some of the function in this service.**\n *\n * #### Example\n *\n * ```js\n * authService.init({\n * oAuthClientId: 'YOUR_OAUTH_CLIENT_ID',\n * })\n * ```\n *\n * @param options\n */\nexport function init({ oAuthClientId }: { oAuthClientId: string }) {\n initCognito({\n region: tenants.current.awsRegion,\n loginDomain: tenants.current.loginDomain,\n oAuthClientId,\n redirectUri: window.location.origin + '/callback',\n logoutUri: window.location.origin + '/logout',\n })\n\n const listener = () => {\n Sentry.setTag('username', getUsername() || undefined)\n }\n listener()\n registerAuthListener(listener)\n}\n\n/**\n * Determine if the current user is a OneBlink App User for a OneBlink Forms\n * App. Returns `false` if the current user is not logged in.\n *\n * #### Example\n *\n * ```js\n * const formsAppId = 1\n * const isAuthorised = await authService.isAuthorised(formsAppId)\n * if (!isAuthorised) {\n * // handle unauthorised user\n * }\n * ```\n *\n * @param formsAppId\n * @param abortSignal\n * @returns\n */\nexport async function isAuthorised(\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<boolean> {\n return getCurrentFormsAppUser(formsAppId, abortSignal)\n .then(() => true)\n .catch((error) => {\n if (error.status >= 400 && error.status < 500) {\n return false\n } else {\n Sentry.captureException(error)\n console.log(\n 'Could not determine if the current user has access to this forms app',\n error,\n )\n return false\n }\n })\n}\n\n/**\n * Get the current user's App User details for a OneBlink Forms App. Returns\n * `undefined` if the current user is not logged in.\n *\n * #### Example\n *\n * ```js\n * const formsAppId = 1\n * const formsAppUserDetails =\n * await authService.getCurrentFormsAppUser(formsAppId)\n * if (!formsAppUserDetails) {\n * // handle unauthorised user\n * }\n * ```\n *\n * @param formsAppId\n * @returns\n */\nexport async function getCurrentFormsAppUser(\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<\n | {\n userProfile?: MiscTypes.UserProfile\n formsAppId: number\n groups: string[]\n }\n | undefined\n> {\n if (getFormsKeyId()) {\n return {\n formsAppId,\n groups: [],\n }\n }\n\n const userProfile = getUserProfile()\n\n if (!userProfile) {\n return undefined\n }\n\n const url = `${tenants.current.apiOrigin}/forms-apps/${formsAppId}/my-forms-app-user`\n return await getRequest<{\n userProfile?: MiscTypes.UserProfile\n formsAppId: number\n groups: string[]\n }>(url, abortSignal)\n}\n\n/**\n * If the current user is not a Forms App User, this function will send a\n * request on behalf of the current user to the OneBlink Forms App\n * administrators to request access.\n *\n * #### Example\n *\n * ```js\n * const formsAppId = 1\n * await authService.requestAccess(formsAppId)\n * // Display a message to user indicating a request has been sent to the application administrators\n * ```\n *\n * @param formsAppId\n */\nexport async function requestAccess(formsAppId: number): Promise<void> {\n if (!isLoggedIn()) {\n throw new OneBlinkAppsError(\n 'You must login before requesting access to this application',\n {\n requiresLogin: true,\n },\n )\n }\n\n try {\n const url = `${tenants.current.apiOrigin}/forms-apps/${formsAppId}/request-access`\n await postRequest(url)\n } catch (error) {\n Sentry.captureException(error)\n console.warn('Error while requesting access to forms app', error)\n\n throw new OneBlinkAppsError(\n 'Sorry, we could not request access automatically right now, please try again. If the problem persists, please contact your administrator yourself.',\n {\n originalError: error as Error,\n title: 'Error Requesting Access',\n httpStatusCode: (error as HTTPError).status,\n },\n )\n }\n}\n\n/**\n * Allow a user to sign up to a forms app.\n *\n * #### Example\n *\n * ```js\n * await authService.signUp({\n * formsAppId: 1,\n * email: 'test@oneblink.io',\n * firstName: 'first',\n * lastName: 'last',\n * })\n * ```\n *\n * @param {formsAppId, email, generatePassword, firstName, lastName}\n * @returns\n */\n\nexport async function signUp({\n formsAppId,\n email,\n firstName,\n lastName,\n}: {\n formsAppId: number\n email: string\n firstName?: string\n lastName?: string\n}): Promise<void> {\n try {\n const url = `${tenants.current.apiOrigin}/forms-apps/${formsAppId}/sign-up`\n return await postRequest(url, {\n email,\n firstName,\n lastName,\n })\n } catch (error) {\n Sentry.captureException(error)\n console.warn('Error while calling sign-up to forms app', error)\n\n throw new OneBlinkAppsError(\n 'Sorry, we could not create you a account right now, please try again. If the problem persists, please contact your administrator yourself.',\n {\n originalError: error as Error,\n title: 'Error Signing up',\n httpStatusCode: (error as HTTPError).status,\n },\n )\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"auth-service.js","sourceRoot":"","sources":["../../src/apps/auth-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { MiscTypes } from '@oneblink/types'\nimport OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport {\n getIdToken,\n getFormsKeyId,\n setFormsKeyToken,\n} from './services/forms-key'\nimport {\n init as initCognito,\n registerAuthListener,\n isLoggedIn,\n loginHostedUI,\n loginUsernamePassword,\n changePassword,\n forgotPassword,\n handleAuthentication,\n logoutHostedUI,\n logout as logoutCognito,\n getUserProfile,\n getUsername,\n getUserFriendlyName,\n LoginAttemptResponse,\n MfaMethod,\n MfaRequirementCheckResult,\n MfaSettings,\n checkIsMfaEnabled,\n getMfaSettings,\n updateUserPhoneNumber,\n removeUserPhoneNumber,\n sendPhoneNumberVerificationCode,\n verifyUserPhoneNumber,\n disableMfaMethod,\n setPreferredMfaMethod,\n setupMfaAuthenticatorApp,\n setupSmsMfa,\n generateMfaAuthenticatorAppQrCodeUrl,\n DEFAULT_MFA_SETTINGS,\n} from './services/cognito'\nimport { getRequest, postRequest, HTTPError } from './services/fetch'\nimport tenants from './tenants'\nimport { getUserToken, setUserToken } from './services/user-token'\nimport utilsService from './services/utils'\n\nexport {\n registerAuthListener,\n loginHostedUI,\n loginUsernamePassword,\n handleAuthentication,\n logoutHostedUI,\n changePassword,\n forgotPassword,\n isLoggedIn,\n getIdToken,\n getUserProfile,\n getFormsKeyId,\n setFormsKeyToken,\n getUserToken,\n setUserToken,\n getUserFriendlyName,\n checkIsMfaEnabled,\n getMfaSettings,\n updateUserPhoneNumber,\n removeUserPhoneNumber,\n sendPhoneNumberVerificationCode,\n verifyUserPhoneNumber,\n disableMfaMethod,\n setPreferredMfaMethod,\n setupMfaAuthenticatorApp,\n setupSmsMfa,\n generateMfaAuthenticatorAppQrCodeUrl,\n DEFAULT_MFA_SETTINGS,\n}\nexport type {\n LoginAttemptResponse,\n MfaMethod,\n MfaRequirementCheckResult,\n MfaSettings,\n}\nimport Sentry from './Sentry'\n\n/**\n * Log the current user out and remove an data stored locally by the user e.g.\n * drafts.\n *\n * #### Example\n *\n * ```js\n * await authService.logout()\n * ```\n */\nexport async function logout() {\n console.log('Logging out...')\n\n try {\n await utilsService.localForage.clear()\n } catch (error) {\n Sentry.captureException(error)\n console.warn('Could not clear localForage before logging out', error)\n }\n\n await logoutCognito()\n}\n\n/**\n * Initialize the service with required configuration. **This must be done\n * before using before some of the function in this service.**\n *\n * #### Example\n *\n * ```js\n * authService.init({\n * oAuthClientId: 'YOUR_OAUTH_CLIENT_ID',\n * })\n * ```\n *\n * @param options\n */\nexport function init({ oAuthClientId }: { oAuthClientId: string }) {\n initCognito({\n region: tenants.current.awsRegion,\n loginDomain: tenants.current.loginDomain,\n oAuthClientId,\n redirectUri: window.location.origin + '/callback',\n logoutUri: window.location.origin + '/logout',\n })\n\n const listener = () => {\n Sentry.setTag('username', getUsername() || undefined)\n }\n listener()\n registerAuthListener(listener)\n}\n\n/**\n * Determine if the current user is a OneBlink App User for a OneBlink Forms\n * App. Returns `false` if the current user is not logged in.\n *\n * #### Example\n *\n * ```js\n * const formsAppId = 1\n * const isAuthorised = await authService.isAuthorised(formsAppId)\n * if (!isAuthorised) {\n * // handle unauthorised user\n * }\n * ```\n *\n * @param formsAppId\n * @param abortSignal\n * @returns\n */\nexport async function isAuthorised(\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<boolean> {\n return getCurrentFormsAppUser(formsAppId, abortSignal)\n .then(() => true)\n .catch((error) => {\n if (error.status >= 400 && error.status < 500) {\n return false\n } else {\n Sentry.captureException(error)\n console.log(\n 'Could not determine if the current user has access to this forms app',\n error,\n )\n return false\n }\n })\n}\n\n/**\n * Get the current user's App User details for a OneBlink Forms App. Returns\n * `undefined` if the current user is not logged in.\n *\n * #### Example\n *\n * ```js\n * const formsAppId = 1\n * const formsAppUserDetails =\n * await authService.getCurrentFormsAppUser(formsAppId)\n * if (!formsAppUserDetails) {\n * // handle unauthorised user\n * }\n * ```\n *\n * @param formsAppId\n * @returns\n */\nexport async function getCurrentFormsAppUser(\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<\n | {\n userProfile?: MiscTypes.UserProfile\n formsAppId: number\n groups: string[]\n }\n | undefined\n> {\n if (getFormsKeyId()) {\n return {\n formsAppId,\n groups: [],\n }\n }\n\n const userProfile = getUserProfile()\n\n if (!userProfile) {\n return undefined\n }\n\n const url = `${tenants.current.apiOrigin}/forms-apps/${formsAppId}/my-forms-app-user`\n return await getRequest<{\n userProfile?: MiscTypes.UserProfile\n formsAppId: number\n groups: string[]\n }>(url, abortSignal)\n}\n\n/**\n * If the current user is not a Forms App User, this function will send a\n * request on behalf of the current user to the OneBlink Forms App\n * administrators to request access.\n *\n * #### Example\n *\n * ```js\n * const formsAppId = 1\n * await authService.requestAccess(formsAppId)\n * // Display a message to user indicating a request has been sent to the application administrators\n * ```\n *\n * @param formsAppId\n */\nexport async function requestAccess(formsAppId: number): Promise<void> {\n if (!isLoggedIn()) {\n throw new OneBlinkAppsError(\n 'You must login before requesting access to this application',\n {\n requiresLogin: true,\n },\n )\n }\n\n try {\n const url = `${tenants.current.apiOrigin}/forms-apps/${formsAppId}/request-access`\n await postRequest(url)\n } catch (error) {\n Sentry.captureException(error)\n console.warn('Error while requesting access to forms app', error)\n\n throw new OneBlinkAppsError(\n 'Sorry, we could not request access automatically right now, please try again. If the problem persists, please contact your administrator yourself.',\n {\n originalError: error as Error,\n title: 'Error Requesting Access',\n httpStatusCode: (error as HTTPError).status,\n },\n )\n }\n}\n\n/**\n * Allow a user to sign up to a forms app.\n *\n * #### Example\n *\n * ```js\n * await authService.signUp({\n * formsAppId: 1,\n * email: 'test@oneblink.io',\n * firstName: 'first',\n * lastName: 'last',\n * })\n * ```\n *\n * @param {formsAppId, email, generatePassword, firstName, lastName}\n * @returns\n */\n\nexport async function signUp({\n formsAppId,\n email,\n firstName,\n lastName,\n}: {\n formsAppId: number\n email: string\n firstName?: string\n lastName?: string\n}): Promise<void> {\n try {\n const url = `${tenants.current.apiOrigin}/forms-apps/${formsAppId}/sign-up`\n return await postRequest(url, {\n email,\n firstName,\n lastName,\n })\n } catch (error) {\n Sentry.captureException(error)\n console.warn('Error while calling sign-up to forms app', error)\n\n throw new OneBlinkAppsError(\n 'Sorry, we could not create you a account right now, please try again. If the problem persists, please contact your administrator yourself.',\n {\n originalError: error as Error,\n title: 'Error Signing up',\n httpStatusCode: (error as HTTPError).status,\n },\n )\n }\n}\n"]}
|
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
import { AuthenticationResultType, CognitoIdentityProviderClient, InitiateAuthResponse } from '@aws-sdk/client-cognito-identity-provider';
|
|
2
|
+
import { MiscTypes } from '@oneblink/types';
|
|
3
|
+
export type MfaMethod = 'authenticator' | 'sms';
|
|
4
|
+
export type MfaSettings = {
|
|
5
|
+
authenticator: {
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
preferred: boolean;
|
|
8
|
+
};
|
|
9
|
+
sms: {
|
|
10
|
+
enabled: boolean;
|
|
11
|
+
preferred: boolean;
|
|
12
|
+
phoneNumber: string | undefined;
|
|
13
|
+
isPhoneNumberVerified: boolean;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare const DEFAULT_MFA_SETTINGS: MfaSettings;
|
|
17
|
+
export type MfaRequirementCheckResult = {
|
|
18
|
+
mfaSettings: MfaSettings;
|
|
19
|
+
userMeetsMfaRequirement: boolean;
|
|
20
|
+
};
|
|
2
21
|
export type LoginAttemptResponse = {
|
|
3
22
|
resetPasswordCallback?: (newPassword: string) => Promise<LoginAttemptResponse>;
|
|
4
|
-
|
|
23
|
+
mfa?: {
|
|
24
|
+
codeCallback: (code: string) => Promise<LoginAttemptResponse>;
|
|
25
|
+
method: MfaMethod;
|
|
26
|
+
};
|
|
5
27
|
};
|
|
6
28
|
export default class AWSCognitoClient {
|
|
7
29
|
clientId: string;
|
|
@@ -46,9 +68,22 @@ export default class AWSCognitoClient {
|
|
|
46
68
|
logout(): Promise<void>;
|
|
47
69
|
getIdToken(): Promise<string | undefined>;
|
|
48
70
|
getAccessToken(): Promise<string | undefined>;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
71
|
+
getMfaSettings(abortSignal?: AbortSignal): Promise<MfaSettings>;
|
|
72
|
+
checkIsMfaEnabled(mfaRequirement: MiscTypes.MfaRequirement | undefined): Promise<MfaRequirementCheckResult>;
|
|
73
|
+
updateUserPhoneNumber(phoneNumber: string): Promise<{
|
|
74
|
+
isPhoneNumberVerified: boolean;
|
|
75
|
+
}>;
|
|
76
|
+
removeUserPhoneNumber(): Promise<void>;
|
|
77
|
+
sendPhoneNumberVerificationCode(): Promise<import("@aws-sdk/client-cognito-identity-provider").GetUserAttributeVerificationCodeCommandOutput | undefined>;
|
|
78
|
+
verifyUserPhoneNumber(code: string): Promise<void>;
|
|
79
|
+
setPreferredMfaMethod(method: MfaMethod): Promise<void>;
|
|
80
|
+
disableMfaMethod(method: MfaMethod): Promise<void>;
|
|
81
|
+
setupSmsMfa({ preferred }?: {
|
|
82
|
+
preferred?: boolean;
|
|
83
|
+
}): Promise<void>;
|
|
84
|
+
setupMfaAuthenticatorApp({ preferred }?: {
|
|
85
|
+
preferred?: boolean;
|
|
86
|
+
}): Promise<{
|
|
52
87
|
secretCode: string | undefined;
|
|
53
88
|
mfaCodeCallback: (code: string) => Promise<void>;
|
|
54
89
|
} | undefined>;
|
|
@@ -1,6 +1,29 @@
|
|
|
1
|
-
import { AssociateSoftwareTokenCommand, ChangePasswordCommand, CognitoIdentityProviderClient, ConfirmForgotPasswordCommand, GetUserCommand, GlobalSignOutCommand, InitiateAuthCommand, RespondToAuthChallengeCommand, SetUserMFAPreferenceCommand, VerifySoftwareTokenCommand, } from '@aws-sdk/client-cognito-identity-provider';
|
|
1
|
+
import { AssociateSoftwareTokenCommand, ChangePasswordCommand, CognitoIdentityProviderClient, ConfirmForgotPasswordCommand, DeleteUserAttributesCommand, GetUserAttributeVerificationCodeCommand, GetUserCommand, GlobalSignOutCommand, InitiateAuthCommand, RespondToAuthChallengeCommand, SetUserMFAPreferenceCommand, UpdateUserAttributesCommand, VerifySoftwareTokenCommand, VerifyUserAttributeCommand, } from '@aws-sdk/client-cognito-identity-provider';
|
|
2
2
|
import Sentry from '../Sentry';
|
|
3
3
|
import { OneBlinkAppsError } from '..';
|
|
4
|
+
export const DEFAULT_MFA_SETTINGS = {
|
|
5
|
+
authenticator: { enabled: false, preferred: false },
|
|
6
|
+
sms: {
|
|
7
|
+
enabled: false,
|
|
8
|
+
preferred: false,
|
|
9
|
+
phoneNumber: undefined,
|
|
10
|
+
isPhoneNumberVerified: false,
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
const MFA_REQUIREMENT_METHOD_CHECKS = {
|
|
14
|
+
sms: (mfaSettings) => mfaSettings.sms.enabled,
|
|
15
|
+
authenticatorApp: (mfaSettings) => mfaSettings.authenticator.enabled,
|
|
16
|
+
};
|
|
17
|
+
function checkUserMeetsMfaRequirement(mfaRequirement, mfaSettings) {
|
|
18
|
+
if (!mfaRequirement) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
const requiredMethods = Object.keys(MFA_REQUIREMENT_METHOD_CHECKS).filter((method) => mfaRequirement[method]);
|
|
22
|
+
if (requiredMethods.length === 0) {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return requiredMethods.some((method) => MFA_REQUIREMENT_METHOD_CHECKS[method](mfaSettings));
|
|
26
|
+
}
|
|
4
27
|
export default class AWSCognitoClient {
|
|
5
28
|
constructor({ clientId, region, loginDomain, redirectUri, logoutUri, }) {
|
|
6
29
|
if (!clientId) {
|
|
@@ -146,17 +169,42 @@ export default class AWSCognitoClient {
|
|
|
146
169
|
}
|
|
147
170
|
case 'SOFTWARE_TOKEN_MFA': {
|
|
148
171
|
return {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
172
|
+
mfa: {
|
|
173
|
+
method: 'authenticator',
|
|
174
|
+
codeCallback: async (code) => {
|
|
175
|
+
const resetPasswordResult = await this.cognitoIdentityProviderClient.send(new RespondToAuthChallengeCommand({
|
|
176
|
+
ChallengeName,
|
|
177
|
+
ClientId: this.clientId,
|
|
178
|
+
Session: initiateAuthResponse.Session,
|
|
179
|
+
ChallengeResponses: {
|
|
180
|
+
USERNAME: username,
|
|
181
|
+
SOFTWARE_TOKEN_MFA_CODE: code,
|
|
182
|
+
},
|
|
183
|
+
}));
|
|
184
|
+
return await this.responseToAuthChallenge(username, resetPasswordResult);
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
case 'EMAIL_OTP': {
|
|
190
|
+
throw new Error('Email OTP is not supported');
|
|
191
|
+
}
|
|
192
|
+
case 'SMS_MFA': {
|
|
193
|
+
return {
|
|
194
|
+
mfa: {
|
|
195
|
+
method: 'sms',
|
|
196
|
+
codeCallback: async (code) => {
|
|
197
|
+
const smsChallengeResult = await this.cognitoIdentityProviderClient.send(new RespondToAuthChallengeCommand({
|
|
198
|
+
ChallengeName,
|
|
199
|
+
ClientId: this.clientId,
|
|
200
|
+
Session: initiateAuthResponse.Session,
|
|
201
|
+
ChallengeResponses: {
|
|
202
|
+
USERNAME: username,
|
|
203
|
+
SMS_MFA_CODE: code,
|
|
204
|
+
},
|
|
205
|
+
}));
|
|
206
|
+
return await this.responseToAuthChallenge(username, smsChallengeResult);
|
|
207
|
+
},
|
|
160
208
|
},
|
|
161
209
|
};
|
|
162
210
|
}
|
|
@@ -315,31 +363,185 @@ export default class AWSCognitoClient {
|
|
|
315
363
|
await this._refreshSession();
|
|
316
364
|
return this._getAccessToken();
|
|
317
365
|
}
|
|
318
|
-
async
|
|
319
|
-
var _a;
|
|
366
|
+
async getMfaSettings(abortSignal) {
|
|
367
|
+
var _a, _b, _c, _d;
|
|
320
368
|
const accessToken = await this.getAccessToken();
|
|
321
369
|
if (!accessToken) {
|
|
322
|
-
return
|
|
370
|
+
return DEFAULT_MFA_SETTINGS;
|
|
323
371
|
}
|
|
324
372
|
const user = await this.cognitoIdentityProviderClient.send(new GetUserCommand({
|
|
325
373
|
AccessToken: accessToken,
|
|
374
|
+
}), { abortSignal });
|
|
375
|
+
const mfaList = user.UserMFASettingList || [];
|
|
376
|
+
const preferredMfaSetting = user.PreferredMfaSetting;
|
|
377
|
+
const phoneNumber = (_b = (_a = user.UserAttributes) === null || _a === void 0 ? void 0 : _a.find((attribute) => attribute.Name === 'phone_number')) === null || _b === void 0 ? void 0 : _b.Value;
|
|
378
|
+
const isPhoneNumberVerified = ((_d = (_c = user.UserAttributes) === null || _c === void 0 ? void 0 : _c.find((attribute) => attribute.Name === 'phone_number_verified')) === null || _d === void 0 ? void 0 : _d.Value) === 'true';
|
|
379
|
+
return {
|
|
380
|
+
authenticator: {
|
|
381
|
+
enabled: mfaList.includes('SOFTWARE_TOKEN_MFA'),
|
|
382
|
+
preferred: preferredMfaSetting === 'SOFTWARE_TOKEN_MFA',
|
|
383
|
+
},
|
|
384
|
+
sms: {
|
|
385
|
+
enabled: mfaList.includes('SMS_MFA'),
|
|
386
|
+
preferred: preferredMfaSetting === 'SMS_MFA',
|
|
387
|
+
phoneNumber,
|
|
388
|
+
isPhoneNumberVerified,
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
async checkIsMfaEnabled(mfaRequirement) {
|
|
393
|
+
const mfaSettings = await this.getMfaSettings();
|
|
394
|
+
return {
|
|
395
|
+
mfaSettings,
|
|
396
|
+
userMeetsMfaRequirement: checkUserMeetsMfaRequirement(mfaRequirement, mfaSettings),
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
async updateUserPhoneNumber(phoneNumber) {
|
|
400
|
+
const accessToken = await this.getAccessToken();
|
|
401
|
+
if (!accessToken) {
|
|
402
|
+
return { isPhoneNumberVerified: false };
|
|
403
|
+
}
|
|
404
|
+
await this.cognitoIdentityProviderClient.send(new UpdateUserAttributesCommand({
|
|
405
|
+
AccessToken: accessToken,
|
|
406
|
+
UserAttributes: [
|
|
407
|
+
{
|
|
408
|
+
Name: 'phone_number',
|
|
409
|
+
Value: phoneNumber,
|
|
410
|
+
},
|
|
411
|
+
],
|
|
412
|
+
}));
|
|
413
|
+
const mfaSettings = await this.getMfaSettings();
|
|
414
|
+
return { isPhoneNumberVerified: mfaSettings.sms.isPhoneNumberVerified };
|
|
415
|
+
}
|
|
416
|
+
async removeUserPhoneNumber() {
|
|
417
|
+
const accessToken = await this.getAccessToken();
|
|
418
|
+
if (!accessToken) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
await this.cognitoIdentityProviderClient.send(new DeleteUserAttributesCommand({
|
|
422
|
+
AccessToken: accessToken,
|
|
423
|
+
UserAttributeNames: ['phone_number'],
|
|
424
|
+
}));
|
|
425
|
+
}
|
|
426
|
+
async sendPhoneNumberVerificationCode() {
|
|
427
|
+
const accessToken = await this.getAccessToken();
|
|
428
|
+
if (!accessToken) {
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
return await this.cognitoIdentityProviderClient.send(new GetUserAttributeVerificationCodeCommand({
|
|
432
|
+
AccessToken: accessToken,
|
|
433
|
+
AttributeName: 'phone_number',
|
|
434
|
+
}));
|
|
435
|
+
}
|
|
436
|
+
async verifyUserPhoneNumber(code) {
|
|
437
|
+
const accessToken = await this.getAccessToken();
|
|
438
|
+
if (!accessToken) {
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
await this.cognitoIdentityProviderClient.send(new VerifyUserAttributeCommand({
|
|
442
|
+
AccessToken: accessToken,
|
|
443
|
+
AttributeName: 'phone_number',
|
|
444
|
+
Code: code,
|
|
326
445
|
}));
|
|
327
|
-
return !!((_a = user.UserMFASettingList) === null || _a === void 0 ? void 0 : _a.length);
|
|
328
446
|
}
|
|
329
|
-
async
|
|
447
|
+
async setPreferredMfaMethod(method) {
|
|
330
448
|
const accessToken = await this.getAccessToken();
|
|
331
449
|
if (!accessToken) {
|
|
332
450
|
return;
|
|
333
451
|
}
|
|
452
|
+
const currentSettings = await this.getMfaSettings();
|
|
334
453
|
await this.cognitoIdentityProviderClient.send(new SetUserMFAPreferenceCommand({
|
|
335
|
-
SoftwareTokenMfaSettings: {
|
|
336
|
-
Enabled: false,
|
|
337
|
-
PreferredMfa: false,
|
|
338
|
-
},
|
|
339
454
|
AccessToken: accessToken,
|
|
455
|
+
...(currentSettings.authenticator.enabled
|
|
456
|
+
? {
|
|
457
|
+
SoftwareTokenMfaSettings: {
|
|
458
|
+
Enabled: true,
|
|
459
|
+
PreferredMfa: method === 'authenticator',
|
|
460
|
+
},
|
|
461
|
+
}
|
|
462
|
+
: {}),
|
|
463
|
+
...(currentSettings.sms.enabled
|
|
464
|
+
? {
|
|
465
|
+
SMSMfaSettings: {
|
|
466
|
+
Enabled: true,
|
|
467
|
+
PreferredMfa: method === 'sms',
|
|
468
|
+
},
|
|
469
|
+
}
|
|
470
|
+
: {}),
|
|
340
471
|
}));
|
|
341
472
|
}
|
|
342
|
-
async
|
|
473
|
+
async disableMfaMethod(method) {
|
|
474
|
+
const accessToken = await this.getAccessToken();
|
|
475
|
+
if (!accessToken) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
const currentSettings = await this.getMfaSettings();
|
|
479
|
+
const wasPreferred = method === 'authenticator'
|
|
480
|
+
? currentSettings.authenticator.preferred
|
|
481
|
+
: currentSettings.sms.preferred;
|
|
482
|
+
const otherMethod = method === 'authenticator' ? 'sms' : 'authenticator';
|
|
483
|
+
const otherSettings = method === 'authenticator'
|
|
484
|
+
? currentSettings.sms
|
|
485
|
+
: currentSettings.authenticator;
|
|
486
|
+
await this.cognitoIdentityProviderClient.send(new SetUserMFAPreferenceCommand({
|
|
487
|
+
AccessToken: accessToken,
|
|
488
|
+
...(method === 'authenticator'
|
|
489
|
+
? {
|
|
490
|
+
SoftwareTokenMfaSettings: {
|
|
491
|
+
Enabled: false,
|
|
492
|
+
PreferredMfa: false,
|
|
493
|
+
},
|
|
494
|
+
}
|
|
495
|
+
: {
|
|
496
|
+
SMSMfaSettings: {
|
|
497
|
+
Enabled: false,
|
|
498
|
+
PreferredMfa: false,
|
|
499
|
+
},
|
|
500
|
+
}),
|
|
501
|
+
...(wasPreferred && otherSettings.enabled
|
|
502
|
+
? otherMethod === 'authenticator'
|
|
503
|
+
? {
|
|
504
|
+
SoftwareTokenMfaSettings: {
|
|
505
|
+
Enabled: true,
|
|
506
|
+
PreferredMfa: true,
|
|
507
|
+
},
|
|
508
|
+
}
|
|
509
|
+
: {
|
|
510
|
+
SMSMfaSettings: {
|
|
511
|
+
Enabled: true,
|
|
512
|
+
PreferredMfa: true,
|
|
513
|
+
},
|
|
514
|
+
}
|
|
515
|
+
: {}),
|
|
516
|
+
}));
|
|
517
|
+
}
|
|
518
|
+
async setupSmsMfa({ preferred } = {}) {
|
|
519
|
+
const accessToken = await this.getAccessToken();
|
|
520
|
+
if (!accessToken) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
const currentSettings = await this.getMfaSettings();
|
|
524
|
+
const hasPreferredMethod = (currentSettings.authenticator.enabled &&
|
|
525
|
+
currentSettings.authenticator.preferred) ||
|
|
526
|
+
(currentSettings.sms.enabled && currentSettings.sms.preferred);
|
|
527
|
+
const shouldBePreferred = preferred !== null && preferred !== void 0 ? preferred : (!hasPreferredMethod && !currentSettings.sms.enabled);
|
|
528
|
+
await this.cognitoIdentityProviderClient.send(new SetUserMFAPreferenceCommand({
|
|
529
|
+
AccessToken: accessToken,
|
|
530
|
+
SMSMfaSettings: {
|
|
531
|
+
Enabled: true,
|
|
532
|
+
PreferredMfa: shouldBePreferred,
|
|
533
|
+
},
|
|
534
|
+
...(shouldBePreferred && currentSettings.authenticator.enabled
|
|
535
|
+
? {
|
|
536
|
+
SoftwareTokenMfaSettings: {
|
|
537
|
+
Enabled: true,
|
|
538
|
+
PreferredMfa: false,
|
|
539
|
+
},
|
|
540
|
+
}
|
|
541
|
+
: {}),
|
|
542
|
+
}));
|
|
543
|
+
}
|
|
544
|
+
async setupMfaAuthenticatorApp({ preferred } = {}) {
|
|
343
545
|
const accessToken = await this.getAccessToken();
|
|
344
546
|
if (!accessToken) {
|
|
345
547
|
return;
|
|
@@ -354,11 +556,24 @@ export default class AWSCognitoClient {
|
|
|
354
556
|
AccessToken: accessToken,
|
|
355
557
|
UserCode: code,
|
|
356
558
|
}));
|
|
559
|
+
const currentSettings = await this.getMfaSettings();
|
|
560
|
+
const hasPreferredMethod = (currentSettings.authenticator.enabled &&
|
|
561
|
+
currentSettings.authenticator.preferred) ||
|
|
562
|
+
(currentSettings.sms.enabled && currentSettings.sms.preferred);
|
|
563
|
+
const shouldBePreferred = preferred !== null && preferred !== void 0 ? preferred : (!hasPreferredMethod && !currentSettings.authenticator.enabled);
|
|
357
564
|
await this.cognitoIdentityProviderClient.send(new SetUserMFAPreferenceCommand({
|
|
358
565
|
SoftwareTokenMfaSettings: {
|
|
359
566
|
Enabled: true,
|
|
360
|
-
PreferredMfa:
|
|
567
|
+
PreferredMfa: shouldBePreferred,
|
|
361
568
|
},
|
|
569
|
+
...(shouldBePreferred && currentSettings.sms.enabled
|
|
570
|
+
? {
|
|
571
|
+
SMSMfaSettings: {
|
|
572
|
+
Enabled: true,
|
|
573
|
+
PreferredMfa: false,
|
|
574
|
+
},
|
|
575
|
+
}
|
|
576
|
+
: {}),
|
|
362
577
|
AccessToken: accessToken,
|
|
363
578
|
}));
|
|
364
579
|
},
|