-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
24 changed files
with
319 additions
and
519 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
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,30 +1,30 @@ | ||
import { auth } from "@vivat/auth"; | ||
// import { auth } from "@vivat/auth"; | ||
|
||
import { SignIn, SignOut } from "~/components/auth"; | ||
// import { SignIn, SignOut } from "~/components/auth"; | ||
|
||
export async function AuthShowcase() { | ||
const session = await auth(); | ||
// export async function AuthShowcase() { | ||
// const session = await auth(); | ||
|
||
if (!session) { | ||
return ( | ||
<SignIn | ||
provider="discord" | ||
className="rounded-full bg-white/10 px-10 py-3 font-semibold no-underline transition hover:bg-white/20" | ||
> | ||
Sign in with Discord | ||
</SignIn> | ||
); | ||
} | ||
// if (!session) { | ||
// return ( | ||
// <SignIn | ||
// provider="discord" | ||
// className="rounded-full bg-white/10 px-10 py-3 font-semibold no-underline transition hover:bg-white/20" | ||
// > | ||
// Sign in with Discord | ||
// </SignIn> | ||
// ); | ||
// } | ||
|
||
return ( | ||
<div className="flex flex-col items-center justify-center gap-4"> | ||
<p className="text-center text-2xl text-white"> | ||
{session && <span>Logged in as {session.user.name}</span>} | ||
</p> | ||
// return ( | ||
// <div className="flex flex-col items-center justify-center gap-4"> | ||
// <p className="text-center text-2xl text-white"> | ||
// {session && <span>Logged in as {session.user.name}</span>} | ||
// </p> | ||
|
||
<SignOut className="rounded-full bg-white/10 px-10 py-3 font-semibold no-underline transition hover:bg-white/20"> | ||
Sign out | ||
</SignOut> | ||
</div> | ||
); | ||
} | ||
// <SignOut className="rounded-full bg-white/10 px-10 py-3 font-semibold no-underline transition hover:bg-white/20"> | ||
// Sign out | ||
// </SignOut> | ||
// </div> | ||
// ); | ||
// } |
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,100 @@ | ||
import { headers } from "next/headers"; | ||
import type { User } from "@clerk/nextjs/api"; | ||
import { Webhook } from "svix"; | ||
|
||
import { db, eq } from "@vivat/db"; | ||
import { users } from "@vivat/db/schema/user"; | ||
|
||
type UnwantedKeys = | ||
| "emailAddresses" | ||
| "firstName" | ||
| "lastName" | ||
| "primaryEmailAddressId" | ||
| "primaryPhoneNumberId" | ||
| "phoneNumbers"; | ||
|
||
interface UserInterface extends Omit<User, UnwantedKeys> { | ||
email_addresses: { | ||
email_address: string; | ||
id: string; | ||
}[]; | ||
primary_email_address_id: string; | ||
first_name: string; | ||
last_name: string; | ||
primary_phone_number_id: string; | ||
phone_numbers: { | ||
phone_number: string; | ||
id: string; | ||
}[]; | ||
image_url: string; | ||
} | ||
|
||
const webhookSecret: string = process.env.WEBHOOK_SECRET ?? ""; | ||
|
||
export async function POST(req: Request) { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment | ||
const payload = await req.json(); | ||
const payloadString = JSON.stringify(payload); | ||
const headerPayload = headers(); | ||
const svixId = headerPayload.get("svix-id"); | ||
const svixIdTimeStamp = headerPayload.get("svix-timestamp"); | ||
const svixSignature = headerPayload.get("svix-signature"); | ||
if (!svixId || !svixIdTimeStamp || !svixSignature) { | ||
console.log("svixId", svixId); | ||
console.log("svixIdTimeStamp", svixIdTimeStamp); | ||
console.log("svixSignature", svixSignature); | ||
return new Response("Error occured", { | ||
status: 400, | ||
}); | ||
} | ||
const svixHeaders = { | ||
"svix-id": svixId, | ||
"svix-timestamp": svixIdTimeStamp, | ||
"svix-signature": svixSignature, | ||
}; | ||
const wh = new Webhook(webhookSecret); | ||
let evt: Event | null = null; | ||
try { | ||
evt = wh.verify(payloadString, svixHeaders) as Event; | ||
} catch (_) { | ||
console.log("error"); | ||
return new Response("Error occured", { | ||
status: 400, | ||
}); | ||
} | ||
const { id } = evt.data; | ||
// Handle the webhook | ||
const eventType: EventType = evt.type; | ||
if (eventType === "user.created" || eventType === "user.updated") { | ||
const { email_addresses, primary_email_address_id } = evt.data; | ||
const emailObject = email_addresses?.find((email) => { | ||
return email.id === primary_email_address_id; | ||
}); | ||
if (!emailObject) { | ||
return new Response("Error locating user", { | ||
status: 400, | ||
}); | ||
} | ||
await db.insert(users).values({ | ||
id, | ||
email: emailObject.email_address, | ||
name: evt.data.first_name + " " + evt.data.last_name, | ||
imageUrl: evt.data.image_url, | ||
}); | ||
} | ||
if (eventType === "user.deleted") { | ||
await db.delete(users).where(eq(users.id, id)); | ||
} | ||
console.log(`User ${id} was ${eventType}`); | ||
return new Response("", { | ||
status: 201, | ||
}); | ||
} | ||
|
||
interface Event { | ||
data: UserInterface; | ||
object: "event"; | ||
type: EventType; | ||
} | ||
|
||
type EventType = "user.created" | "user.updated" | "user.deleted"; |
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,25 +1,25 @@ | ||
import type { ComponentProps } from "react"; | ||
// import type { ComponentProps } from "react"; | ||
|
||
import type { OAuthProviders } from "@vivat/auth"; | ||
import { CSRF_experimental } from "@vivat/auth"; | ||
// import type { OAuthProviders } from "@vivat/auth"; | ||
// import { CSRF_experimental } from "@vivat/auth"; | ||
|
||
export function SignIn({ | ||
provider, | ||
...props | ||
}: { provider: OAuthProviders } & ComponentProps<"button">) { | ||
return ( | ||
<form action={`/api/auth/signin/${provider}`} method="post"> | ||
<button {...props} /> | ||
<CSRF_experimental /> | ||
</form> | ||
); | ||
} | ||
// export function SignIn({ | ||
// provider, | ||
// ...props | ||
// }: { provider: OAuthProviders } & ComponentProps<"button">) { | ||
// return ( | ||
// <form action={`/api/auth/signin/${provider}`} method="post"> | ||
// <button {...props} /> | ||
// <CSRF_experimental /> | ||
// </form> | ||
// ); | ||
// } | ||
|
||
export function SignOut(props: ComponentProps<"button">) { | ||
return ( | ||
<form action="/api/auth/signout" method="post"> | ||
<button {...props} /> | ||
<CSRF_experimental /> | ||
</form> | ||
); | ||
} | ||
// export function SignOut(props: ComponentProps<"button">) { | ||
// return ( | ||
// <form action="/api/auth/signout" method="post"> | ||
// <button {...props} /> | ||
// <CSRF_experimental /> | ||
// </form> | ||
// ); | ||
// } |
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 |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { authMiddleware } from "@clerk/nextjs"; | ||
|
||
export default authMiddleware({ | ||
publicRoutes: ["/api/webhook"], | ||
}); | ||
|
||
export const config = { | ||
matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"], | ||
}; |
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 |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { getAuth } from "@clerk/nextjs/server"; | ||
import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; | ||
|
||
import { appRouter, createInnerTRPCContext } from "@vivat/api"; | ||
import type { NextRequest } from "next/server"; | ||
|
||
export const runtime = "edge"; | ||
|
||
/** | ||
* Configure basic CORS headers | ||
* You should extend this to match your needs | ||
*/ | ||
function setCorsHeaders(res: Response) { | ||
res.headers.set("Access-Control-Allow-Origin", "*"); | ||
res.headers.set("Access-Control-Request-Method", "*"); | ||
res.headers.set("Access-Control-Allow-Methods", "OPTIONS, GET, POST"); | ||
res.headers.set("Access-Control-Allow-Headers", "*"); | ||
} | ||
|
||
export function OPTIONS() { | ||
const response = new Response(null, { | ||
status: 204, | ||
}); | ||
setCorsHeaders(response); | ||
return response; | ||
} | ||
|
||
const handler = async (req: NextRequest) => { | ||
const auth = getAuth(req); | ||
const response = await fetchRequestHandler({ | ||
endpoint: "/api/trpc", | ||
router: appRouter, | ||
req, | ||
createContext: () => createInnerTRPCContext({ auth }), | ||
onError({ error, path }) { | ||
console.error(`>>> tRPC Error on '${path}'`, error); | ||
}, | ||
}); | ||
|
||
setCorsHeaders(response); | ||
return response; | ||
}; | ||
|
||
export { handler as GET, handler as POST }; |
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
Oops, something went wrong.