@oxyhq/services
Version:
Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀
165 lines (163 loc) • 5.91 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _reactNative = require("react-native");
var _vectorIcons = require("@expo/vector-icons");
var _GroupedPillButtons = _interopRequireDefault(require("../../components/internal/GroupedPillButtons"));
var _TextField = _interopRequireDefault(require("../../components/internal/TextField"));
var _useI18n = require("../../hooks/useI18n");
var _spacing = require("../../styles/spacing");
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const RecoverResetPasswordStep = ({
colors,
styles,
nextStep,
prevStep,
identifier,
verificationCode,
password,
confirmPassword,
setPassword,
setConfirmPassword,
errorMessage,
setErrorMessage,
isLoading,
setIsLoading,
oxyServices
}) => {
const {
t
} = (0, _useI18n.useI18n)();
const baseStyles = _spacing.stepStyles;
const webShadowReset = _reactNative.Platform.OS === 'web' ? {
boxShadow: 'none'
} : null;
const handleReset = async () => {
if (!password || password.length < 8) {
setErrorMessage(t('recover.password.minLength') || 'Password must be at least 8 characters long');
return;
}
if (password !== confirmPassword) {
setErrorMessage(t('recover.password.mismatch') || 'Passwords do not match');
return;
}
setErrorMessage('');
setIsLoading(true);
try {
const code = verificationCode?.trim();
if (!code) throw new Error(t('recover.missingCode') || 'Missing code');
// Heuristic: recovery key starts with 'oxy-' or longer strings, backup codes have dashes of short format, else assume TOTP
if (code.toLowerCase().startsWith('oxy-') || code.length >= 16) {
await oxyServices.resetPasswordWithRecoveryKey(identifier, code, password);
} else if (/[A-Za-z0-9]+-[A-Za-z0-9]+/.test(code)) {
await oxyServices.resetPasswordWithBackupCode(identifier, code, password);
} else {
await oxyServices.resetPasswordWithTotp(identifier, code, password);
}
nextStep();
} catch (e) {
setErrorMessage(e?.message || t('recover.password.resetFailed') || 'Failed to reset password');
} finally {
setIsLoading(false);
}
};
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [baseStyles.container, baseStyles.sectionSpacing, baseStyles.header],
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [styles.modernTitle, baseStyles.title, {
color: colors.text,
marginBottom: 0,
marginTop: 0
}],
children: t('recover.newPassword')
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
style: [styles.modernSubtitle, baseStyles.subtitle, {
color: colors.secondaryText,
marginBottom: 0,
marginTop: 0
}],
children: [t('recover.title'), " @", identifier]
})]
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [baseStyles.container, baseStyles.sectionSpacing],
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
style: [stylesheet.formCard, {
backgroundColor: colors.inputBackground || colors.card || 'rgba(0,0,0,0.04)'
}, webShadowReset],
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
label: t('common.labels.password'),
leading: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
name: "lock-closed-outline",
size: 24,
color: colors.secondaryText
}),
value: password,
onChangeText: setPassword,
secureTextEntry: true,
autoCapitalize: "none",
autoCorrect: false,
variant: "filled",
error: errorMessage || undefined,
onSubmitEditing: handleReset,
autoFocus: true,
style: {
marginBottom: 0
}
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
label: t('common.labels.confirmPassword'),
leading: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
name: "lock-closed-outline",
size: 24,
color: colors.secondaryText
}),
value: confirmPassword,
onChangeText: setConfirmPassword,
secureTextEntry: true,
autoCapitalize: "none",
autoCorrect: false,
variant: "filled",
onSubmitEditing: handleReset,
style: {
marginBottom: 0
}
})]
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
style: [baseStyles.container, baseStyles.sectionSpacing, baseStyles.buttonContainer],
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_GroupedPillButtons.default, {
buttons: [{
text: t('common.actions.back'),
onPress: prevStep,
icon: 'arrow-back',
variant: 'transparent'
}, {
text: t('common.actions.resetPassword'),
onPress: handleReset,
icon: 'key-outline',
variant: 'primary',
loading: isLoading,
disabled: isLoading || !password || password.length < 8 || password !== confirmPassword
}],
colors: colors
})
})]
});
};
var _default = exports.default = RecoverResetPasswordStep;
const stylesheet = _reactNative.StyleSheet.create({
formCard: {
width: '100%',
maxWidth: 420,
borderRadius: 28,
paddingHorizontal: 20,
paddingVertical: 18,
gap: _spacing.STEP_INNER_GAP,
alignItems: 'stretch',
shadowColor: 'transparent'
}
});
//# sourceMappingURL=RecoverResetPasswordStep.js.map