-
Notifications
You must be signed in to change notification settings - Fork 579
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
replaced auth with new auth and updated packages
- Loading branch information
Showing
13 changed files
with
353 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,60 @@ | ||
import { Database } from '@/types/supabase' | ||
import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' | ||
import { cookies } from 'next/headers' | ||
import { NextResponse } from 'next/server' | ||
import { Database } from "@/types/supabase"; | ||
import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs"; | ||
import { isAuthApiError } from "@supabase/supabase-js"; | ||
import { cookies } from "next/headers"; | ||
import { NextRequest, NextResponse } from "next/server"; | ||
|
||
import type { NextRequest } from 'next/server' | ||
export async function GET(req: NextRequest) { | ||
const requestUrl = new URL(req.url); | ||
const code = requestUrl.searchParams.get("code"); | ||
const error = requestUrl.searchParams.get("error"); | ||
const next = requestUrl.searchParams.get("next") || "/"; | ||
const error_description = requestUrl.searchParams.get("error_description"); | ||
|
||
export const dynamic = 'force-dynamic' | ||
|
||
export async function GET(request: NextRequest) { | ||
const requestUrl = new URL(request.url) | ||
const code = requestUrl.searchParams.get('code') | ||
if (error) { | ||
console.log("error: ", { | ||
error, | ||
error_description, | ||
code, | ||
}); | ||
} | ||
|
||
if (code) { | ||
const supabase = createRouteHandlerClient<Database>({ cookies }) | ||
await supabase.auth.exchangeCodeForSession(code) | ||
const supabase = createRouteHandlerClient<Database>({ cookies }); | ||
|
||
try { | ||
await supabase.auth.exchangeCodeForSession(code); | ||
|
||
// ater exchanging the code, we should check if the user has a feature-flag row and a credits now, if not, we should create one | ||
|
||
const { data: user, error: userError } = await supabase.auth.getUser(); | ||
|
||
if (userError || !user) { | ||
console.error( | ||
"[login] [session] [500] Error getting user: ", | ||
userError | ||
); | ||
return NextResponse.redirect( | ||
`${requestUrl.origin}/login/failed?err=500` | ||
); | ||
} | ||
} catch (error) { | ||
if (isAuthApiError(error)) { | ||
console.error( | ||
"[login] [session] [500] Error exchanging code for session: ", | ||
error | ||
); | ||
return NextResponse.redirect( | ||
`${requestUrl.origin}/login/failed?err=AuthApiError` | ||
); | ||
} else { | ||
console.error("[login] [session] [500] Something wrong: ", error); | ||
return NextResponse.redirect( | ||
`${requestUrl.origin}/login/failed?err=500` | ||
); | ||
} | ||
} | ||
} | ||
|
||
// URL to redirect to after sign in process completes | ||
return NextResponse.redirect(requestUrl.origin) | ||
} | ||
return NextResponse.redirect(new URL(next, req.url)); | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
"use client"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
import { Input } from "@/components/ui/input"; | ||
import { useToast } from "@/components/ui/use-toast"; | ||
import { Database } from "@/types/supabase"; | ||
import { createClientComponentClient } from "@supabase/auth-helpers-nextjs"; | ||
import disposableDomains from "disposable-email-domains"; | ||
import { useState } from "react"; | ||
import { SubmitHandler, useForm } from "react-hook-form"; | ||
import { AiOutlineGoogle } from "react-icons/ai"; | ||
import { WaitingForMagicLink } from "./WaitingForMagicLink"; | ||
|
||
type Inputs = { | ||
email: string; | ||
}; | ||
|
||
export const Login = ({ | ||
host, | ||
searchParams, | ||
}: { | ||
host: string | null; | ||
searchParams?: { [key: string]: string | string[] | undefined }; | ||
}) => { | ||
const supabase = createClientComponentClient<Database>(); | ||
const [isSubmitting, setIsSubmitting] = useState(false); | ||
const [isMagicLinkSent, setIsMagicLinkSent] = useState(false); | ||
const { toast } = useToast(); | ||
|
||
const { | ||
register, | ||
handleSubmit, | ||
formState: { errors, isSubmitted }, | ||
} = useForm<Inputs>(); | ||
|
||
const onSubmit: SubmitHandler<Inputs> = async (data) => { | ||
setIsSubmitting(true); | ||
try { | ||
await signInWithMagicLink(data.email); | ||
setTimeout(() => { | ||
setIsSubmitting(false); | ||
toast({ | ||
title: "Email sent", | ||
description: "Check your inbox for a magic link to sign in.", | ||
duration: 5000, | ||
}); | ||
setIsMagicLinkSent(true); | ||
}, 1000); | ||
} catch (error) { | ||
setIsSubmitting(false); | ||
toast({ | ||
title: "Something went wrong", | ||
variant: "destructive", | ||
description: | ||
"Please try again, if the problem persists, contact us at hello@tryleap.ai", | ||
duration: 5000, | ||
}); | ||
} | ||
}; | ||
|
||
let inviteToken = null; | ||
if (searchParams && "inviteToken" in searchParams) { | ||
inviteToken = searchParams["inviteToken"]; | ||
} | ||
|
||
const protocol = host?.includes("localhost") ? "http" : "https"; | ||
const redirectUrl = `${protocol}://${host}/auth/callback`; | ||
|
||
console.log({ redirectUrl }); | ||
|
||
const signInWithGoogle = async () => { | ||
const { data, error } = await supabase.auth.signInWithOAuth({ | ||
provider: "google", | ||
options: { | ||
redirectTo: redirectUrl, | ||
}, | ||
}); | ||
|
||
console.log(data, error); | ||
}; | ||
|
||
const signInWithMagicLink = async (email: string) => { | ||
const { error } = await supabase.auth.signInWithOtp({ | ||
email, | ||
options: { | ||
emailRedirectTo: redirectUrl, | ||
}, | ||
}); | ||
|
||
if (error) { | ||
console.log(`Error: ${error.message}`); | ||
} | ||
}; | ||
|
||
if (isMagicLinkSent) { | ||
return ( | ||
<WaitingForMagicLink toggleState={() => setIsMagicLinkSent(false)} /> | ||
); | ||
} | ||
|
||
return ( | ||
<> | ||
<div className="flex items-center justify-center p-8"> | ||
<div className="flex flex-col gap-4 bg-neutral-50 dark:bg-neutral-900 border border-neutral-200 p-4 rounded-xl max-w-sm w-full"> | ||
<h1 className="text-xl">Welcome</h1> | ||
<p className="text-xs opacity-60"> | ||
Sign in or create an account to get started. | ||
</p> | ||
<Button | ||
onClick={signInWithGoogle} | ||
variant={"outline"} | ||
className="font-semibold" | ||
> | ||
<AiOutlineGoogle size={20} /> | ||
Continue with Google | ||
</Button> | ||
<OR /> | ||
|
||
<form | ||
onSubmit={handleSubmit(onSubmit)} | ||
className="flex flex-col gap-2" | ||
> | ||
<div className="flex flex-col gap-4"> | ||
<div className="flex flex-col gap-2"> | ||
<Input | ||
type="email" | ||
placeholder="Email" | ||
{...register("email", { | ||
required: true, | ||
validate: { | ||
emailIsValid: (value: string) => | ||
/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(value) || | ||
"Please enter a valid email", | ||
emailDoesntHavePlus: (value: string) => | ||
/^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(value) || | ||
"Email addresses with a '+' are not allowed", | ||
emailIsntDisposable: (value: string) => | ||
!disposableDomains.includes(value.split("@")[1]) || | ||
"Please use a permanent email address", | ||
}, | ||
})} | ||
/> | ||
{isSubmitted && errors.email && ( | ||
<span className={"text-xs text-red-400"}> | ||
{errors.email?.message || "Email is required to sign in"} | ||
</span> | ||
)} | ||
</div> | ||
</div> | ||
|
||
<Button | ||
isLoading={isSubmitting} | ||
disabled={isSubmitting} | ||
variant="outline" | ||
className="w-full" | ||
type="submit" | ||
> | ||
Continue with Email | ||
</Button> | ||
</form> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export const OR = () => { | ||
return ( | ||
<div className="flex items-center my-1"> | ||
<div className="border-b flex-grow mr-2 opacity-50" /> | ||
<span className="text-sm opacity-50">OR</span> | ||
<div className="border-b flex-grow ml-2 opacity-50" /> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { Button } from "@/components/ui/button"; | ||
import { ArrowLeft } from "lucide-react"; | ||
|
||
export const WaitingForMagicLink = ({ | ||
toggleState, | ||
}: { | ||
toggleState: () => void; | ||
}) => { | ||
return ( | ||
<> | ||
<div className="flex items-center justify-center p-8"> | ||
<div className="flex flex-col gap-4 bg-neutral-50 dark:bg-neutral-900 border border-neutral-200 p-4 rounded-xl max-w-sm w-full"> | ||
<h1 className="text-xl">Check your email to continue</h1> | ||
<div className="flex flex-col gap-2"> | ||
<p className="text-sm"> | ||
We've emailed you a magic link to access your account. | ||
</p> | ||
<p className="text-xs opacity-60"> | ||
Hint: it might be in your spam folder. | ||
</p> | ||
</div> | ||
<div> | ||
<Button onClick={toggleState} variant="secondary" size="sm"> | ||
<ArrowLeft size={14} /> | ||
Go back | ||
</Button> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; |
Oops, something went wrong.