finalized signup/signin ux regarding redirects

This commit is contained in:
Sheen Capadngan
2023-05-07 20:54:30 +08:00
parent ea86e59d4f
commit 4c434555a4
9 changed files with 46 additions and 12 deletions
@@ -28,6 +28,7 @@ declare module 'jsonwebtoken' {
userId: string; userId: string;
email: string; email: string;
authProvider: AuthProvider; authProvider: AuthProvider;
isUserCompleted: boolean,
} }
} }
+2 -1
View File
@@ -74,7 +74,7 @@ const initializePassport = async () => {
let user = await User.findOne({ let user = await User.findOne({
authProvider: AuthProvider.GOOGLE, authProvider: AuthProvider.GOOGLE,
authId: profile.id, authId: profile.id,
}) }).select('+publicKey')
if (!user) { if (!user) {
user = await new User({ user = await new User({
@@ -89,6 +89,7 @@ const initializePassport = async () => {
userId: user._id.toString(), userId: user._id.toString(),
email: user.email, email: user.email,
authProvider: user.authProvider, authProvider: user.authProvider,
isUserCompleted: !!user.publicKey
}, },
expiresIn: await getJwtProviderAuthLifetime(), expiresIn: await getJwtProviderAuthLifetime(),
secret: await getJwtProviderAuthSecret(), secret: await getJwtProviderAuthSecret(),
@@ -33,15 +33,15 @@ export default function PasswordInputStep({
const handleLogin = async () => { const handleLogin = async () => {
try { try {
setIsLoading(true); setIsLoading(true);
const isLoginSuccessful = await attemptLogin({ const loginAttempt = await attemptLogin({
email, email,
password password
}); });
if (isLoginSuccessful && isLoginSuccessful.success) { if (loginAttempt && loginAttempt.success) {
// case: login was successful // case: login was successful
if (isLoginSuccessful.mfaEnabled) { if (loginAttempt.mfaEnabled) {
// case: login requires MFA step // case: login requires MFA step
setStep(2); setStep(2);
setIsLoading(false); setIsLoading(false);
@@ -167,6 +167,7 @@ export default function UserInfoStep({
// unset signup JWT token and set JWT token // unset signup JWT token and set JWT token
SecurityClient.setSignupToken(''); SecurityClient.setSignupToken('');
SecurityClient.setToken(response.token); SecurityClient.setToken(response.token);
SecurityClient.setProviderAuthToken('');
saveTokenToLocalStorage({ saveTokenToLocalStorage({
publicKey, publicKey,
@@ -92,6 +92,8 @@ const attemptLogin = async (
) { ) {
// case: MFA is not enabled // case: MFA is not enabled
// unset provider auth token in case it was used
SecurityClient.setProviderAuthToken('');
// set JWT token // set JWT token
SecurityClient.setToken(token); SecurityClient.setToken(token);
@@ -36,7 +36,10 @@ const attemptLoginMfa = async ({
}, async () => { }, async () => {
try { try {
const clientPublicKey = client.getPublicKey(); const clientPublicKey = client.getPublicKey();
const { salt } = await login1(email, clientPublicKey); const { salt } = await login1({
email,
clientPublicKey,
});
const { const {
encryptionVersion, encryptionVersion,
@@ -56,6 +59,7 @@ const attemptLoginMfa = async ({
// unset temporary (MFA) JWT token and set JWT token // unset temporary (MFA) JWT token and set JWT token
SecurityClient.setMfaToken(''); SecurityClient.setMfaToken('');
SecurityClient.setToken(token); SecurityClient.setToken(token);
SecurityClient.setProviderAuthToken('');
const privateKey = await KeyService.decryptPrivateKey({ const privateKey = await KeyService.decryptPrivateKey({
encryptionVersion, encryptionVersion,
+16 -4
View File
@@ -9,14 +9,19 @@ export const useProviderAuth = () => {
const [providerAuthToken, setProviderAuthToken] = useState<string>( const [providerAuthToken, setProviderAuthToken] = useState<string>(
SecurityClient.getProviderAuthToken() || '' SecurityClient.getProviderAuthToken() || ''
); );
const [isProviderUserCompleted, setIsProviderUserCompleted] = useState<boolean>();
useEffect(() => { useEffect(() => {
const handleStorageChange = (event: StorageEvent) => { const handleStorageChange = (event: StorageEvent) => {
if (event.storageArea === localStorage && event.key === PROVIDER_AUTH_TOKEN_KEY) { if (event.storageArea === localStorage && event.key === PROVIDER_AUTH_TOKEN_KEY) {
if (event.newValue) { if (event.newValue) {
const token = event.newValue; const token = event.newValue;
const { userId: resultUserId, email: resultEmail } = jwt_decode(token) as any; const {
userId: resultUserId,
email: resultEmail,
isUserCompleted: resultIsUserCompleted,
} = jwt_decode(token) as any;
setIsProviderUserCompleted(resultIsUserCompleted);
setProviderAuthToken(token); setProviderAuthToken(token);
setEmail(resultEmail); setEmail(resultEmail);
setUserId(resultUserId); setUserId(resultUserId);
@@ -24,6 +29,7 @@ export const useProviderAuth = () => {
setProviderAuthToken(''); setProviderAuthToken('');
setEmail(''); setEmail('');
setUserId(''); setUserId('');
setIsProviderUserCompleted(false);
} }
setProviderAuthToken(event.newValue || ''); setProviderAuthToken(event.newValue || '');
} }
@@ -32,9 +38,14 @@ export const useProviderAuth = () => {
window.addEventListener('storage', handleStorageChange); window.addEventListener('storage', handleStorageChange);
if (providerAuthToken) { if (providerAuthToken) {
const { userId: resultUserId, email: resultEmail } = jwt_decode(providerAuthToken) as any; const {
userId: resultUserId,
email: resultEmail,
isUserCompleted: resultIsUserCompleted,
} = jwt_decode(providerAuthToken) as any;
setEmail(resultEmail); setEmail(resultEmail);
setUserId(resultUserId); setUserId(resultUserId);
setIsProviderUserCompleted(resultIsUserCompleted);
} }
return () => { return () => {
@@ -44,10 +55,11 @@ export const useProviderAuth = () => {
return { return {
email, email,
isProviderUserCompleted,
providerAuthToken, providerAuthToken,
userId, userId,
setProviderAuthToken,
setEmail, setEmail,
setProviderAuthToken,
setUserId, setUserId,
}; };
}; };
+6 -1
View File
@@ -27,9 +27,14 @@ export default function Login() {
const { const {
providerAuthToken, providerAuthToken,
email: providerEmail, email: providerEmail,
setProviderAuthToken setProviderAuthToken,
isProviderUserCompleted,
} = useProviderAuth(); } = useProviderAuth();
if (providerAuthToken && isProviderUserCompleted === false) {
router.push('/signup');
}
const setLanguage = async (to: string) => { const setLanguage = async (to: string) => {
router.push('/login', '/login', { locale: to }); router.push('/login', '/login', { locale: to });
localStorage.setItem('lang', to); localStorage.setItem('lang', to);
+9 -1
View File
@@ -35,7 +35,15 @@ export default function SignUp() {
const { data: serverDetails } = useFetchServerStatus(); const { data: serverDetails } = useFetchServerStatus();
const [isSignupWithEmail, setIsSignupWithEmail] = useState(false); const [isSignupWithEmail, setIsSignupWithEmail] = useState(false);
const { t } = useTranslation(); const { t } = useTranslation();
const { email: providerEmail, providerAuthToken } = useProviderAuth(); const {
email: providerEmail,
providerAuthToken,
isProviderUserCompleted,
} = useProviderAuth();
if (providerAuthToken && isProviderUserCompleted) {
router.push('/login');
}
if (providerAuthToken && step < 3) { if (providerAuthToken && step < 3) {
setStep(3); setStep(3);