mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
feat(frontend): Improve waitlist error display & messages (#11206)
Improves the "not on waitlist" error display based on feedback. - Follow-up to #11198 - Follow-up to #11196 ### Changes 🏗️ - Use standard `ErrorCard` - Improve text strings - Merge `isWaitlistError` and `isWaitlistErrorFromParams` ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: <!-- Put your test plan here: --> - [x] We need to test in dev becasue we don't have a waitlist locally and will revert if it doesnt work - deploy to dev environment and sign up with a non approved account and see if error appears
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { Button } from "@/components/atoms/Button/Button";
|
||||
import { Text } from "@/components/atoms/Text/Text";
|
||||
import { Card } from "@/components/atoms/Card/Card";
|
||||
import { WaitlistErrorContent } from "@/components/auth/WaitlistErrorContent";
|
||||
import { isWaitlistErrorFromParams } from "@/app/api/auth/utils";
|
||||
import { isWaitlistError } from "@/app/api/auth/utils";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ErrorCard } from "@/components/molecules/ErrorCard/ErrorCard";
|
||||
import { environment } from "@/services/environment";
|
||||
|
||||
export default function AuthErrorPage() {
|
||||
@@ -38,12 +38,9 @@ export default function AuthErrorPage() {
|
||||
}
|
||||
|
||||
// Check if this is a waitlist/not allowed error
|
||||
const isWaitlistError = isWaitlistErrorFromParams(
|
||||
errorCode,
|
||||
errorDescription,
|
||||
);
|
||||
const isWaitlistErr = isWaitlistError(errorCode, errorDescription);
|
||||
|
||||
if (isWaitlistError) {
|
||||
if (isWaitlistErr) {
|
||||
return (
|
||||
<div className="flex h-screen items-center justify-center">
|
||||
<Card className="w-full max-w-md p-8">
|
||||
@@ -56,34 +53,25 @@ export default function AuthErrorPage() {
|
||||
);
|
||||
}
|
||||
|
||||
// Default error display for other types of errors
|
||||
// Use ErrorCard for consistent error display
|
||||
const errorMessage = errorDescription
|
||||
? `${errorDescription}. If this error persists, please contact support at contact@agpt.co`
|
||||
: "An authentication error occurred. Please contact support at contact@agpt.co";
|
||||
|
||||
return (
|
||||
<div className="flex h-screen items-center justify-center">
|
||||
<Card className="w-full max-w-md p-8">
|
||||
<div className="flex flex-col items-center gap-6">
|
||||
<Text variant="h3">Authentication Error</Text>
|
||||
<div className="flex flex-col gap-2 text-center">
|
||||
{errorType && (
|
||||
<Text variant="body">
|
||||
<strong>Error Type:</strong> {errorType}
|
||||
</Text>
|
||||
)}
|
||||
{errorCode && (
|
||||
<Text variant="body">
|
||||
<strong>Error Code:</strong> {errorCode}
|
||||
</Text>
|
||||
)}
|
||||
{errorDescription && (
|
||||
<Text variant="body">
|
||||
<strong>Description:</strong> {errorDescription}
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
<Button variant="primary" onClick={() => router.push("/login")}>
|
||||
Back to Login
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
<div className="flex h-screen items-center justify-center p-4">
|
||||
<div className="w-full max-w-md">
|
||||
<ErrorCard
|
||||
responseError={{
|
||||
message: errorMessage,
|
||||
detail: errorCode
|
||||
? `Error code: ${errorCode}${errorType ? ` (${errorType})` : ""}`
|
||||
: undefined,
|
||||
}}
|
||||
context="authentication"
|
||||
onRetry={() => router.push("/login")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ export function useSignupPage() {
|
||||
resetCaptcha();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/auth/provider", {
|
||||
method: "POST",
|
||||
@@ -71,7 +72,6 @@ export function useSignupPage() {
|
||||
setIsGoogleLoading(false);
|
||||
resetCaptcha();
|
||||
|
||||
// Check for waitlist error
|
||||
if (error === "not_allowed") {
|
||||
setShowNotAllowedModal(true);
|
||||
return;
|
||||
@@ -149,6 +149,7 @@ export function useSignupPage() {
|
||||
setShowNotAllowedModal(true);
|
||||
return;
|
||||
}
|
||||
|
||||
toast({
|
||||
title: result?.error || "Signup failed",
|
||||
variant: "destructive",
|
||||
|
||||
@@ -33,7 +33,7 @@ export async function POST(request: Request) {
|
||||
|
||||
if (error) {
|
||||
// Check for waitlist/allowlist error
|
||||
if (isWaitlistError(error)) {
|
||||
if (isWaitlistError(error?.code, error?.message)) {
|
||||
logWaitlistError("OAuth Provider", error.message);
|
||||
return NextResponse.json({ error: "not_allowed" }, { status: 403 });
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ export async function POST(request: Request) {
|
||||
turnstileToken ?? "",
|
||||
"signup",
|
||||
);
|
||||
|
||||
if (!captchaOk) {
|
||||
return NextResponse.json(
|
||||
{ error: "CAPTCHA verification failed. Please try again." },
|
||||
@@ -48,8 +49,7 @@ export async function POST(request: Request) {
|
||||
const { data, error } = await supabase.auth.signUp(parsed.data);
|
||||
|
||||
if (error) {
|
||||
// Check for waitlist/allowlist error
|
||||
if (isWaitlistError(error)) {
|
||||
if (isWaitlistError(error?.code, error?.message)) {
|
||||
logWaitlistError("Signup", error.message);
|
||||
return NextResponse.json({ error: "not_allowed" }, { status: 403 });
|
||||
}
|
||||
|
||||
@@ -1,49 +1,45 @@
|
||||
/**
|
||||
* Checks if a Supabase auth error is related to the waitlist/allowlist
|
||||
* Checks if an error is related to the waitlist/allowlist
|
||||
*
|
||||
* Can be used with either:
|
||||
* - Error objects from Supabase auth operations: `isWaitlistError(error?.code, error?.message)`
|
||||
* - URL parameters from OAuth callbacks: `isWaitlistError(errorCode, errorDescription)`
|
||||
*
|
||||
* The PostgreSQL trigger raises P0001 with message format:
|
||||
* "The email address "email" is not allowed to register. Please contact support for assistance."
|
||||
*
|
||||
* @param error - The error object from Supabase auth operations
|
||||
* @returns true if this is a waitlist/allowlist error
|
||||
*/
|
||||
export function isWaitlistError(error: any): boolean {
|
||||
if (!error?.message) return false;
|
||||
|
||||
if (error?.code === "P0001") return true;
|
||||
|
||||
return (
|
||||
error.message.includes("P0001") || // PostgreSQL custom error code
|
||||
error.message.includes("not allowed to register") || // Trigger message
|
||||
error.message.toLowerCase().includes("allowed_users") // Table reference
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if OAuth callback URL parameters indicate a waitlist error
|
||||
*
|
||||
* This is for the auth-code-error page which receives errors via URL hash params
|
||||
* from Supabase OAuth redirects
|
||||
*
|
||||
* @param errorCode - The error_code parameter from the URL
|
||||
* @param errorDescription - The error_description parameter from the URL
|
||||
* @param code - Error code (e.g., "P0001", "unexpected_failure") or null
|
||||
* @param message - Error message/description or null
|
||||
* @returns true if this appears to be a waitlist/allowlist error
|
||||
*/
|
||||
export function isWaitlistErrorFromParams(
|
||||
errorCode?: string | null,
|
||||
errorDescription?: string | null,
|
||||
export function isWaitlistError(
|
||||
code?: string | null,
|
||||
message?: string | null,
|
||||
): boolean {
|
||||
if (!errorDescription) return false;
|
||||
// Check for explicit PostgreSQL trigger error code
|
||||
if (code === "P0001") return true;
|
||||
|
||||
if (errorCode === "P0001") return true;
|
||||
if (!message) return false;
|
||||
|
||||
const description = errorDescription.toLowerCase();
|
||||
const lowerMessage = message.toLowerCase();
|
||||
|
||||
// Check for the generic database error that occurs during waitlist check
|
||||
// This happens when Supabase wraps the PostgreSQL trigger error
|
||||
if (
|
||||
code === "unexpected_failure" &&
|
||||
message === "Database error saving new user"
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for various waitlist-related patterns in the message
|
||||
return (
|
||||
description.includes("p0001") || // PostgreSQL error code might be in description
|
||||
description.includes("not allowed") ||
|
||||
description.includes("waitlist") ||
|
||||
description.includes("allowlist") ||
|
||||
description.includes("allowed_users")
|
||||
lowerMessage.includes("p0001") || // PostgreSQL error code in message
|
||||
lowerMessage.includes("not allowed") || // Common waitlist message
|
||||
lowerMessage.includes("waitlist") || // Explicit waitlist mention
|
||||
lowerMessage.includes("allowlist") || // Explicit allowlist mention
|
||||
lowerMessage.includes("allowed_users") || // Database table reference
|
||||
lowerMessage.includes("not allowed to register") // Full trigger message
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,15 @@ export function WaitlistErrorContent({
|
||||
exact same email address you used when signing up.
|
||||
</Text>
|
||||
<Text variant="small" className="text-center text-muted-foreground">
|
||||
If you're not sure which email you used or need help,{" "}
|
||||
If you're not sure which email you used or need help, contact us
|
||||
at{" "}
|
||||
<a
|
||||
href="mailto:contact@agpt.co"
|
||||
className="underline hover:text-foreground"
|
||||
>
|
||||
contact@agpt.co
|
||||
</a>{" "}
|
||||
or{" "}
|
||||
<a
|
||||
href="https://discord.gg/autogpt"
|
||||
target="_blank"
|
||||
|
||||
Reference in New Issue
Block a user