Skip to content

Commit bd6ee6c

Browse files
authored
Merge pull request #45 from authorizerdev/feat/update-js-major
feat: update js major version
2 parents 5cf167c + 5e6a16f commit bd6ee6c

11 files changed

Lines changed: 203 additions & 52 deletions

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "1.1.18",
2+
"version": "1.2.0",
33
"license": "MIT",
44
"main": "dist/index.js",
55
"typings": "dist/index.d.ts",
@@ -66,7 +66,7 @@
6666
"typescript": "^5.2.2"
6767
},
6868
"dependencies": {
69-
"@authorizerdev/authorizer-js": "^1.2.18",
69+
"@authorizerdev/authorizer-js": "^2.0.0-beta.3",
7070
"validator": "^13.11.0"
7171
}
7272
}

src/components/AuthorizerBasicAuthLogin.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ export const AuthorizerBasicAuthLogin: FC<{
9393
data.roles = roles;
9494
}
9595

96-
const res = await authorizerRef.login(data);
96+
const { data: res, errors } = await authorizerRef.login(data);
97+
if (errors && errors.length) {
98+
setError(errors[0].message);
99+
setLoading(false);
100+
return;
101+
}
97102
// if totp is enabled for the first time show totp screen with scanner
98103
if (
99104
res &&

src/components/AuthorizerForgotPassword.tsx

Lines changed: 100 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,41 @@
11
import React, { FC, useEffect, useState } from 'react';
22
import isEmail from 'validator/es/lib/isEmail';
3+
import isMobilePhone from 'validator/es/lib/isMobilePhone';
34

45
import styles from '../styles/default.css';
56
import { ButtonAppearance, MessageType, Views } from '../constants';
67
import { useAuthorizer } from '../contexts/AuthorizerContext';
78
import { StyledButton, StyledFooter, StyledLink } from '../styledComponents';
89
import { formatErrorMessage } from '../utils/format';
910
import { Message } from './Message';
11+
import { OtpDataType } from '../types';
12+
import { AuthorizerResetPassword } from './AuthorizerResetPassword';
1013

1114
interface InputDataType {
12-
email: string | null;
15+
email_or_phone_number: string | null;
1316
}
1417

18+
const initOtpData: OtpDataType = {
19+
is_screen_visible: false,
20+
email: '',
21+
phone_number: '',
22+
};
23+
1524
export const AuthorizerForgotPassword: FC<{
1625
setView?: (v: Views) => void;
1726
onForgotPassword?: (data: any) => void;
27+
onPasswordReset?: () => void;
1828
urlProps?: Record<string, any>;
19-
}> = ({ setView, onForgotPassword, urlProps }) => {
29+
}> = ({ setView, onForgotPassword, onPasswordReset, urlProps }) => {
2030
const [error, setError] = useState(``);
2131
const [loading, setLoading] = useState(false);
2232
const [successMessage, setSuccessMessage] = useState(``);
33+
const [otpData, setOtpData] = useState<OtpDataType>({ ...initOtpData });
2334
const [formData, setFormData] = useState<InputDataType>({
24-
email: null,
35+
email_or_phone_number: null,
2536
});
2637
const [errorData, setErrorData] = useState<InputDataType>({
27-
email: null,
38+
email_or_phone_number: null,
2839
});
2940
const { authorizerRef, config } = useAuthorizer();
3041

@@ -36,22 +47,50 @@ export const AuthorizerForgotPassword: FC<{
3647
e.preventDefault();
3748
try {
3849
setLoading(true);
39-
40-
const res = await authorizerRef.forgotPassword({
41-
email: formData.email || '',
50+
let email: string = '';
51+
let phone_number: string = '';
52+
if (formData.email_or_phone_number) {
53+
if (isEmail(formData.email_or_phone_number)) {
54+
email = formData.email_or_phone_number;
55+
} else if (isMobilePhone(formData.email_or_phone_number)) {
56+
phone_number = formData.email_or_phone_number;
57+
}
58+
}
59+
if (!email && !phone_number) {
60+
setErrorData({
61+
...errorData,
62+
email_or_phone_number: 'Invalid email or phone number',
63+
});
64+
setLoading(false);
65+
return;
66+
}
67+
const { data: res, errors } = await authorizerRef.forgotPassword({
68+
email: email,
69+
phone_number: phone_number,
4270
state: urlProps?.state || '',
4371
redirect_uri:
4472
urlProps?.redirect_uri ||
4573
config.redirectURL ||
4674
window.location.origin,
4775
});
4876
setLoading(false);
49-
50-
if (res && res.message) {
77+
if (errors && errors.length) {
78+
setError(formatErrorMessage(errors[0]?.message));
79+
return;
80+
}
81+
if (res?.message) {
5182
setError(``);
5283
setSuccessMessage(res.message);
84+
if (res?.should_show_mobile_otp_screen) {
85+
setOtpData({
86+
...otpData,
87+
is_screen_visible: true,
88+
email: email,
89+
phone_number: phone_number,
90+
});
91+
return;
92+
}
5393
}
54-
5594
if (onForgotPassword) {
5695
onForgotPassword(res);
5796
}
@@ -66,17 +105,38 @@ export const AuthorizerForgotPassword: FC<{
66105
};
67106

68107
useEffect(() => {
69-
if (formData.email === '') {
70-
setErrorData({ ...errorData, email: 'Email is required' });
71-
} else if (formData.email && !isEmail(formData.email)) {
72-
setErrorData({ ...errorData, email: 'Please enter valid email' });
108+
if (formData.email_or_phone_number === '') {
109+
setErrorData({
110+
...errorData,
111+
email_or_phone_number: 'Email OR Phone Number is required',
112+
});
113+
} else if (
114+
formData.email_or_phone_number !== null &&
115+
!isEmail(formData.email_or_phone_number || '') &&
116+
!isMobilePhone(formData.email_or_phone_number || '')
117+
) {
118+
setErrorData({
119+
...errorData,
120+
email_or_phone_number: 'Invalid Email OR Phone Number',
121+
});
73122
} else {
74-
setErrorData({ ...errorData, email: null });
123+
setErrorData({ ...errorData, email_or_phone_number: null });
75124
}
76-
}, [formData.email]);
125+
}, [formData.email_or_phone_number]);
77126

78127
if (successMessage) {
79-
return <Message type={MessageType.Success} text={successMessage} />;
128+
return (
129+
<>
130+
<Message type={MessageType.Success} text={successMessage} />
131+
{otpData.is_screen_visible && (
132+
<AuthorizerResetPassword
133+
showOTPInput
134+
onReset={onPasswordReset}
135+
phone_number={otpData.phone_number}
136+
/>
137+
)}
138+
</>
139+
);
80140
}
81141

82142
return (
@@ -93,32 +153,42 @@ export const AuthorizerForgotPassword: FC<{
93153
<div className={styles['styled-form-group']}>
94154
<label
95155
className={styles['form-input-label']}
96-
htmlFor="authorizer-forgot-password-email"
156+
htmlFor="authorizer-forgot-password-email-or-phone-number"
97157
>
98-
<span>* </span>Email
158+
<span>* </span>Email / Phone Number
99159
</label>
100160
<input
101-
name="email"
102-
id="authorizer-forgot-password-email"
161+
name="email_or_phone_number"
162+
id="authorizer-forgot-password-email-or-phone-number"
103163
className={`${styles['form-input-field']} ${
104-
errorData.email ? styles['input-error-content'] : null
164+
errorData.email_or_phone_number
165+
? styles['input-error-content']
166+
: null
105167
}`}
106-
placeholder="eg. foo@bar.com"
107-
type="email"
108-
value={formData.email || ''}
109-
onChange={(e) => onInputChange('email', e.target.value)}
168+
placeholder="eg. hello@world.com / +919999999999"
169+
type="text"
170+
value={formData.email_or_phone_number || ''}
171+
onChange={(e) =>
172+
onInputChange('email_or_phone_number', e.target.value)
173+
}
110174
/>
111-
{errorData.email && (
112-
<div className={styles['form-input-error']}>{errorData.email}</div>
175+
{errorData.email_or_phone_number && (
176+
<div className={styles['form-input-error']}>
177+
{errorData.email_or_phone_number}
178+
</div>
113179
)}
114180
</div>
115181
<br />
116182
<StyledButton
117183
type="submit"
118-
disabled={loading || !!errorData.email || !formData.email}
184+
disabled={
185+
loading ||
186+
!!errorData.email_or_phone_number ||
187+
!formData.email_or_phone_number
188+
}
119189
appearance={ButtonAppearance.Primary}
120190
>
121-
{loading ? `Processing ...` : `Send Email`}
191+
{loading ? `Processing ...` : `Request Change`}
122192
</StyledButton>
123193
</form>
124194
{setView && (

src/components/AuthorizerMagicLinkLogin.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,12 @@ export const AuthorizerMagicLinkLogin: FC<{
4747
if (roles && roles.length) {
4848
data.roles = roles;
4949
}
50-
const res = await authorizerRef.magicLinkLogin(data);
50+
const { data: res, errors } = await authorizerRef.magicLinkLogin(data);
5151
setLoading(false);
52+
if (errors && errors.length) {
53+
setError(formatErrorMessage(errors[0]?.message));
54+
return;
55+
}
5256

5357
if (res) {
5458
setError(``);

src/components/AuthorizerResetPassword.tsx

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,32 @@ import { getSearchParams } from '../utils/url';
1010
import PasswordStrengthIndicator from './PasswordStrengthIndicator';
1111

1212
type Props = {
13+
showOTPInput?: boolean;
1314
onReset?: (res: any) => void;
15+
phone_number?: string;
1416
};
1517

1618
interface InputDataType {
19+
otp: string | null;
1720
password: string | null;
1821
confirmPassword: string | null;
1922
}
2023

21-
export const AuthorizerResetPassword: FC<Props> = ({ onReset }) => {
24+
export const AuthorizerResetPassword: FC<Props> = ({
25+
onReset,
26+
showOTPInput,
27+
phone_number,
28+
}) => {
2229
const { token, redirect_uri } = getSearchParams();
23-
const [error, setError] = useState(!token ? `Invalid token` : ``);
30+
const [error, setError] = useState('');
2431
const [loading, setLoading] = useState(false);
2532
const [formData, setFormData] = useState<InputDataType>({
33+
otp: null,
2634
password: null,
2735
confirmPassword: null,
2836
});
2937
const [errorData, setErrorData] = useState<InputDataType>({
38+
otp: null,
3039
password: null,
3140
confirmPassword: null,
3241
});
@@ -41,12 +50,18 @@ export const AuthorizerResetPassword: FC<Props> = ({ onReset }) => {
4150
e.preventDefault();
4251
setLoading(true);
4352
try {
44-
const res = await authorizerRef.resetPassword({
53+
const { data: res, errors } = await authorizerRef.resetPassword({
4554
token,
55+
otp: formData.otp || '',
56+
phone_number: phone_number || '',
4657
password: formData.password || '',
4758
confirm_password: formData.confirmPassword || '',
4859
});
4960
setLoading(false);
61+
if (errors && errors.length) {
62+
setError(formatErrorMessage(errors[0]?.message));
63+
return;
64+
}
5065
setError(``);
5166
if (onReset) {
5267
onReset(res);
@@ -107,6 +122,30 @@ export const AuthorizerResetPassword: FC<Props> = ({ onReset }) => {
107122
<Message type={MessageType.Error} text={error} onClose={onErrorClose} />
108123
)}
109124
<form onSubmit={onSubmit} name="authorizer-reset-password-form">
125+
{showOTPInput && (
126+
<div className={styles['styled-form-group']}>
127+
<label
128+
className={styles['form-input-label']}
129+
htmlFor="authorizer-verify-otp"
130+
>
131+
<span>* </span>OTP (One Time Password)
132+
</label>
133+
<input
134+
name="otp"
135+
id="authorizer-verify-otp"
136+
className={`${styles['form-input-field']} ${
137+
errorData.otp ? styles['input-error-content'] : null
138+
}`}
139+
placeholder="e.g.- AB123C"
140+
type="password"
141+
value={formData.otp || ''}
142+
onChange={(e) => onInputChange('otp', e.target.value)}
143+
/>
144+
{errorData.otp && (
145+
<div className={styles['form-input-error']}>{errorData.otp}</div>
146+
)}
147+
</div>
148+
)}
110149
<div className={styles['styled-form-group']}>
111150
<label
112151
className={styles['form-input-label']}

src/components/AuthorizerRoot.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,16 @@ export const AuthorizerRoot: FC<{
1717
onSignup?: (data: AuthToken | void) => void;
1818
onMagicLinkLogin?: (data: any) => void;
1919
onForgotPassword?: (data: any) => void;
20+
onPasswordReset?: () => void;
2021
roles?: string[];
21-
}> = ({ onLogin, onSignup, onMagicLinkLogin, onForgotPassword, roles }) => {
22+
}> = ({
23+
onLogin,
24+
onSignup,
25+
onMagicLinkLogin,
26+
onForgotPassword,
27+
onPasswordReset,
28+
roles,
29+
}) => {
2230
const [view, setView] = useState(Views.Login);
2331
const { config } = useAuthorizer();
2432
const searchParams = new URLSearchParams(
@@ -84,6 +92,7 @@ export const AuthorizerRoot: FC<{
8492
<AuthorizerForgotPassword
8593
setView={setView}
8694
onForgotPassword={onForgotPassword}
95+
onPasswordReset={onPasswordReset}
8796
urlProps={urlProps}
8897
/>
8998
)}

0 commit comments

Comments
 (0)