Harden production auth for hackathon demo.
Configure Supabase redirect URLs, disable email confirmation on the remote project, create profile and avatar rows on signup, and route new users to /protected when a session is returned immediately. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -16,12 +16,13 @@ export default function Page() {
|
|||||||
<CardTitle className="text-2xl">
|
<CardTitle className="text-2xl">
|
||||||
Thank you for signing up!
|
Thank you for signing up!
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
<CardDescription>Check your email to confirm</CardDescription>
|
<CardDescription>
|
||||||
|
{`You're ready to go`}
|
||||||
|
</CardDescription>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
You've successfully signed up. Please check your email to
|
Your account is ready. You can sign in and start using Habit Pet.
|
||||||
confirm your account before signing in.
|
|
||||||
</p>
|
</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -40,14 +40,18 @@ export function SignUpForm({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const { error } = await supabase.auth.signUp({
|
const { data, error } = await supabase.auth.signUp({
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
options: {
|
options: {
|
||||||
emailRedirectTo: `${window.location.origin}/protected`,
|
emailRedirectTo: `${window.location.origin}/auth/confirm?next=/protected`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
if (data.session) {
|
||||||
|
router.push("/protected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
router.push("/auth/sign-up-success");
|
router.push("/auth/sign-up-success");
|
||||||
} catch (error: unknown) {
|
} catch (error: unknown) {
|
||||||
setError(error instanceof Error ? error.message : "An error occurred");
|
setError(error instanceof Error ? error.message : "An error occurred");
|
||||||
|
|||||||
@@ -30,8 +30,14 @@ file_size_limit = "50MiB"
|
|||||||
|
|
||||||
[auth]
|
[auth]
|
||||||
enabled = true
|
enabled = true
|
||||||
site_url = "http://127.0.0.1:3000"
|
site_url = "https://cursor-hackathon-flame.vercel.app"
|
||||||
additional_redirect_urls = ["http://127.0.0.1:3000/**", "http://localhost:3000/**"]
|
additional_redirect_urls = [
|
||||||
|
"http://127.0.0.1:3000/**",
|
||||||
|
"http://localhost:3000/**",
|
||||||
|
"https://cursor-hackathon-flame.vercel.app/**",
|
||||||
|
"https://cursor-hackathon-*-harkamal-randhawas-projects.vercel.app/**",
|
||||||
|
"https://cursor-hackathon-*-recentrunner-harkamal-randhawas-projects.vercel.app/**",
|
||||||
|
]
|
||||||
jwt_expiry = 3600
|
jwt_expiry = 3600
|
||||||
enable_refresh_token_rotation = true
|
enable_refresh_token_rotation = true
|
||||||
refresh_token_reuse_interval = 10
|
refresh_token_reuse_interval = 10
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
create or replace function public.handle_new_user()
|
||||||
|
returns trigger
|
||||||
|
language plpgsql
|
||||||
|
security definer
|
||||||
|
set search_path = public
|
||||||
|
as $$
|
||||||
|
begin
|
||||||
|
insert into public.profiles (id, display_name)
|
||||||
|
values (
|
||||||
|
new.id,
|
||||||
|
coalesce(new.raw_user_meta_data ->> 'display_name', split_part(new.email, '@', 1))
|
||||||
|
)
|
||||||
|
on conflict (id) do nothing;
|
||||||
|
|
||||||
|
insert into public.avatar_state (user_id)
|
||||||
|
values (new.id)
|
||||||
|
on conflict (user_id) do nothing;
|
||||||
|
|
||||||
|
return new;
|
||||||
|
end;
|
||||||
|
$$;
|
||||||
|
|
||||||
|
drop trigger if exists on_auth_user_created on auth.users;
|
||||||
|
|
||||||
|
create trigger on_auth_user_created
|
||||||
|
after insert on auth.users
|
||||||
|
for each row
|
||||||
|
execute function public.handle_new_user();
|
||||||
Reference in New Issue
Block a user