Files
leadchat/app/javascript/v3/api/auth.js
Shivam Mishra 4f94ad4a75 feat: ensure signup verification [UPM-14] (#13858)
Previously, signing up gave immediate access to the app. Now,
unconfirmed users are redirected to a verification page where they can
resend the confirmation email.

- After signup, the user is routed to `/auth/verify-email` instead of
the dashboard
- After login, unconfirmed users are redirected to the verification page
- The dashboard route guard catches unconfirmed users and redirects them
- `active_for_authentication?` is removed from the sessions controller
so unconfirmed users can authenticate — the frontend gates access
instead
- If the user visits the verification page after already confirming,
they're automatically redirected to the dashboard
- No session is issued until the user is verified

<details><summary>Demo</summary>
<p>

#### Fresh Signup


https://github.com/user-attachments/assets/abb735e5-7c8e-44a2-801c-96d9e4823e51

#### Google Fresh Signup


https://github.com/user-attachments/assets/ab9e389a-a604-4a9d-b492-219e6d94ee3f


#### Create new account from Dashboard


https://github.com/user-attachments/assets/c456690d-1946-4e0b-834b-ad8efcea8369



</p>
</details>

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2026-04-07 13:45:17 +05:30

104 lines
2.6 KiB
JavaScript

import {
setAuthCredentials,
throwErrorMessage,
clearLocalStorageOnLogout,
} from 'dashboard/store/utils/api';
import wootAPI from './apiClient';
import {
getLoginRedirectURL,
getCredentialsFromEmail,
} from '../helpers/AuthHelper';
export const login = async ({
ssoAccountId,
ssoConversationId,
...credentials
}) => {
try {
const response = await wootAPI.post('auth/sign_in', credentials);
// Check if MFA is required
if (response.status === 206 && response.data.mfa_required) {
// Return MFA data instead of throwing error
return {
mfaRequired: true,
mfaToken: response.data.mfa_token,
};
}
setAuthCredentials(response);
clearLocalStorageOnLogout();
window.location = getLoginRedirectURL({
ssoAccountId,
ssoConversationId,
user: response.data.data,
});
return null;
} catch (error) {
// Check if it's an MFA required response
if (error.response?.status === 206 && error.response?.data?.mfa_required) {
return {
mfaRequired: true,
mfaToken: error.response.data.mfa_token,
};
}
throwErrorMessage(error);
return null;
}
};
export const register = async creds => {
try {
const { fullName, accountName } = getCredentialsFromEmail(creds.email);
const response = await wootAPI.post('api/v1/accounts.json', {
account_name: accountName,
user_full_name: fullName,
email: creds.email,
password: creds.password,
h_captcha_client_response: creds.hCaptchaClientResponse,
});
return response.data;
} catch (error) {
throwErrorMessage(error);
}
return null;
};
export const resendConfirmation = async ({ email, hCaptchaClientResponse }) => {
return wootAPI.post('resend_confirmation', {
email,
h_captcha_client_response: hCaptchaClientResponse,
});
};
export const verifyPasswordToken = async ({ confirmationToken }) => {
try {
const response = await wootAPI.post('auth/confirmation', {
confirmation_token: confirmationToken,
});
setAuthCredentials(response);
} catch (error) {
throwErrorMessage(error);
}
};
export const setNewPassword = async ({
resetPasswordToken,
password,
confirmPassword,
}) => {
try {
const response = await wootAPI.put('auth/password', {
reset_password_token: resetPasswordToken,
password_confirmation: confirmPassword,
password,
});
setAuthCredentials(response);
} catch (error) {
throwErrorMessage(error);
}
};
export const resetPassword = async ({ email }) =>
wootAPI.post('auth/password', { email });