chore: added approved messages (#40108)
## Description Conversation link - https://theappsmith.slack.com/archives/C0341RERY4R/p1743064966404339 EE PR - https://github.com/appsmithorg/appsmith-ee/pull/6989 Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.All" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/14355493550> > Commit: a3fdc2ea4ad72061f843586fd17706b3ec3ddd49 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=14355493550&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Wed, 09 Apr 2025 12:22:30 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Enhanced error messaging across authentication flows (login, signup, verification) to ensure safe and clear feedback. - Expanded user feedback for authentication issues, including login failures, account lockouts, and session-related errors. - Introduced a structured set of approved static and dynamic error messages. - **Style** - Standardized punctuation and formatting in user messages for improved readability. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
0c9d96c149
commit
82f061a1be
137
app/client/src/ce/constants/approvedErrorMessages.ts
Normal file
137
app/client/src/ce/constants/approvedErrorMessages.ts
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
import {
|
||||
createMessage,
|
||||
DEFAULT_ERROR_MESSAGE,
|
||||
ERROR_401,
|
||||
FORM_VALIDATION_EMPTY_PASSWORD,
|
||||
FORM_VALIDATION_INVALID_EMAIL,
|
||||
VERIFY_ERROR_ALREADY_VERIFIED_TITLE,
|
||||
VERIFY_ERROR_EXPIRED_TITLE,
|
||||
VERIFY_ERROR_MISMATCH_TITLE,
|
||||
FORM_VALIDATION_EMPTY_EMAIL,
|
||||
AUTH_LOGIN_TOO_MANY_ATTEMPTS,
|
||||
AUTH_INVALID_CREDENTIALS,
|
||||
AUTH_UNAUTHORIZED,
|
||||
AUTH_NOT_LOGGED_IN,
|
||||
AUTH_RESET_PASSWORD_REQUEST_INVALID,
|
||||
AUTH_LOGIN_METHOD_NOT_SUPPORTED,
|
||||
AUTH_ACCOUNT_LOCKED,
|
||||
AUTH_SESSION_INVALID,
|
||||
EMAIL_VERIFICATION_NOT_ENABLED,
|
||||
GOOGLE_RECAPTCHA_FAILED,
|
||||
PASSWORD_INSUFFICIENT_STRENGTH,
|
||||
LOGIN_PAGE_INVALID_CREDS_ERROR,
|
||||
FORM_VALIDATION_PASSWORD_RULE,
|
||||
FORM_VALIDATION_INVALID_PASSWORD,
|
||||
RESET_PASSWORD_EXPIRED_TOKEN,
|
||||
RESET_PASSWORD_INVALID_TOKEN,
|
||||
FORGOT_PASSWORD_PAGE_SUBTITLE,
|
||||
SIGNUP_PAGE_SUCCESS,
|
||||
RESET_PASSWORD_RESET_SUCCESS,
|
||||
CREATE_PASSWORD_RESET_SUCCESS,
|
||||
WELCOME_FORM_PASSWORDS_NOT_MATCHING_ERROR_MESSAGE,
|
||||
WELCOME_FORM_STRONG_PASSWORD_ERROR_MESSAGE,
|
||||
} from "./messages";
|
||||
|
||||
// List of approved static error messages that can be shown to users
|
||||
export const APPROVED_ERROR_MESSAGES = {
|
||||
// Static messages that are exact matches
|
||||
static: [
|
||||
// Authentication & Authorization
|
||||
ERROR_401,
|
||||
AUTH_LOGIN_TOO_MANY_ATTEMPTS,
|
||||
AUTH_INVALID_CREDENTIALS,
|
||||
AUTH_UNAUTHORIZED,
|
||||
AUTH_NOT_LOGGED_IN,
|
||||
AUTH_RESET_PASSWORD_REQUEST_INVALID,
|
||||
AUTH_LOGIN_METHOD_NOT_SUPPORTED,
|
||||
AUTH_ACCOUNT_LOCKED,
|
||||
AUTH_SESSION_INVALID,
|
||||
LOGIN_PAGE_INVALID_CREDS_ERROR,
|
||||
FORM_VALIDATION_PASSWORD_RULE,
|
||||
FORM_VALIDATION_INVALID_PASSWORD,
|
||||
FORM_VALIDATION_EMPTY_PASSWORD,
|
||||
FORM_VALIDATION_EMPTY_EMAIL,
|
||||
FORM_VALIDATION_INVALID_EMAIL,
|
||||
RESET_PASSWORD_EXPIRED_TOKEN,
|
||||
RESET_PASSWORD_INVALID_TOKEN,
|
||||
FORGOT_PASSWORD_PAGE_SUBTITLE,
|
||||
SIGNUP_PAGE_SUCCESS,
|
||||
RESET_PASSWORD_RESET_SUCCESS,
|
||||
CREATE_PASSWORD_RESET_SUCCESS,
|
||||
WELCOME_FORM_PASSWORDS_NOT_MATCHING_ERROR_MESSAGE,
|
||||
WELCOME_FORM_STRONG_PASSWORD_ERROR_MESSAGE,
|
||||
|
||||
// Signup Specific
|
||||
VERIFY_ERROR_ALREADY_VERIFIED_TITLE,
|
||||
VERIFY_ERROR_EXPIRED_TITLE,
|
||||
EMAIL_VERIFICATION_NOT_ENABLED,
|
||||
VERIFY_ERROR_MISMATCH_TITLE,
|
||||
GOOGLE_RECAPTCHA_FAILED,
|
||||
PASSWORD_INSUFFICIENT_STRENGTH,
|
||||
],
|
||||
|
||||
// Patterns for dynamic messages that are allowed
|
||||
patterns: [
|
||||
// Authentication patterns
|
||||
/^Please use [a-zA-Z0-9\s\.-]+ authentication to login to Appsmith$/,
|
||||
/^Authentication failed with error: [a-zA-Z0-9\s.,_\-:()'"]+$/,
|
||||
/^Invalid email domain [a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9]\.[a-zA-Z]{2,} used for sign in\/sign up\. Please contact the administrator to configure this domain if this is unexpected\.$/,
|
||||
/^Password length should be between [0-9]+ and [0-9]+$/,
|
||||
/^Unable to find user with email [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/,
|
||||
/^Please enter a valid parameter [a-zA-Z][a-zA-Z0-9._-]*\.$/,
|
||||
/^There is already an account registered with this email [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\. Please sign in instead\.$/,
|
||||
/^Cannot find an outstanding reset password request for this email\. Please initiate a request via "forgot password" button to reset your password$/,
|
||||
/^A password reset link has been sent to your email address [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} registered with Appsmith\.$/,
|
||||
/^Password must be [0-9]+-[0-9]+ characters long and include at least one uppercase letter, one lowercase letter, one number, one symbol, and no whitespaces\.$/,
|
||||
/^Signup is restricted on this instance of Appsmith\. Please contact the administrator to get an invite for user [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\.$/,
|
||||
/^The user [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,} has already been added to the workspace with role [a-zA-Z0-9\s_-]+\. To change the role, please navigate to `Manage users` page\.$/,
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if an error message is in the approved list
|
||||
* @param message The error message to validate
|
||||
* @returns boolean indicating if message is approved
|
||||
*/
|
||||
export function isApprovedErrorMessage(message: string): boolean {
|
||||
// First check static messages
|
||||
if (
|
||||
APPROVED_ERROR_MESSAGES.static.some((msg) =>
|
||||
typeof msg === "function" ? msg() === message : msg === message,
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Then check regex patterns
|
||||
return APPROVED_ERROR_MESSAGES.patterns.some((pattern) =>
|
||||
pattern.test(message),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns either the approved message or a default error message
|
||||
* @param message The error message to validate
|
||||
* @returns The original message if approved, or a default message
|
||||
*/
|
||||
export function getSafeErrorMessage(message: string): string {
|
||||
const isApproved = isApprovedErrorMessage(message);
|
||||
|
||||
if (!isApproved) {
|
||||
return createMessage(DEFAULT_ERROR_MESSAGE);
|
||||
}
|
||||
|
||||
// If it's a static message, find and return it wrapped in createMessage
|
||||
const staticMessage = APPROVED_ERROR_MESSAGES.static.find((msg) =>
|
||||
typeof msg === "function" ? msg() === message : msg === message,
|
||||
);
|
||||
|
||||
if (staticMessage) {
|
||||
return typeof staticMessage === "function"
|
||||
? createMessage(staticMessage)
|
||||
: staticMessage;
|
||||
}
|
||||
|
||||
// For pattern matches, return the original message wrapped in createMessage
|
||||
return createMessage(() => message);
|
||||
}
|
||||
|
|
@ -2663,3 +2663,27 @@ export const ADD_CUSTOM_ACTION = () => "Add custom action";
|
|||
export const CONFIG_PROPERTY_COMMAND = () => "command";
|
||||
|
||||
export const CUSTOM_ACTION_LABEL = () => "Custom Action";
|
||||
|
||||
export const AUTH_LOGIN_TOO_MANY_ATTEMPTS = () =>
|
||||
"Too many login attempts. Please try again after some time.";
|
||||
export const AUTH_INVALID_CREDENTIALS = () =>
|
||||
"Invalid credentials provided. Did you input the credentials correctly?";
|
||||
export const AUTH_UNAUTHORIZED = () => "Unauthorized access";
|
||||
export const AUTH_NOT_LOGGED_IN = () =>
|
||||
"You are not logged in. Please sign in with the registered email ID or sign up";
|
||||
export const AUTH_RESET_PASSWORD_REQUEST_INVALID = () =>
|
||||
'Cannot find an outstanding reset password request for this email. Please initiate a request via "forgot password" button to reset your password';
|
||||
export const AUTH_LOGIN_METHOD_NOT_SUPPORTED = () =>
|
||||
"Login with this method is not supported.";
|
||||
export const AUTH_ACCOUNT_LOCKED = () =>
|
||||
"Account temporarily locked due to multiple failed attempts. Please try again later.";
|
||||
export const AUTH_SESSION_INVALID = () =>
|
||||
"User session is invalid. Please log out and log in again.";
|
||||
|
||||
// Signup & Email verification
|
||||
export const EMAIL_VERIFICATION_NOT_ENABLED = () =>
|
||||
"Email Verification not enabled";
|
||||
export const GOOGLE_RECAPTCHA_FAILED = () =>
|
||||
"Google reCAPTCHA verification failed";
|
||||
export const PASSWORD_INSUFFICIENT_STRENGTH = () =>
|
||||
"Insufficient password strength";
|
||||
|
|
|
|||
1
app/client/src/ee/constants/approvedErrorMessages.ts
Normal file
1
app/client/src/ee/constants/approvedErrorMessages.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "ce/constants/approvedErrorMessages";
|
||||
|
|
@ -53,6 +53,7 @@ import { FEATURE_FLAG } from "ee/entities/FeatureFlag";
|
|||
import { getHTMLPageTitle } from "ee/utils/BusinessFeatures/brandingPageHelpers";
|
||||
import * as Sentry from "@sentry/react";
|
||||
import CsrfTokenInput from "pages/UserAuth/CsrfTokenInput";
|
||||
import { getSafeErrorMessage } from "ee/constants/approvedErrorMessages";
|
||||
|
||||
const validate = (values: LoginFormValues, props: ValidateProps) => {
|
||||
const errors: LoginFormValues = {};
|
||||
|
|
@ -175,7 +176,7 @@ export function Login(props: LoginFormProps) {
|
|||
}
|
||||
>
|
||||
{!!errorMessage && errorMessage !== "true"
|
||||
? errorMessage
|
||||
? getSafeErrorMessage(errorMessage)
|
||||
: createMessage(LOGIN_PAGE_INVALID_CREDS_ERROR)}
|
||||
</Callout>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ import CsrfTokenInput from "pages/UserAuth/CsrfTokenInput";
|
|||
import { useIsCloudBillingEnabled } from "hooks";
|
||||
import { isLoginHostname } from "utils/cloudBillingUtils";
|
||||
import { getIsAiAgentFlowEnabled } from "ee/selectors/aiAgentSelectors";
|
||||
import { getSafeErrorMessage } from "ee/constants/approvedErrorMessages";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
|
@ -260,7 +261,9 @@ export function SignUp(props: SignUpFormProps) {
|
|||
<title>{htmlPageTitle}</title>
|
||||
</Helmet>
|
||||
|
||||
{showError && <Callout kind="error">{errorMessage}</Callout>}
|
||||
{showError && (
|
||||
<Callout kind="error">{getSafeErrorMessage(errorMessage)}</Callout>
|
||||
)}
|
||||
{socialLoginList.length > 0 && (
|
||||
<ThirdPartyAuth logins={socialLoginList} type={"SIGNUP"} />
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { useResendEmailVerification } from "./helpers";
|
|||
import type { RouteComponentProps } from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
|
||||
import { getSafeErrorMessage } from "ee/constants/approvedErrorMessages";
|
||||
|
||||
const Body = styled.div`
|
||||
display: flex;
|
||||
|
|
@ -77,7 +78,7 @@ const VerificationError = (
|
|||
<Container testId="verification-error" title="">
|
||||
<Body>
|
||||
<Callout kind="error">
|
||||
<Text kind={"body-m"}>{message}</Text>
|
||||
<Text kind={"body-m"}>{getSafeErrorMessage(message || "")}</Text>
|
||||
</Callout>
|
||||
</Body>
|
||||
<Body>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user