-
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.
Merge pull request #89 from XionWCFM/cursor
๏ฟฝfix: ์ปดํ์ผ ์๋ฌ๋ก ์ธํ ๋น๋ ์คํจ
- Loading branch information
Showing
44 changed files
with
2,381 additions
and
295 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 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 |
---|---|---|
@@ -1,4 +1,4 @@ | ||
name: Pull Request Labeler | ||
name: Labeler | ||
|
||
on: pull_request_target | ||
|
||
|
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,34 +1,29 @@ | ||
name: Pr Size Labeler | ||
name: PR Size Labeler | ||
|
||
on: [pull_request] | ||
on: | ||
pull_request: | ||
types: [opened, synchronize] | ||
|
||
jobs: | ||
labeler: | ||
size-label: | ||
permissions: | ||
pull-requests: write | ||
contents: read | ||
issues: write | ||
pull-requests: write | ||
runs-on: ubuntu-latest | ||
name: Label the PR size | ||
steps: | ||
- uses: codelytv/pr-size-labeler@v1 | ||
- name: Assign PR Size Label | ||
uses: pascalgn/[email protected] | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
xs_label: 'size/xs' | ||
xs_max_size: '10' | ||
s_label: 'size/s' | ||
s_max_size: '100' | ||
m_label: 'size/m' | ||
m_max_size: '500' | ||
l_label: 'size/l' | ||
l_max_size: '1000' | ||
xl_label: 'size/xl' | ||
fail_if_xl: 'false' | ||
message_if_xl: > | ||
This PR exceeds the recommended size of 1000 lines. | ||
Please make sure you are NOT addressing multiple issues with one PR. | ||
Note this PR might be rejected due to its size. | ||
github_api_url: "https://api.github.com" | ||
files_to_ignore: | | ||
sizes: | | ||
{ | ||
"0": "size/XS", | ||
"10": "size/S", | ||
"30": "size/M", | ||
"100": "size/L", | ||
"500": "size/XL", | ||
"1000": "size/XXL" | ||
} | ||
ignore: | | ||
pnpm-lock.yaml | ||
package-lock.json | ||
yarn.lock |
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 |
---|---|---|
|
@@ -34,3 +34,8 @@ yarn-error.log* | |
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts | ||
|
||
# Million Lint | ||
.million | ||
|
||
certificates |
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,26 @@ | ||
"use client"; | ||
|
||
import { MdxEditor } from "@repo/mdx/editor"; | ||
import { Debounce } from "@xionwcfm/react"; | ||
import { Flex, Stack } from "@xionwcfm/xds"; | ||
import dynamic from "next/dynamic"; | ||
import { useState } from "react"; | ||
|
||
const MdxViewer = dynamic(() => import("@repo/mdx").then((mod) => mod.MdxViewer), { ssr: false }); | ||
|
||
export default function Page() { | ||
const [markdown, setMarkdown] = useState(""); | ||
|
||
return ( | ||
<Flex className="p-32" w={"screen"} h={"screen"} gap={"16"}> | ||
<Stack className="w-full"> | ||
<MdxEditor content={markdown} onChange={(value) => setMarkdown(value)} /> | ||
</Stack> | ||
<Stack className="w-full border rounded-sm px-16"> | ||
<Debounce value={markdown} delay={2500}> | ||
{({ debounced }) => <MdxViewer source={debounced} />} | ||
</Debounce> | ||
</Stack> | ||
</Flex> | ||
); | ||
} |
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,78 @@ | ||
import { type GoogleClaim, google } from "@repo/auth/google"; | ||
import { generateJwt } from "@repo/auth/jwt"; | ||
import { createServerSupabaseAdminClient } from "@repo/database/server"; | ||
import { env } from "@repo/env"; | ||
import { decodeIdToken } from "arctic"; | ||
import { cookies } from "next/headers"; | ||
import { type NextRequest, NextResponse } from "next/server"; | ||
import { z } from "zod"; | ||
|
||
export async function GET(req: NextRequest) { | ||
const { searchParams } = new URL(req.url); | ||
const { success: codeSuccess, data: code } = schema.safeParse(searchParams.get("code")); | ||
const { success: stateSuccess, data: state } = schema.safeParse(searchParams.get("state")); | ||
|
||
if (!(codeSuccess && stateSuccess)) { | ||
return NextResponse.redirect(`${env.NEXT_PUBLIC_BASE_URL}/login?error=invalid_request`); | ||
} | ||
|
||
const storedState = req.cookies.get("google_oauth_state")?.value; | ||
const codeVerifier = req.cookies.get("google_code_verifier")?.value; | ||
|
||
if (state !== storedState || !codeVerifier) { | ||
return NextResponse.redirect(`${env.NEXT_PUBLIC_BASE_URL}/login?error=invalid_state`); | ||
} | ||
|
||
try { | ||
const tokens = await google.validateAuthorizationCode(code, codeVerifier); | ||
const idToken = tokens.idToken(); | ||
const { sub: googleId, email, name, picture } = decodeIdToken(idToken) as GoogleClaim; | ||
|
||
const cookie = await cookies(); | ||
const supabase = await createServerSupabaseAdminClient(cookie); | ||
|
||
const { error } = await supabase.from("users").upsert( | ||
[ | ||
{ | ||
google_id: googleId, | ||
gmail: email, | ||
name, | ||
picture: picture ?? null, | ||
}, | ||
], | ||
{ onConflict: "google_id" }, | ||
); | ||
|
||
if (error) { | ||
return NextResponse.redirect(`${env.NEXT_PUBLIC_BASE_URL}/login?error=authentication_failed`); | ||
} | ||
|
||
const { data: userData, error: fetchError } = await supabase | ||
.from("users") | ||
.select("google_id, role, name, gmail") | ||
.eq("google_id", googleId) | ||
.single(); | ||
|
||
if (fetchError) { | ||
return NextResponse.redirect(`${env.NEXT_PUBLIC_BASE_URL}/login?error=authentication_failed`); | ||
} | ||
const jwtToken = await generateJwt({ | ||
google_id: googleId, | ||
mail: email, | ||
name, | ||
role: userData?.role ?? "viewer", | ||
}); | ||
|
||
cookie.set("session_token", jwtToken, { | ||
httpOnly: true, | ||
secure: env.NODE_ENV === "production", | ||
sameSite: "lax", | ||
}); | ||
|
||
return NextResponse.redirect(`${env.NEXT_PUBLIC_BASE_URL}`); | ||
} catch (_error) { | ||
return NextResponse.redirect(`${env.NEXT_PUBLIC_BASE_URL}/login?error=authentication_failed`); | ||
} | ||
} | ||
|
||
const schema = z.string().min(1); |
Oops, something went wrong.