@aws-amplify/ui-react-core 2.1.33 → 3.0.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/esm/Authenticator/context/AuthenticatorProvider.mjs +5 -6
- package/dist/esm/Authenticator/hooks/constants.mjs +4 -4
- package/dist/esm/Authenticator/hooks/useAuthenticator/useAuthenticator.mjs +14 -11
- package/dist/esm/Authenticator/hooks/useAuthenticator/utils.mjs +10 -18
- package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/constants.mjs +7 -4
- package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.mjs +6 -6
- package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/utils.mjs +47 -18
- package/dist/esm/Authenticator/hooks/utils.mjs +2 -2
- package/dist/esm/components/FormCore/FormProvider.mjs +15 -0
- package/dist/esm/components/FormCore/useField.mjs +20 -0
- package/dist/esm/components/FormCore/useForm.mjs +51 -0
- package/dist/esm/components/FormCore/withFormProvider.mjs +15 -0
- package/dist/esm/hooks/useSetUserAgent.mjs +15 -0
- package/dist/esm/hooks/useTimeout.mjs +22 -0
- package/dist/esm/index.mjs +7 -0
- package/dist/esm/utils/createContextUtilities.mjs +80 -0
- package/dist/index.js +284 -96
- package/dist/types/Authenticator/hooks/types.d.ts +10 -7
- package/dist/types/Authenticator/hooks/useAuthenticator/types.d.ts +1 -3
- package/dist/types/Authenticator/hooks/useAuthenticator/utils.d.ts +2 -3
- package/dist/types/Authenticator/hooks/useAuthenticatorRoute/types.d.ts +3 -3
- package/dist/types/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.d.ts +2 -2
- package/dist/types/Authenticator/hooks/useAuthenticatorRoute/utils.d.ts +2 -2
- package/dist/types/components/FormCore/FormProvider.d.ts +4 -0
- package/dist/types/components/FormCore/index.d.ts +5 -0
- package/dist/types/components/FormCore/types.d.ts +217 -0
- package/dist/types/components/FormCore/useControlledField.d.ts +9 -0
- package/dist/types/components/FormCore/useField.d.ts +9 -0
- package/dist/types/components/FormCore/useForm.d.ts +12 -0
- package/dist/types/components/FormCore/withFormProvider.d.ts +8 -0
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/hooks/index.d.ts +2 -0
- package/dist/types/hooks/useSetUserAgent.d.ts +2 -0
- package/dist/types/hooks/useTimeout.d.ts +4 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/types.d.ts +2 -0
- package/dist/types/utils/createContextUtilities.d.ts +26 -18
- package/package.json +11 -29
- package/src/Authenticator/context/AuthenticatorContext.tsx +17 -0
- package/src/Authenticator/context/AuthenticatorProvider.tsx +82 -0
- package/src/Authenticator/context/index.ts +2 -0
- package/src/Authenticator/hooks/constants.ts +30 -0
- package/src/Authenticator/hooks/index.ts +5 -0
- package/src/Authenticator/hooks/types.ts +218 -0
- package/src/Authenticator/hooks/useAuthenticator/__mock__/useAuthenticator.ts +66 -0
- package/src/Authenticator/hooks/useAuthenticator/constants.ts +2 -0
- package/src/Authenticator/hooks/useAuthenticator/index.ts +2 -0
- package/src/Authenticator/hooks/useAuthenticator/types.ts +48 -0
- package/src/Authenticator/hooks/useAuthenticator/useAuthenticator.ts +72 -0
- package/src/Authenticator/hooks/useAuthenticator/utils.ts +97 -0
- package/src/Authenticator/hooks/useAuthenticatorInitMachine/index.ts +1 -0
- package/src/Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.tsx +25 -0
- package/src/Authenticator/hooks/useAuthenticatorRoute/constants.ts +107 -0
- package/src/Authenticator/hooks/useAuthenticatorRoute/index.ts +2 -0
- package/src/Authenticator/hooks/useAuthenticatorRoute/types.ts +111 -0
- package/src/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.ts +126 -0
- package/src/Authenticator/hooks/useAuthenticatorRoute/utils.ts +204 -0
- package/src/Authenticator/hooks/utils.ts +38 -0
- package/src/Authenticator/index.ts +23 -0
- package/src/components/FormCore/FormProvider.tsx +37 -0
- package/src/components/FormCore/index.ts +13 -0
- package/src/components/FormCore/types.ts +277 -0
- package/src/components/FormCore/useControlledField.ts +73 -0
- package/src/components/FormCore/useField.ts +25 -0
- package/src/components/FormCore/useForm.ts +84 -0
- package/src/components/FormCore/withFormProvider.tsx +31 -0
- package/src/components/RenderNothing/RenderNothing.tsx +6 -0
- package/src/components/RenderNothing/index.ts +1 -0
- package/src/components/index.ts +15 -0
- package/src/hooks/index.ts +8 -0
- package/src/hooks/useDeprecationWarning.ts +27 -0
- package/src/hooks/useHasValueUpdated.ts +28 -0
- package/src/hooks/usePreviousValue.ts +15 -0
- package/src/hooks/useSetUserAgent.ts +18 -0
- package/src/hooks/useTimeout.ts +30 -0
- package/src/index.ts +48 -0
- package/src/types/index.ts +1 -0
- package/src/types/types.ts +3 -0
- package/src/utils/createContextUtilities.tsx +131 -0
- package/src/utils/index.ts +1 -0
- package/dist/esm/node_modules/tslib/tslib.es6.mjs +0 -38
package/dist/index.js
CHANGED
|
@@ -4,8 +4,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var react = require('@xstate/react');
|
|
7
|
-
var
|
|
7
|
+
var auth = require('aws-amplify/auth');
|
|
8
8
|
var ui = require('@aws-amplify/ui');
|
|
9
|
+
var reactHookForm = require('react-hook-form');
|
|
9
10
|
|
|
10
11
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
12
|
|
|
@@ -30,43 +31,6 @@ function _interopNamespace(e) {
|
|
|
30
31
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
31
32
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
32
33
|
|
|
33
|
-
/******************************************************************************
|
|
34
|
-
Copyright (c) Microsoft Corporation.
|
|
35
|
-
|
|
36
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
37
|
-
purpose with or without fee is hereby granted.
|
|
38
|
-
|
|
39
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
40
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
41
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
42
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
43
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
44
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
45
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
46
|
-
***************************************************************************** */
|
|
47
|
-
|
|
48
|
-
function __rest(s, e) {
|
|
49
|
-
var t = {};
|
|
50
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
51
|
-
t[p] = s[p];
|
|
52
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
53
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
54
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
55
|
-
t[p[i]] = s[p[i]];
|
|
56
|
-
}
|
|
57
|
-
return t;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
61
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
62
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
63
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
64
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
65
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
66
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
34
|
/**
|
|
71
35
|
* AuthenticatorContext serves static reference to the auth machine service.
|
|
72
36
|
*
|
|
@@ -74,9 +38,9 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
74
38
|
*/
|
|
75
39
|
const AuthenticatorContext = React__default["default"].createContext(null);
|
|
76
40
|
|
|
77
|
-
const createHubHandler = (options) => (data, service) =>
|
|
78
|
-
|
|
79
|
-
}
|
|
41
|
+
const createHubHandler = (options) => async (data, service) => {
|
|
42
|
+
await ui.defaultAuthHubHandler(data, service, options);
|
|
43
|
+
};
|
|
80
44
|
function AuthenticatorProvider({ children, }) {
|
|
81
45
|
// `authStatus` is exposed by `useAuthenticator` but should not be derived directly from the
|
|
82
46
|
// state machine as the machine only updates on `Authenticator` initiated events, which
|
|
@@ -85,7 +49,7 @@ function AuthenticatorProvider({ children, }) {
|
|
|
85
49
|
const [authStatus, setAuthStatus] = React__default["default"].useState('configuring');
|
|
86
50
|
// only run on first render
|
|
87
51
|
React__default["default"].useEffect(() => {
|
|
88
|
-
|
|
52
|
+
auth.getCurrentUser()
|
|
89
53
|
.then(() => {
|
|
90
54
|
setAuthStatus('authenticated');
|
|
91
55
|
})
|
|
@@ -125,8 +89,8 @@ const COMPONENT_ROUTE_KEYS = [
|
|
|
125
89
|
'confirmSignUp',
|
|
126
90
|
'confirmVerifyUser',
|
|
127
91
|
'forceNewPassword',
|
|
128
|
-
'
|
|
129
|
-
'
|
|
92
|
+
'forgotPassword',
|
|
93
|
+
'setupTotp',
|
|
130
94
|
'signIn',
|
|
131
95
|
'signUp',
|
|
132
96
|
'verifyUser',
|
|
@@ -137,8 +101,8 @@ const COMPONENT_ROUTE_NAMES = [
|
|
|
137
101
|
'ConfirmSignUp',
|
|
138
102
|
'ConfirmVerifyUser',
|
|
139
103
|
'ForceNewPassword',
|
|
140
|
-
'
|
|
141
|
-
'
|
|
104
|
+
'ForgotPassword',
|
|
105
|
+
'SetupTotp',
|
|
142
106
|
'SignIn',
|
|
143
107
|
'SignUp',
|
|
144
108
|
'VerifyUser',
|
|
@@ -153,7 +117,7 @@ function resolveAuthenticatorComponents(defaults, overrides) {
|
|
|
153
117
|
const Default = defaults[route];
|
|
154
118
|
const Override = overrides[route];
|
|
155
119
|
if (typeof Override !== 'function') {
|
|
156
|
-
return
|
|
120
|
+
return { ...components, [route]: Default };
|
|
157
121
|
}
|
|
158
122
|
const { Footer, FormFields, Header } = Default;
|
|
159
123
|
// cast to allow assigning of component slots
|
|
@@ -161,7 +125,7 @@ function resolveAuthenticatorComponents(defaults, overrides) {
|
|
|
161
125
|
Component.Footer = Footer;
|
|
162
126
|
Component.FormFields = FormFields;
|
|
163
127
|
Component.Header = Header;
|
|
164
|
-
return
|
|
128
|
+
return { ...components, [route]: Component };
|
|
165
129
|
}, {});
|
|
166
130
|
}
|
|
167
131
|
|
|
@@ -189,19 +153,13 @@ const getComparator = (selector) => (currentFacade, nextFacade) => {
|
|
|
189
153
|
// Shallow compare the array values
|
|
190
154
|
return areSelectorDepsEqual(currentSelectorDeps, nextSelectorDeps);
|
|
191
155
|
};
|
|
192
|
-
const getQRFields = (state) => {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
};
|
|
196
|
-
const
|
|
197
|
-
return
|
|
198
|
-
|
|
199
|
-
});
|
|
200
|
-
};
|
|
201
|
-
const flattenFormFields = (fields) => fields.flatMap(([name, options]) => (Object.assign({ name }, options)));
|
|
202
|
-
const convertContactMethodsToFields = (unverifiedContactMethods) => {
|
|
203
|
-
return (unverifiedContactMethods &&
|
|
204
|
-
Object.entries(unverifiedContactMethods).map(([name, value]) => {
|
|
156
|
+
const getQRFields = (state) => ({
|
|
157
|
+
...ui.getActorContext(state)?.formFields?.setupTotp?.QR,
|
|
158
|
+
});
|
|
159
|
+
const flattenFormFields = (fields) => fields.flatMap(([name, options]) => ({ name, ...options }));
|
|
160
|
+
const convertContactMethodsToFields = (unverifiedUserAttributes) => {
|
|
161
|
+
return (unverifiedUserAttributes &&
|
|
162
|
+
Object.entries(unverifiedUserAttributes).map(([name, value]) => {
|
|
205
163
|
const valueIsString = ui.isString(value);
|
|
206
164
|
if (!valueIsString || !name) {
|
|
207
165
|
return {};
|
|
@@ -213,10 +171,10 @@ const convertContactMethodsToFields = (unverifiedContactMethods) => {
|
|
|
213
171
|
* Retrieves default and custom (RWA only, to be updated) form field values from state machine
|
|
214
172
|
* for subcomponent routes that render fields
|
|
215
173
|
*/
|
|
216
|
-
const getMachineFields = (route, state,
|
|
174
|
+
const getMachineFields = (route, state, unverifiedUserAttributes) => {
|
|
217
175
|
if (isComponentRouteKey(route)) {
|
|
218
176
|
return route === 'verifyUser'
|
|
219
|
-
? convertContactMethodsToFields(
|
|
177
|
+
? convertContactMethodsToFields(unverifiedUserAttributes)
|
|
220
178
|
: flattenFormFields(ui.getSortedFormFields(route, state));
|
|
221
179
|
}
|
|
222
180
|
return [];
|
|
@@ -232,27 +190,116 @@ function useAuthenticator(selector) {
|
|
|
232
190
|
}
|
|
233
191
|
const { service } = context;
|
|
234
192
|
const { send } = service;
|
|
235
|
-
const xstateSelector = React.useCallback((state) => (
|
|
193
|
+
const xstateSelector = React.useCallback((state) => ({ ...ui.getServiceFacade({ send, state }) }), [send]);
|
|
236
194
|
const comparator = selector ? getComparator(selector) : defaultComparator;
|
|
237
195
|
// the purpose of `context.authStatus`is to intentionally override `facade.authStatus`. `facade.authStatus` does
|
|
238
196
|
// not update on external sign in events (for example when a user is not using the `Authenticator`).
|
|
239
197
|
const { authStatus } = context;
|
|
240
198
|
const facade = react.useSelector(service, xstateSelector, comparator);
|
|
241
|
-
const { route, totpSecretCode,
|
|
199
|
+
const { route, totpSecretCode, unverifiedUserAttributes, user, ...rest } = facade;
|
|
242
200
|
// do not memoize output. `service.getSnapshot` reference remains stable preventing
|
|
243
201
|
// `fields` from updating with current form state on value changes
|
|
244
202
|
const serviceSnapshot = service.getSnapshot();
|
|
245
|
-
// legacy `QRFields` values only used for
|
|
246
|
-
const QRFields = route === '
|
|
203
|
+
// legacy `QRFields` values only used for SetupTotp page to retrieve issuer information, will be removed in future
|
|
204
|
+
const QRFields = route === 'setupTotp' ? getQRFields(serviceSnapshot) : null;
|
|
247
205
|
// legacy `formFields` values required until form state is removed from state machine
|
|
248
|
-
const fields = getMachineFields(route, serviceSnapshot,
|
|
249
|
-
return
|
|
206
|
+
const fields = getMachineFields(route, serviceSnapshot, unverifiedUserAttributes);
|
|
207
|
+
return {
|
|
208
|
+
...rest,
|
|
209
|
+
authStatus,
|
|
250
210
|
route,
|
|
251
211
|
totpSecretCode,
|
|
252
|
-
|
|
212
|
+
unverifiedUserAttributes,
|
|
253
213
|
user,
|
|
254
214
|
/** @deprecated For internal use only */
|
|
255
|
-
fields,
|
|
215
|
+
fields,
|
|
216
|
+
QRFields,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const DEFAULT_ERROR_MESSAGE$1 = '`useForm` must be called inside a `FormProvider`';
|
|
221
|
+
/**
|
|
222
|
+
* Utility hook corresponding to `FormProvider`, must be used within a `FormProvider`
|
|
223
|
+
*
|
|
224
|
+
* @internal Extend for public export. `useForm` and `UseForm` are an abstraction layer
|
|
225
|
+
* on top of `useFormContext` and `UseFormReturn`, imported from `react-hook-form`
|
|
226
|
+
*
|
|
227
|
+
* @param options optional parameters
|
|
228
|
+
* @returns `Form` utilities
|
|
229
|
+
*/
|
|
230
|
+
function useForm(options = {}) {
|
|
231
|
+
const formContext = reactHookForm.useFormContext();
|
|
232
|
+
const { errorMessage, onSubmit: _onSubmit } = options;
|
|
233
|
+
if (!formContext) {
|
|
234
|
+
throw new Error(errorMessage ?? DEFAULT_ERROR_MESSAGE$1);
|
|
235
|
+
}
|
|
236
|
+
const { formState, getFieldState: _getFieldState, getValues, handleSubmit, register, reset, setValue, } = formContext;
|
|
237
|
+
// Do not memoize, `formState` updates on all events
|
|
238
|
+
const getFieldState = (name) => {
|
|
239
|
+
const { error, ...fieldState } = _getFieldState(name, formState);
|
|
240
|
+
const { message: errorMessage } = error ?? {};
|
|
241
|
+
return { ...fieldState, errorMessage, hasError: !!errorMessage };
|
|
242
|
+
};
|
|
243
|
+
// memoize `registerField` and `setFormValue` together,
|
|
244
|
+
// `register` and `setValue` maintain stable references
|
|
245
|
+
const { registerField, setFormValue } = React__default["default"].useMemo(() => {
|
|
246
|
+
return {
|
|
247
|
+
registerField: ({ name, ...options }) => register(name, options),
|
|
248
|
+
setFormValue: ({ name, value, ...options }) => setValue(name, value, options),
|
|
249
|
+
};
|
|
250
|
+
}, [register, setValue]);
|
|
251
|
+
const onSubmit = React__default["default"].useCallback((event) => {
|
|
252
|
+
const handler = _onSubmit ? handleSubmit(_onSubmit) : ui.noop;
|
|
253
|
+
handler(event);
|
|
254
|
+
}, [_onSubmit, handleSubmit]);
|
|
255
|
+
return {
|
|
256
|
+
getFieldState,
|
|
257
|
+
getValues,
|
|
258
|
+
isValid: formState.isValid,
|
|
259
|
+
onSubmit,
|
|
260
|
+
registerField,
|
|
261
|
+
reset,
|
|
262
|
+
setFormValue,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const DEFAULT_ERROR_MESSAGE = '`useField` must be used within a `FormProvider`';
|
|
267
|
+
/**
|
|
268
|
+
* `Field` integration hook for usage with React `Field` components.
|
|
269
|
+
*
|
|
270
|
+
* @param params Requires `name`, all additional params optional
|
|
271
|
+
* @returns `Form` aware `Field` event handlers and state values
|
|
272
|
+
*/
|
|
273
|
+
function useField(params) {
|
|
274
|
+
const { getFieldState, registerField } = useForm({
|
|
275
|
+
errorMessage: DEFAULT_ERROR_MESSAGE,
|
|
276
|
+
});
|
|
277
|
+
return {
|
|
278
|
+
...registerField(params),
|
|
279
|
+
...getFieldState(params.name),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const DEFAULT_MODE = 'onTouched';
|
|
284
|
+
const FormProvider = React__default["default"].forwardRef(function FormProvider({ children, defaultValues, mode = DEFAULT_MODE }, ref) {
|
|
285
|
+
const formProviderProps = reactHookForm.useForm({
|
|
286
|
+
defaultValues,
|
|
287
|
+
mode,
|
|
288
|
+
});
|
|
289
|
+
const { getValues, reset } = formProviderProps;
|
|
290
|
+
React__default["default"].useImperativeHandle(ref, () => ({ getValues, reset: () => reset(defaultValues) }), [defaultValues, getValues, reset]);
|
|
291
|
+
return (React__default["default"].createElement(reactHookForm.FormProvider, { ...formProviderProps }, children));
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* @param Child `Form` base component wrapped inside `FormProvider`
|
|
296
|
+
* @returns Composed `Form` component exposing `FormContext` values to descendents
|
|
297
|
+
*/
|
|
298
|
+
function withFormProvider(Child) {
|
|
299
|
+
return React__default["default"].forwardRef(function Form({ defaultValues, mode, ...props }, ref) {
|
|
300
|
+
return (React__default["default"].createElement(FormProvider, { defaultValues: defaultValues, mode: mode, ref: ref },
|
|
301
|
+
React__default["default"].createElement(Child, { ...props })));
|
|
302
|
+
});
|
|
256
303
|
}
|
|
257
304
|
|
|
258
305
|
/**
|
|
@@ -282,8 +329,8 @@ const CONFIRM_RESET_PASSWORD_MACHINE_KEYS = [
|
|
|
282
329
|
];
|
|
283
330
|
const CONFIRM_SIGN_IN_MACHINE_KEYS = [
|
|
284
331
|
...COMMON_ROUTE_MACHINE_KEYS,
|
|
332
|
+
'challengeName',
|
|
285
333
|
'toSignIn',
|
|
286
|
-
'user',
|
|
287
334
|
];
|
|
288
335
|
const CONFIRM_SIGN_UP_MACHINE_KEYS = [
|
|
289
336
|
...COMMON_ROUTE_MACHINE_KEYS,
|
|
@@ -306,13 +353,15 @@ const RESET_PASSWORD_MACHINE_KEYS = [
|
|
|
306
353
|
];
|
|
307
354
|
const SIGN_IN_MACHINE_KEYS = [
|
|
308
355
|
...COMMON_ROUTE_MACHINE_KEYS,
|
|
356
|
+
'socialProviders',
|
|
309
357
|
'toFederatedSignIn',
|
|
310
|
-
'
|
|
358
|
+
'toForgotPassword',
|
|
311
359
|
'toSignUp',
|
|
312
360
|
];
|
|
313
361
|
const SIGN_UP_MACHINE_KEYS = [
|
|
314
362
|
...COMMON_ROUTE_MACHINE_KEYS,
|
|
315
363
|
'hasValidationErrors',
|
|
364
|
+
'socialProviders',
|
|
316
365
|
'toSignIn',
|
|
317
366
|
'validationErrors',
|
|
318
367
|
];
|
|
@@ -320,6 +369,7 @@ const SETUP_TOTP_MACHINE_KEYS = [
|
|
|
320
369
|
...COMMON_ROUTE_MACHINE_KEYS,
|
|
321
370
|
'toSignIn',
|
|
322
371
|
'totpSecretCode',
|
|
372
|
+
'username',
|
|
323
373
|
];
|
|
324
374
|
const VERIFY_USER_MACHINE_KEYS = [
|
|
325
375
|
...COMMON_ROUTE_MACHINE_KEYS,
|
|
@@ -333,8 +383,8 @@ const MACHINE_PROP_KEYS = {
|
|
|
333
383
|
forceNewPassword: FORCE_NEW_PASSWORD_MACHINE_KEYS,
|
|
334
384
|
signIn: SIGN_IN_MACHINE_KEYS,
|
|
335
385
|
signUp: SIGN_UP_MACHINE_KEYS,
|
|
336
|
-
|
|
337
|
-
|
|
386
|
+
forgotPassword: RESET_PASSWORD_MACHINE_KEYS,
|
|
387
|
+
setupTotp: SETUP_TOTP_MACHINE_KEYS,
|
|
338
388
|
verifyUser: VERIFY_USER_MACHINE_KEYS,
|
|
339
389
|
};
|
|
340
390
|
|
|
@@ -350,47 +400,66 @@ const getRouteMachineSelector = (route) => isComponentRouteKey(route)
|
|
|
350
400
|
: routeSelector$1;
|
|
351
401
|
const isFormEventHandlerKey = (key) => ['updateBlur', 'updateForm', 'submitForm'].includes(key);
|
|
352
402
|
const convertEventHandlerKey = (key) => EVENT_HANDLER_KEY_MAP[key];
|
|
353
|
-
const getConvertedMachineProps = (route, context) => MACHINE_PROP_KEYS[route].reduce((acc, key) => (
|
|
403
|
+
const getConvertedMachineProps = (route, context) => MACHINE_PROP_KEYS[route].reduce((acc, key) => ({
|
|
404
|
+
...acc,
|
|
405
|
+
[isFormEventHandlerKey(key) ? convertEventHandlerKey(key) : key]: context[key],
|
|
406
|
+
}), {});
|
|
354
407
|
function resolveConfirmResetPasswordRoute(Component, props) {
|
|
355
408
|
return {
|
|
356
409
|
Component,
|
|
357
|
-
props:
|
|
410
|
+
props: {
|
|
411
|
+
...Component,
|
|
412
|
+
...getConvertedMachineProps('confirmResetPassword', props),
|
|
413
|
+
},
|
|
358
414
|
};
|
|
359
415
|
}
|
|
360
416
|
function resolveConfirmSignInRoute(Component, props) {
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
const challengeName = user.challengeName;
|
|
364
|
-
return { Component, props: Object.assign(Object.assign(Object.assign({}, Component), machineProps), { challengeName }) };
|
|
417
|
+
const { challengeName, ...machineProps } = getConvertedMachineProps('confirmSignIn', props);
|
|
418
|
+
return { Component, props: { ...Component, ...machineProps, challengeName } };
|
|
365
419
|
}
|
|
366
420
|
function resolveConfirmSignUpRoute(Component, props) {
|
|
367
421
|
return {
|
|
368
422
|
Component,
|
|
369
|
-
props:
|
|
423
|
+
props: {
|
|
424
|
+
...Component,
|
|
425
|
+
...getConvertedMachineProps('confirmSignUp', props),
|
|
426
|
+
},
|
|
370
427
|
};
|
|
371
428
|
}
|
|
372
429
|
function resolveConfirmVerifyUserRoute(Component, props) {
|
|
373
430
|
return {
|
|
374
431
|
Component,
|
|
375
|
-
props:
|
|
432
|
+
props: {
|
|
433
|
+
...Component,
|
|
434
|
+
...getConvertedMachineProps('confirmVerifyUser', props),
|
|
435
|
+
},
|
|
376
436
|
};
|
|
377
437
|
}
|
|
378
438
|
function resolveForceNewPasswordRoute(Component, props) {
|
|
379
439
|
return {
|
|
380
440
|
Component,
|
|
381
|
-
props:
|
|
441
|
+
props: {
|
|
442
|
+
...Component,
|
|
443
|
+
...getConvertedMachineProps('forceNewPassword', props),
|
|
444
|
+
},
|
|
382
445
|
};
|
|
383
446
|
}
|
|
384
|
-
function
|
|
447
|
+
function resolveForgotPasswordRoute(Component, props) {
|
|
385
448
|
return {
|
|
386
449
|
Component,
|
|
387
|
-
props:
|
|
450
|
+
props: {
|
|
451
|
+
...Component,
|
|
452
|
+
...getConvertedMachineProps('forgotPassword', props),
|
|
453
|
+
},
|
|
388
454
|
};
|
|
389
455
|
}
|
|
390
|
-
function
|
|
456
|
+
function resolveSetupTotpRoute(Component, props) {
|
|
391
457
|
return {
|
|
392
458
|
Component,
|
|
393
|
-
props:
|
|
459
|
+
props: {
|
|
460
|
+
...Component,
|
|
461
|
+
...getConvertedMachineProps('setupTotp', props),
|
|
462
|
+
},
|
|
394
463
|
};
|
|
395
464
|
}
|
|
396
465
|
function resolveSignInRoute(Component, props) {
|
|
@@ -398,19 +467,26 @@ function resolveSignInRoute(Component, props) {
|
|
|
398
467
|
const hideSignUp = false;
|
|
399
468
|
return {
|
|
400
469
|
Component,
|
|
401
|
-
props:
|
|
470
|
+
props: {
|
|
471
|
+
...Component,
|
|
472
|
+
...getConvertedMachineProps('signIn', props),
|
|
473
|
+
hideSignUp,
|
|
474
|
+
},
|
|
402
475
|
};
|
|
403
476
|
}
|
|
404
477
|
function resolveSignUpRoute(Component, props) {
|
|
405
478
|
return {
|
|
406
479
|
Component,
|
|
407
|
-
props:
|
|
480
|
+
props: { ...Component, ...getConvertedMachineProps('signUp', props) },
|
|
408
481
|
};
|
|
409
482
|
}
|
|
410
483
|
function resolveVerifyUserRoute(Component, props) {
|
|
411
484
|
return {
|
|
412
485
|
Component,
|
|
413
|
-
props:
|
|
486
|
+
props: {
|
|
487
|
+
...Component,
|
|
488
|
+
...getConvertedMachineProps('verifyUser', props),
|
|
489
|
+
},
|
|
414
490
|
};
|
|
415
491
|
}
|
|
416
492
|
function resolveDefault() {
|
|
@@ -429,7 +505,7 @@ function useAuthenticatorRoute({ components, }) {
|
|
|
429
505
|
// Only state machine props specified by the current `routeSelector` will have their current value
|
|
430
506
|
// returned by `useAuthenticator`, non-machine props returned will always be the current value
|
|
431
507
|
const routeSelectorProps = useAuthenticator(routeMachineSelector);
|
|
432
|
-
const { ConfirmResetPassword, ConfirmSignIn, ConfirmSignUp, ConfirmVerifyUser, ForceNewPassword,
|
|
508
|
+
const { ConfirmResetPassword, ConfirmSignIn, ConfirmSignUp, ConfirmVerifyUser, ForceNewPassword, ForgotPassword, SetupTotp, SignIn, SignUp, VerifyUser, } = components;
|
|
433
509
|
switch (route) {
|
|
434
510
|
case 'confirmResetPassword': {
|
|
435
511
|
return resolveConfirmResetPasswordRoute(ConfirmResetPassword, routeSelectorProps);
|
|
@@ -446,11 +522,11 @@ function useAuthenticatorRoute({ components, }) {
|
|
|
446
522
|
case 'forceNewPassword': {
|
|
447
523
|
return resolveForceNewPasswordRoute(ForceNewPassword, routeSelectorProps);
|
|
448
524
|
}
|
|
449
|
-
case '
|
|
450
|
-
return
|
|
525
|
+
case 'forgotPassword': {
|
|
526
|
+
return resolveForgotPasswordRoute(ForgotPassword, routeSelectorProps);
|
|
451
527
|
}
|
|
452
|
-
case '
|
|
453
|
-
return
|
|
528
|
+
case 'setupTotp': {
|
|
529
|
+
return resolveSetupTotpRoute(SetupTotp, routeSelectorProps);
|
|
454
530
|
}
|
|
455
531
|
case 'signIn': {
|
|
456
532
|
return resolveSignInRoute(SignIn, routeSelectorProps);
|
|
@@ -528,13 +604,125 @@ function useHasValueUpdated(value, ignoreFirstRender = false) {
|
|
|
528
604
|
return previous !== value;
|
|
529
605
|
}
|
|
530
606
|
|
|
607
|
+
function useSetUserAgent({ componentName, packageName, version, }) {
|
|
608
|
+
React.useEffect(() => {
|
|
609
|
+
const clearUserAgent = ui.setUserAgent({
|
|
610
|
+
componentName,
|
|
611
|
+
packageName,
|
|
612
|
+
version,
|
|
613
|
+
});
|
|
614
|
+
return clearUserAgent;
|
|
615
|
+
}, [componentName, packageName, version]);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function useTimeout({ callback, delay, }) {
|
|
619
|
+
const storedCallback = React__default["default"].useRef(callback);
|
|
620
|
+
React__default["default"].useLayoutEffect(() => {
|
|
621
|
+
storedCallback.current = callback;
|
|
622
|
+
}, [callback]);
|
|
623
|
+
React__default["default"].useEffect(() => {
|
|
624
|
+
if (!ui.isTypedFunction(storedCallback.current) || !delay) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
const timeoutId = setTimeout(() => {
|
|
628
|
+
storedCallback.current?.();
|
|
629
|
+
}, delay);
|
|
630
|
+
return () => {
|
|
631
|
+
clearTimeout(timeoutId);
|
|
632
|
+
};
|
|
633
|
+
}, [delay]);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
const INVALID_OPTIONS_MESSAGE = 'an `errorMessage` or a `defaultValue` must be provided in `options`';
|
|
637
|
+
/**
|
|
638
|
+
* Uses `ContextType`/`Name` generics and `options` to create:
|
|
639
|
+
* - `${Name}Context`: React Context of type `ContextType`
|
|
640
|
+
* - `Provider${Name}`: React Context `Provider` component exposing the `ContextType`
|
|
641
|
+
* as optional props
|
|
642
|
+
* - `use${Name}`: Utility Hook exposing the values of `ContextType`. Allows
|
|
643
|
+
* params with `errorMessage` for granular error messaging
|
|
644
|
+
*
|
|
645
|
+
* @template ContextType Type definition of the Context.
|
|
646
|
+
* > For most use cases the keys of `ContextType` should not be optional in
|
|
647
|
+
* preference of explicit `undefined` to avoid optional types on the
|
|
648
|
+
* Utility Hook return
|
|
649
|
+
*
|
|
650
|
+
* @param options Context utility options. Requires a `contextName`, and
|
|
651
|
+
* either a `defaultValue` of `ContextType` **or** an `errorMessage`
|
|
652
|
+
* allowing for differing behaviors of the Utility Hook when used outside a
|
|
653
|
+
* parent `Provider`:
|
|
654
|
+
*
|
|
655
|
+
* - `defaultValue`: Ensures the Utility Hook returns a default value for
|
|
656
|
+
* scenarios **where the missing context values should not impact usage**
|
|
657
|
+
* - `errorMessage`: Ensures the Utility Hook throws an error for
|
|
658
|
+
* scenarios **where the missing context values should prevent** usage
|
|
659
|
+
*
|
|
660
|
+
* @returns `Context`, `Provider` Component and `useContext` Utility Hook
|
|
661
|
+
*
|
|
662
|
+
* @usage
|
|
663
|
+
* ```ts
|
|
664
|
+
* interface StuffContextType {
|
|
665
|
+
* things: number;
|
|
666
|
+
* }
|
|
667
|
+
*
|
|
668
|
+
* // with `defaultValue`
|
|
669
|
+
* const defaultValue: StuffContextType = { things: 7 };
|
|
670
|
+
*
|
|
671
|
+
* const { StuffProvider, useStuff } = createContextUtilities({
|
|
672
|
+
* contextName: 'Stuff',
|
|
673
|
+
* defaultValue,
|
|
674
|
+
* });
|
|
675
|
+
*
|
|
676
|
+
* // with `errorMessage`
|
|
677
|
+
* const { StuffProvider, useStuff } = createContextUtilities<StuffContextType>({
|
|
678
|
+
* contextName: 'Stuff',
|
|
679
|
+
* errorMessage: '`useStuff` must be used in a `StuffProvider`'
|
|
680
|
+
* });
|
|
681
|
+
* ```
|
|
682
|
+
*/
|
|
683
|
+
function createContextUtilities(options) {
|
|
684
|
+
const { contextName, defaultValue, errorMessage } = options ?? {};
|
|
685
|
+
if (ui.isUndefined(defaultValue) && !ui.isString(errorMessage)) {
|
|
686
|
+
throw new Error(INVALID_OPTIONS_MESSAGE);
|
|
687
|
+
}
|
|
688
|
+
const Context = React__default["default"].createContext(defaultValue);
|
|
689
|
+
function Provider(props) {
|
|
690
|
+
const { children, ...context } = props;
|
|
691
|
+
const value = React__default["default"].useMemo(() => context,
|
|
692
|
+
// Unpack `context` for the dep array; using `[context]` results in
|
|
693
|
+
// evaluation on every render
|
|
694
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
695
|
+
Object.values(context));
|
|
696
|
+
return React__default["default"].createElement(Context.Provider, { value: value }, children);
|
|
697
|
+
}
|
|
698
|
+
Provider.displayName = `${contextName}Provider`;
|
|
699
|
+
return {
|
|
700
|
+
[`use${contextName}`]: function (params) {
|
|
701
|
+
const context = React__default["default"].useContext(Context);
|
|
702
|
+
if (ui.isUndefined(context)) {
|
|
703
|
+
throw new Error(params?.errorMessage ?? errorMessage);
|
|
704
|
+
}
|
|
705
|
+
return context;
|
|
706
|
+
},
|
|
707
|
+
[`${contextName}Provider`]: Provider,
|
|
708
|
+
[`${contextName}Context`]: Context,
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
|
|
531
712
|
exports.AuthenticatorProvider = AuthenticatorProvider;
|
|
713
|
+
exports.FormProvider = FormProvider;
|
|
532
714
|
exports.RenderNothing = RenderNothing;
|
|
715
|
+
exports.createContextUtilities = createContextUtilities;
|
|
533
716
|
exports.isAuthenticatorComponentRouteKey = isComponentRouteKey;
|
|
534
717
|
exports.resolveAuthenticatorComponents = resolveAuthenticatorComponents;
|
|
535
718
|
exports.useAuthenticator = useAuthenticator;
|
|
536
719
|
exports.useAuthenticatorInitMachine = useAuthenticatorInitMachine;
|
|
537
720
|
exports.useAuthenticatorRoute = useAuthenticatorRoute;
|
|
538
721
|
exports.useDeprecationWarning = useDeprecationWarning;
|
|
722
|
+
exports.useField = useField;
|
|
723
|
+
exports.useForm = useForm;
|
|
539
724
|
exports.useHasValueUpdated = useHasValueUpdated;
|
|
540
725
|
exports.usePreviousValue = usePreviousValue;
|
|
726
|
+
exports.useSetUserAgent = useSetUserAgent;
|
|
727
|
+
exports.useTimeout = useTimeout;
|
|
728
|
+
exports.withFormProvider = withFormProvider;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ChallengeName, AuthenticatorServiceFacade, LegacyFormFieldOptions } from '@aws-amplify/ui';
|
|
3
3
|
import { UseAuthenticator } from './useAuthenticator';
|
|
4
|
-
export type AuthenticatorRouteComponentKey = 'confirmResetPassword' | 'confirmSignIn' | 'confirmSignUp' | 'confirmVerifyUser' | 'forceNewPassword' | '
|
|
4
|
+
export type AuthenticatorRouteComponentKey = 'confirmResetPassword' | 'confirmSignIn' | 'confirmSignUp' | 'confirmVerifyUser' | 'forceNewPassword' | 'forgotPassword' | 'setupTotp' | 'signIn' | 'signUp' | 'verifyUser';
|
|
5
5
|
export type AuthenticatorLegacyField = LegacyFormFieldOptions;
|
|
6
6
|
export type AuthenticatorLegacyFields = AuthenticatorLegacyField[];
|
|
7
7
|
/**
|
|
@@ -52,7 +52,7 @@ export type ConfirmResetPasswordBaseProps<FieldType = {}> = {
|
|
|
52
52
|
resendCode: UseAuthenticator['resendCode'];
|
|
53
53
|
} & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
|
|
54
54
|
export type ConfirmSignInBaseProps<FieldType = {}> = {
|
|
55
|
-
challengeName:
|
|
55
|
+
challengeName: ChallengeName | undefined;
|
|
56
56
|
toSignIn: UseAuthenticator['toSignIn'];
|
|
57
57
|
} & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
|
|
58
58
|
export type ConfirmSignUpBaseProps<FieldType = {}> = {
|
|
@@ -68,18 +68,21 @@ export type ForceResetPasswordBaseProps<FieldType = {}> = {
|
|
|
68
68
|
export type ResetPasswordBaseProps<FieldType = {}> = {
|
|
69
69
|
toSignIn: UseAuthenticator['toSignIn'];
|
|
70
70
|
} & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
|
|
71
|
-
export type
|
|
71
|
+
export type SetupTotpBaseProps<FieldType = {}> = {
|
|
72
72
|
toSignIn: UseAuthenticator['toSignIn'];
|
|
73
73
|
totpSecretCode: UseAuthenticator['totpSecretCode'];
|
|
74
|
+
username: UseAuthenticator['username'];
|
|
74
75
|
} & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
|
|
75
76
|
export type SignInBaseProps<FieldType = {}> = {
|
|
76
77
|
hideSignUp?: boolean;
|
|
78
|
+
socialProviders?: UseAuthenticator['socialProviders'];
|
|
77
79
|
toFederatedSignIn: UseAuthenticator['toFederatedSignIn'];
|
|
78
|
-
|
|
80
|
+
toForgotPassword: UseAuthenticator['toForgotPassword'];
|
|
79
81
|
toSignUp: UseAuthenticator['toSignUp'];
|
|
80
82
|
} & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
|
|
81
83
|
export type SignUpBaseProps<FieldType = {}> = {
|
|
82
84
|
hideSignIn?: boolean;
|
|
85
|
+
socialProviders?: UseAuthenticator['socialProviders'];
|
|
83
86
|
toFederatedSignIn: UseAuthenticator['toFederatedSignIn'];
|
|
84
87
|
toSignIn: UseAuthenticator['toSignIn'];
|
|
85
88
|
} & CommonRouteProps & ComponentSlots<FieldType> & ValidationProps;
|
|
@@ -92,8 +95,8 @@ export interface DefaultProps<FieldType = {}> {
|
|
|
92
95
|
ConfirmResetPassword: ConfirmResetPasswordBaseProps<FieldType>;
|
|
93
96
|
ConfirmVerifyUser: ConfirmVerifyUserProps<FieldType>;
|
|
94
97
|
ForceNewPassword: ForceResetPasswordBaseProps<FieldType>;
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
ForgotPassword: ResetPasswordBaseProps<FieldType>;
|
|
99
|
+
SetupTotp: SetupTotpBaseProps<FieldType>;
|
|
97
100
|
SignIn: SignInBaseProps<FieldType>;
|
|
98
101
|
SignUp: SignUpBaseProps<FieldType>;
|
|
99
102
|
VerifyUser: VerifyUserProps<FieldType>;
|
|
@@ -5,7 +5,7 @@ import { AuthenticatorServiceFacade, LegacyFormFieldOptions } from '@aws-amplify
|
|
|
5
5
|
*/
|
|
6
6
|
type AuthenticatorMachineContext = AuthenticatorServiceFacade;
|
|
7
7
|
type AuthenticatorMachineContextKey = keyof AuthenticatorMachineContext;
|
|
8
|
-
export type AuthenticatorRouteComponentKey = 'signIn' | 'signUp' | 'forceNewPassword' | 'confirmResetPassword' | 'confirmSignIn' | 'confirmSignUp' | 'confirmVerifyUser' | '
|
|
8
|
+
export type AuthenticatorRouteComponentKey = 'signIn' | 'signUp' | 'forceNewPassword' | 'confirmResetPassword' | 'confirmSignIn' | 'confirmSignUp' | 'confirmVerifyUser' | 'forgotPassword' | 'setupTotp' | 'verifyUser';
|
|
9
9
|
export type AuthenticatorLegacyFields = LegacyFormFieldOptions[];
|
|
10
10
|
/**
|
|
11
11
|
* Inspired from https://xstate.js.org/docs/packages/xstate-react/#useselector-actor-selector-compare-getsnapshot.
|
|
@@ -18,8 +18,6 @@ export interface UseAuthenticator extends AuthenticatorServiceFacade {
|
|
|
18
18
|
/** @deprecated For internal use only */
|
|
19
19
|
fields: AuthenticatorLegacyFields;
|
|
20
20
|
/** @deprecated For internal use only */
|
|
21
|
-
getTotpSecretCode: () => Promise<string>;
|
|
22
|
-
/** @deprecated For internal use only */
|
|
23
21
|
QRFields: {
|
|
24
22
|
totpIssuer?: string;
|
|
25
23
|
totpUsername?: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AuthenticatorRoute, AuthMachineState, UnverifiedUserAttributes } from '@aws-amplify/ui';
|
|
2
2
|
import { AuthenticatorLegacyFields } from '../types';
|
|
3
3
|
import { Comparator, UseAuthenticatorSelector } from './types';
|
|
4
4
|
export declare const defaultComparator: () => false;
|
|
@@ -12,9 +12,8 @@ export declare const getQRFields: (state: AuthMachineState) => {
|
|
|
12
12
|
totpIssuer?: string;
|
|
13
13
|
totpUsername?: string;
|
|
14
14
|
};
|
|
15
|
-
export declare const getTotpSecretCodeCallback: (user: AmplifyUser) => () => Promise<string>;
|
|
16
15
|
/**
|
|
17
16
|
* Retrieves default and custom (RWA only, to be updated) form field values from state machine
|
|
18
17
|
* for subcomponent routes that render fields
|
|
19
18
|
*/
|
|
20
|
-
export declare const getMachineFields: (route: AuthenticatorRoute, state: AuthMachineState,
|
|
19
|
+
export declare const getMachineFields: (route: AuthenticatorRoute, state: AuthMachineState, unverifiedUserAttributes: UnverifiedUserAttributes) => AuthenticatorLegacyFields;
|