supertokens-auth-react
Version:
ReactJS SDK that provides login functionality with SuperTokens.
938 lines (925 loc) • 43 kB
JavaScript
"use strict";
var genericComponentOverrideContext = require("./genericComponentOverrideContext.js");
var jsxRuntime = require("react/jsx-runtime");
var React = require("react");
var constants = require("./emailpassword-shared4.js");
var button = require("./emailpassword-shared.js");
require("./index2.js");
var translationContext = require("./translationContext.js");
function _interopDefault(e) {
return e && e.__esModule ? e : { default: e };
}
var React__default = /*#__PURE__*/ _interopDefault(React);
/*
* Component.
*/
function FormRow(_a) {
var children = _a.children,
hasError = _a.hasError;
return jsxRuntime.jsx(
"div",
genericComponentOverrideContext.__assign(
{ "data-supertokens": ["formRow", hasError ? "hasError" : ""].join(" ") },
{ children: children }
)
);
}
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/*
* Imports.
*/
/*
* Component.
*/
function CheckedIcon() {
return jsxRuntime.jsx(
"svg",
genericComponentOverrideContext.__assign(
{
xmlns: "http://www.w3.org/2000/svg",
width: "14.862",
height: "12.033",
viewBox: "0 0 14.862 12.033",
"data-supertokens": "checkedIcon",
},
{
children: jsxRuntime.jsx("path", {
fill: "rgb(var(--palette-primary))",
d: "M12.629 49L5.06 56.572l-2.829-2.829L0 55.977l5.057 5.057.654-.651 9.152-9.152z",
transform: "translate(0 -49)",
}),
}
)
);
}
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/*
* Imports.
*/
/*
* Component.
*/
function ErrorIcon() {
return jsxRuntime.jsx(
"svg",
genericComponentOverrideContext.__assign(
{
xmlns: "http://www.w3.org/2000/svg",
width: "17",
height: "15",
viewBox: "0 0 17 15",
"data-supertokens": "errorIcon",
},
{
children: jsxRuntime.jsxs("g", {
children: [
jsxRuntime.jsx(
"g",
genericComponentOverrideContext.__assign(
{ className: "Asdf", fill: "rgb(var(--palette-error))" },
{
children: jsxRuntime.jsx("path", {
d: "M13.568 14.75H3.432c-.63 0-1.195-.325-1.512-.869-.317-.544-.32-1.196-.01-1.744l5.067-8.943c.315-.556.884-.887 1.523-.887.639 0 1.208.331 1.523.887l5.067 8.943c.31.548.307 1.2-.01 1.744s-.882.869-1.512.869z",
transform: "translate(-824.894 -352.829) translate(824.894 352.829)",
}),
}
)
),
jsxRuntime.jsx(
"text",
genericComponentOverrideContext.__assign(
{
fill: "#fff",
fontSize: "10px",
fontWeight: "700",
transform: "translate(-824.894 -352.829) translate(832.014 365.198)",
},
{
children: jsxRuntime.jsx(
"tspan",
genericComponentOverrideContext.__assign({ x: "0", y: "0" }, { children: "!" })
),
}
)
),
],
}),
}
)
);
}
/* Copyright (c) 2021, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
/*
* Imports.
*/
/*
* Component.
*/
function ShowPasswordIcon(_a) {
var showPassword = _a.showPassword;
if (showPassword === true) {
return jsxRuntime.jsx("div", {
children: jsxRuntime.jsx(
"svg",
genericComponentOverrideContext.__assign(
{
xmlns: "http://www.w3.org/2000/svg",
width: "18.391",
height: "16.276",
viewBox: "0 0 18.391 16.276",
"data-supertokens": "showPasswordIcon show",
},
{
children: jsxRuntime.jsxs("g", {
children: [
jsxRuntime.jsx("g", {
children: jsxRuntime.jsx("g", {
children: jsxRuntime.jsx("g", {
children: jsxRuntime.jsx("path", {
fill: "rgb(var(--palette-textPrimary))",
d: "M29.289 100.33c-2.4-3.63-5.619-5.63-9.069-5.63s-6.67 2-9.069 5.63a.767.767 0 0 0 0 .845c2.4 3.63 5.619 5.63 9.069 5.63s6.67-2 9.069-5.63a.767.767 0 0 0 0-.845zm-9.069 4.944c-2.785 0-5.435-1.6-7.5-4.519 2.065-2.92 4.715-4.519 7.5-4.519s5.435 1.6 7.5 4.519c-2.064 2.92-4.711 4.519-7.5 4.519z",
transform:
"translate(-822 -420.048) translate(822 422.035) translate(-11.025 -94.7)",
}),
}),
}),
}),
jsxRuntime.jsxs(
"g",
genericComponentOverrideContext.__assign(
{
fill: "rgb(var(--palette-textPrimary))",
stroke: "rgb(var(--palette-inputBackground))",
transform: "translate(-822 -420.048) translate(827.164 424.055)",
},
{
children: [
jsxRuntime.jsx("circle", {
cx: "4.036",
cy: "4.036",
r: "4.036",
stroke: "none",
}),
jsxRuntime.jsx("circle", {
cx: "4.036",
cy: "4.036",
r: "3.536",
fill: "none",
}),
],
}
)
),
jsxRuntime.jsx("path", {
fill: "none",
stroke: "#707070",
strokeLinecap: "round",
strokeWidth: "2.25px",
d: "M11.981 0L0 11.981",
transform: "translate(-822 -420.048) translate(825.084 421.639)",
}),
jsxRuntime.jsx("path", {
fill: "none",
stroke: "rgb(var(--palette-inputBackground))",
strokeLinecap: "round",
d: "M13.978 0L0 13.978",
transform: "translate(-822 -420.048) translate(825.084 421.639)",
}),
],
}),
}
)
),
});
}
return jsxRuntime.jsx("div", {
children: jsxRuntime.jsx(
"svg",
genericComponentOverrideContext.__assign(
{
xmlns: "http://www.w3.org/2000/svg",
width: "18.281",
height: "12.033",
viewBox: "0 0 18.281 12.033",
"data-supertokens": "showPasswordIcon hide",
},
{
children: jsxRuntime.jsxs("g", {
children: [
jsxRuntime.jsx("g", {
children: jsxRuntime.jsx("g", {
children: jsxRuntime.jsx("g", {
children: jsxRuntime.jsx("path", {
fill: "rgb(var(--palette-textPrimary))",
d: "M29.18 100.3c-2.384-3.608-5.586-5.6-9.015-5.6s-6.63 1.989-9.015 5.6a.763.763 0 0 0 0 .84c2.384 3.608 5.586 5.6 9.015 5.6s6.63-1.989 9.015-5.6a.763.763 0 0 0 0-.84zm-9.015 4.914c-2.769 0-5.4-1.589-7.459-4.492 2.052-2.9 4.686-4.492 7.459-4.492s5.4 1.589 7.459 4.492c-2.056 2.899-4.686 4.489-7.458 4.489z",
transform:
"translate(-822 -422.088) translate(822 422.088) translate(-11.025 -94.7)",
}),
}),
}),
}),
jsxRuntime.jsxs(
"g",
genericComponentOverrideContext.__assign(
{
fill: "rgb(var(--palette-textPrimary))",
stroke: "rgb(var(--palette-inputBackground))",
transform: "translate(-822 -422.088) translate(827.133 424.096)",
},
{
children: [
jsxRuntime.jsx("circle", {
cx: "4.012",
cy: "4.012",
r: "4.012",
stroke: "none",
}),
jsxRuntime.jsx("circle", {
cx: "4.012",
cy: "4.012",
r: "3.512",
fill: "none",
}),
],
}
)
),
],
}),
}
)
),
});
}
var Input = function (_a) {
var type = _a.type,
name = _a.name,
hasError = _a.hasError,
autoComplete = _a.autoComplete,
onInputFocus = _a.onInputFocus,
onInputBlur = _a.onInputBlur,
onChange = _a.onChange,
value = _a.value,
placeholder = _a.placeholder,
validated = _a.validated,
autofocus = _a.autofocus;
var t = translationContext.useTranslation();
var _b = React.useState(false),
showPassword = _b[0],
setShowPassword = _b[1];
/*
* Method.
*/
function handleFocus() {
if (onInputFocus !== undefined) {
onInputFocus(value);
}
}
function handleBlur() {
if (onInputBlur !== undefined) {
onInputBlur(value);
}
}
function handleChange(event) {
if (onChange) {
onChange(event.target.value);
}
}
if (autoComplete === undefined) {
autoComplete = "off";
}
var inputType = type;
if (type === "password" && showPassword === true) {
inputType = "text";
}
return jsxRuntime.jsx(
"div",
genericComponentOverrideContext.__assign(
{ "data-supertokens": "inputContainer" },
{
children: jsxRuntime.jsxs(
"div",
genericComponentOverrideContext.__assign(
{ "data-supertokens": ["inputWrapper", hasError ? "inputError" : ""].join(" ") },
{
children: [
jsxRuntime.jsx("input", {
autoFocus: autofocus,
autoComplete: autoComplete,
"data-supertokens": "input input-".concat(name),
className: "supertokens-input",
onFocus: handleFocus,
onBlur: handleBlur,
type: inputType,
name: name,
placeholder: t(placeholder),
onChange: handleChange,
value: value,
}),
hasError === true &&
jsxRuntime.jsx(
"div",
genericComponentOverrideContext.__assign(
{ "data-supertokens": "inputAdornment inputAdornmentError" },
{ children: jsxRuntime.jsx(ErrorIcon, {}) }
)
),
validated === true &&
hasError === false &&
jsxRuntime.jsx(
"div",
genericComponentOverrideContext.__assign(
{ "data-supertokens": "inputAdornment inputAdornmentSuccess" },
{ children: jsxRuntime.jsx(CheckedIcon, {}) }
)
),
type === "password" &&
value.length > 0 &&
jsxRuntime.jsx(
"div",
genericComponentOverrideContext.__assign(
{
onClick: function () {
return setShowPassword(showPassword === false);
},
"data-supertokens": "inputAdornment showPassword",
},
{
children: jsxRuntime.jsx(ShowPasswordIcon, {
showPassword: showPassword,
}),
}
)
),
],
}
)
),
}
)
);
};
function InputError(_a) {
var error = _a.error;
var t = translationContext.useTranslation();
return jsxRuntime.jsx(
"div",
genericComponentOverrideContext.__assign({ "data-supertokens": "inputErrorMessage" }, { children: t(error) })
);
}
function Label(_a) {
var value = _a.value,
showIsRequired = _a.showIsRequired;
var t = translationContext.useTranslation();
return jsxRuntime.jsxs(
"div",
genericComponentOverrideContext.__assign(
{ "data-supertokens": "label" },
{ children: [t(value), showIsRequired && value && value.trim() !== "" && " *"] }
)
);
}
var fetchDefaultValue = function (field) {
if (field.getDefaultValue !== undefined) {
var defaultValue = field.getDefaultValue();
if (typeof defaultValue !== "string") {
throw new Error("getDefaultValue for ".concat(field.id, " must return a string"));
} else {
return defaultValue;
}
}
return "";
};
function InputComponentWrapper(props) {
var field = props.field,
type = props.type,
fstate = props.fstate,
onInputFocus = props.onInputFocus,
onInputBlur = props.onInputBlur,
onInputChange = props.onInputChange;
var useCallbackOnInputFocus = React.useCallback(
function (value) {
onInputFocus({
id: field.id,
value: value,
});
},
[onInputFocus, field.id]
);
var useCallbackOnInputBlur = React.useCallback(
function (value) {
onInputBlur({
id: field.id,
value: value,
});
},
[onInputBlur, field.id]
);
var useCallbackOnInputChange = React.useCallback(
function (value) {
onInputChange({
id: field.id,
value: value,
});
},
[onInputChange, field.id]
);
return field.inputComponent !== undefined
? jsxRuntime.jsx(
field.inputComponent,
{
type: type,
name: field.id,
validated: fstate.validated === true,
placeholder: field.placeholder,
value: fstate.value,
autoComplete: field.autoComplete,
autofocus: field.autofocus,
onInputFocus: useCallbackOnInputFocus,
onInputBlur: useCallbackOnInputBlur,
onChange: useCallbackOnInputChange,
hasError: fstate.error !== undefined,
},
field.id
)
: jsxRuntime.jsx(
Input,
{
type: type,
name: field.id,
validated: fstate.validated === true,
placeholder: field.placeholder,
value: fstate.value,
autoComplete: field.autoComplete,
onInputFocus: useCallbackOnInputFocus,
onInputBlur: useCallbackOnInputBlur,
onChange: useCallbackOnInputChange,
autofocus: field.autofocus,
hasError: fstate.error !== undefined,
},
field.id
);
}
var FormBase = function (props) {
var footer = props.footer,
buttonLabel = props.buttonLabel,
showLabels = props.showLabels,
validateOnBlur = props.validateOnBlur,
formFields = props.formFields;
var unmounting = React.useRef(new AbortController());
React.useEffect(
function () {
// We need this because in some cases this gets called multiple times
unmounting.current = new AbortController();
return function () {
unmounting.current.abort();
};
},
[unmounting]
);
var _a = React.useState(
props.formFields.map(function (f) {
return { id: f.id, value: fetchDefaultValue(f) };
})
),
fieldStates = _a[0],
setFieldStates = _a[1];
React.useEffect(
function () {
setFieldStates(function (fs) {
var ret = fs;
var fieldsWithoutState = props.formFields.filter(function (f) {
return !fieldStates.some(function (s) {
return f.id === s.id;
});
});
// If there is a formfield missing from the states array, we fill with the default value
if (fieldsWithoutState.length > 0) {
fs = genericComponentOverrideContext.__spreadArray(
genericComponentOverrideContext.__spreadArray([], fs, true),
fieldsWithoutState.map(function (f) {
return { id: f.id, value: fetchDefaultValue(f) };
}),
true
);
}
// If a field has been removed from formFields, we want to remove it from the states array as well.
if (
fieldStates.some(function (s) {
return !props.formFields.some(function (f) {
return f.id === s.id;
});
})
) {
ret = fs.filter(function (s) {
return props.formFields.some(function (f) {
return f.id === s.id;
});
});
}
return ret;
});
},
[props.formFields, setFieldStates]
);
var _b = React.useState(false),
isLoading = _b[0],
setIsLoading = _b[1];
var updateFieldState = React.useCallback(
function (id, update) {
setFieldStates(function (os) {
var field = os.find(function (f) {
return f.id === id;
});
if (field === undefined) {
return genericComponentOverrideContext.__spreadArray(
genericComponentOverrideContext.__spreadArray([], os, true),
[update({ id: id, value: "" })],
false
);
}
return os
.filter(function (f) {
return f.id !== field.id;
})
.concat(update(field));
});
},
[setFieldStates]
);
var onInputFocus = React.useCallback(
function (field) {
updateFieldState(field.id, function (os) {
return genericComponentOverrideContext.__assign(genericComponentOverrideContext.__assign({}, os), {
validated: false,
});
});
},
[updateFieldState]
);
var onInputBlur = React.useCallback(
function (field) {
return genericComponentOverrideContext.__awaiter(void 0, void 0, void 0, function () {
var fieldConfig, error, _a;
return genericComponentOverrideContext.__generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!validateOnBlur) {
return [2 /*return*/];
}
fieldConfig = props.formFields.find(function (f) {
return f.id === field.id;
});
if (!(fieldConfig && field.value !== "")) return [3 /*break*/, 2];
return [4 /*yield*/, fieldConfig.validate(field.value)];
case 1:
_a = _b.sent();
return [3 /*break*/, 3];
case 2:
_a = undefined;
_b.label = 3;
case 3:
error = _a;
updateFieldState(field.id, function (os) {
return genericComponentOverrideContext.__assign(
genericComponentOverrideContext.__assign({}, os),
{ error: error, validated: error === undefined && field.value.length !== 0 }
);
});
return [2 /*return*/];
}
});
});
},
[validateOnBlur, updateFieldState, props.formFields]
);
var onInputChange = React.useCallback(
function (field) {
if (typeof field.value !== "string") {
throw new Error("".concat(field.id, " value must be a string"));
}
updateFieldState(field.id, function (os) {
return genericComponentOverrideContext.__assign(genericComponentOverrideContext.__assign({}, os), {
value: field.value,
error: undefined,
});
});
props.clearError();
},
[updateFieldState]
);
var onFormSubmit = React.useCallback(
function (e) {
return genericComponentOverrideContext.__awaiter(void 0, void 0, void 0, function () {
var apiFields,
fieldUpdates,
_a,
result,
generalError,
fetchError,
_loop_1,
_i,
_b,
field,
errorFields_1,
getErrorMessage_1,
e_1;
return genericComponentOverrideContext.__generator(this, function (_c) {
switch (_c.label) {
case 0:
// Prevent default event propagation.
e.preventDefault();
// Set loading state.
setIsLoading(true);
setFieldStates(function (os) {
return os.map(function (fs) {
return genericComponentOverrideContext.__assign(
genericComponentOverrideContext.__assign({}, fs),
{ error: undefined }
);
});
});
apiFields =
formFields === null || formFields === void 0
? void 0
: formFields.map(function (field) {
var fieldState =
fieldStates === null || fieldStates === void 0
? void 0
: fieldStates.find(function (fs) {
return fs.id === field.id;
});
return {
id: field.id,
value: fieldState === undefined ? "" : fieldState.value,
};
});
fieldUpdates = [];
_c.label = 1;
case 1:
_c.trys.push([1, 3, 4, 5]);
return [
4 /*yield*/,
genericComponentOverrideContext.handleCallAPI({
apiFields: apiFields,
fieldUpdates: fieldUpdates,
callAPI: props.callAPI,
}),
];
case 2:
(_a = _c.sent()),
(result = _a.result),
(generalError = _a.generalError),
(fetchError = _a.fetchError);
if (
unmounting === null || unmounting === void 0
? void 0
: unmounting.current.signal.aborted
) {
return [2 /*return*/];
}
if (generalError !== undefined || (result !== undefined && result.status !== "OK")) {
_loop_1 = function (field) {
var update = fieldUpdates.find(function (f) {
return f.id === field.id;
});
if ((update || field.clearOnSubmit === true) && updateFieldState) {
// We can do these one by one, it's almost never more than one field
updateFieldState(field.id, function (os) {
return genericComponentOverrideContext.__assign(
genericComponentOverrideContext.__assign({}, os),
{ value: update ? update.value : "" }
);
});
}
};
for (_i = 0, _b = formFields || []; _i < _b.length; _i++) {
field = _b[_i];
_loop_1(field);
}
}
if (generalError !== undefined) {
props.onError(generalError.message);
} else if (fetchError !== undefined) {
if (props.onFetchError) {
props.onFetchError(fetchError);
} else {
throw fetchError;
}
} else {
// If successful
if (result.status === "OK") {
setIsLoading(false);
props.clearError();
if (props.onSuccess !== undefined) {
props.onSuccess(result);
}
}
if (
unmounting === null || unmounting === void 0
? void 0
: unmounting.current.signal.aborted
) {
return [2 /*return*/];
}
// If field error.
if (result.status === "FIELD_ERROR") {
errorFields_1 = result.formFields;
getErrorMessage_1 = function (fs) {
var _a;
var errorMessage =
(_a = errorFields_1.find(function (ef) {
return ef.id === fs.id;
})) === null || _a === void 0
? void 0
: _a.error;
if (errorMessage === "Field is not optional") {
var fieldConfigData =
formFields === null || formFields === void 0
? void 0
: formFields.find(function (f) {
return f.id === fs.id;
});
// replace non-optional server error message from nonOptionalErrorMsg
if (
(fieldConfigData === null || fieldConfigData === void 0
? void 0
: fieldConfigData.nonOptionalErrorMsg) !== undefined
) {
return fieldConfigData === null || fieldConfigData === void 0
? void 0
: fieldConfigData.nonOptionalErrorMsg;
}
}
return errorMessage;
};
setFieldStates(function (os) {
return os.map(function (fs) {
return genericComponentOverrideContext.__assign(
genericComponentOverrideContext.__assign({}, fs),
{ error: getErrorMessage_1(fs) }
);
});
});
}
}
return [3 /*break*/, 5];
case 3:
e_1 = _c.sent();
console.error(e_1);
props.onError("SOMETHING_WENT_WRONG_ERROR");
return [3 /*break*/, 5];
case 4:
setIsLoading(false);
return [7 /*endfinally*/];
case 5:
return [2 /*return*/];
}
});
});
},
[setIsLoading, setFieldStates, props, formFields, fieldStates, updateFieldState]
);
return jsxRuntime.jsx(
FormStateContext.Provider,
genericComponentOverrideContext.__assign(
{ value: fieldStates },
{
children: jsxRuntime.jsxs(
"form",
genericComponentOverrideContext.__assign(
{
autoComplete: "on",
noValidate: true,
onSubmit: onFormSubmit,
"data-supertokens": props.formDataSupertokens,
},
{
children: [
formFields
.filter(function (f) {
return f.hidden !== true;
})
.map(function (field) {
var type = "text";
// If email or password, replace field type.
if (constants.MANDATORY_FORM_FIELDS_ID_ARRAY.includes(field.id)) {
type = field.id;
}
if (field.id === "confirm-password") {
type = "password";
}
var fstate = fieldStates.find(function (s) {
return s.id === field.id;
}) || {
id: field.id,
value: fetchDefaultValue(field),
};
return jsxRuntime.jsx(
FormRow,
genericComponentOverrideContext.__assign(
{ hasError: fstate.error !== undefined },
{
children: jsxRuntime.jsxs(React.Fragment, {
children: [
showLabels &&
(field.labelComponent !== undefined
? field.labelComponent
: jsxRuntime.jsx(Label, {
value: field.label,
showIsRequired: field.showIsRequired,
})),
jsxRuntime.jsx(InputComponentWrapper, {
type: type,
field: field,
fstate: fstate,
onInputFocus: onInputFocus,
onInputBlur: onInputBlur,
onInputChange: onInputChange,
}),
fstate.error &&
jsxRuntime.jsx(InputError, { error: fstate.error }),
],
}),
}
),
field.id
);
}),
jsxRuntime.jsx(
FormRow,
{
children: jsxRuntime.jsxs(React.Fragment, {
children: [
jsxRuntime.jsx(button.Button, {
disabled: isLoading,
isLoading: isLoading,
type: "submit",
label: buttonLabel,
}),
footer,
],
}),
},
"form-button"
),
],
}
)
),
}
)
);
};
var FormStateContext = React__default.default.createContext(undefined);
var useFormFields = function () {
var ctx = React.useContext(FormStateContext);
if (ctx === undefined) {
throw new Error("useFormState used outside FormBase");
}
return ctx;
};
exports.ErrorIcon = ErrorIcon;
exports.FormBase = FormBase;
exports.FormRow = FormRow;
exports.Label = Label;
exports.useFormFields = useFormFields;