diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..a223d32 --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +SUPABASE_URL=supabase_url +SUPABASE_ANON_KEY=anon_key \ No newline at end of file diff --git a/.env.sample b/.env.sample deleted file mode 100644 index 5df4df0..0000000 --- a/.env.sample +++ /dev/null @@ -1,3 +0,0 @@ -PUBLIC_APPWRITE_ENDPOINT="https://example.com/v1" -PUBLIC_APPWRITE_PROJECT_ID="" -APPWRITE_KEY="" \ No newline at end of file diff --git a/public/appwrite-logo-dark.svg b/public/appwrite-logo-dark.svg deleted file mode 100644 index af9916d..0000000 --- a/public/appwrite-logo-dark.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/public/login-dark-mode.png b/public/login-dark-mode.png deleted file mode 100644 index 682b517..0000000 Binary files a/public/login-dark-mode.png and /dev/null differ diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro deleted file mode 100644 index 4fa864c..0000000 --- a/src/layouts/Layout.astro +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/layouts/SignInUp.astro b/src/layouts/SignInUp.astro deleted file mode 100644 index 0e481ee..0000000 --- a/src/layouts/SignInUp.astro +++ /dev/null @@ -1,155 +0,0 @@ ---- -// Properties -const {Title, Type} = Astro.props - -// Check if user is already logged in, redirect if so -const { user } = Astro.locals; -if (user) { - return Astro.redirect("/account"); -} ---- - - -
-
- -
-
-

{Title}

-
- { - ()=> { - if (Type === "SignUp") { - return - } else { - return null - } - } - } - - -
- { - ()=> { - if (Type === "SignIn") { - return

Don't have an account? Sign Up

- - } else if (Type === "SignUp") { - return

Already have an account? Sign In

- - } - } - } -
- -
- -
-
- - \ No newline at end of file diff --git a/src/library/supabase.ts b/src/library/supabase.ts new file mode 100644 index 0000000..ef765d0 --- /dev/null +++ b/src/library/supabase.ts @@ -0,0 +1,14 @@ +import { createClient } from "@supabase/supabase-js"; + +export const supabase = createClient( + import.meta.env.SUPABASE_URL, + import.meta.env.SUPABASE_ANON_KEY, + { + auth: { + flowType: "pkce", + autoRefreshToken: false, + detectSessionInUrl: false, + persistSession: true, + }, + }, +); diff --git a/src/middleware.ts b/src/middleware.ts deleted file mode 100644 index 0fdff14..0000000 --- a/src/middleware.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineMiddleware } from "astro:middleware"; -import { createSessionClient } from "./server/appwrite"; - -export const onRequest = defineMiddleware(async ({ request, locals }, next) => { - try { - const { account } = createSessionClient(request); - locals.user = await account.get(); - } catch {} - - return next(); -}); diff --git a/src/middleware/index.ts b/src/middleware/index.ts new file mode 100644 index 0000000..58c9e74 --- /dev/null +++ b/src/middleware/index.ts @@ -0,0 +1,55 @@ +import { defineMiddleware } from "astro:middleware" +import { supabase } from "../library/supabase" + +const protectedRoutes = ["/dashboard"] +const redirectRoutes = ["/signin", "/register"] + +export const onRequest = defineMiddleware( + async ({ locals, url, cookies, redirect }, next) => { + if (protectedRoutes.includes(url.pathname)) { + const accessToken = cookies.get("sb-access-token") + const refreshToken = cookies.get("sb-refresh-token") + + if (!accessToken || !refreshToken) { + return redirect("/signin") + } + + const { data, error } = await supabase.auth.setSession({ + refresh_token: refreshToken.value, + access_token: accessToken.value, + }) + + if (error) { + cookies.delete("sb-access-token", { + path: "/", + }) + cookies.delete("sb-refresh-token", { + path: "/", + }) + return redirect("/signin") + } + + locals.email = data.user?.email! + cookies.set("sb-access-token", data?.session?.access_token!, { + sameSite: "strict", + path: "/", + secure: true, + }) + cookies.set("sb-refresh-token", data?.session?.refresh_token!, { + sameSite: "strict", + path: "/", + secure: true, + }) + } + + if (redirectRoutes.includes(url.pathname)) { + const accessToken = cookies.get("sb-access-token") + const refreshToken = cookies.get("sb-refresh-token") + + if (accessToken && refreshToken) { + return redirect("/dashboard") + } + } + return next() + }, +) diff --git a/src/pages/api/an.ts b/src/pages/api/an.ts deleted file mode 100644 index cc22f94..0000000 --- a/src/pages/api/an.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { APIRoute } from "astro"; -import { createAdminClient, SESSION_COOKIE } from "../../server/appwrite"; - -export const GET: APIRoute = async ({ cookies, redirect, url }) => { - const { account } = createAdminClient(); - - cookies.set('anonymous', 'true') - const secret = url.searchParams.get("secret"); - - const session = await account.createAnonymousSession(secret); - if (!session.secret) { - throw new Error("Failed to create session from token"); - } - - cookies.set(SESSION_COOKIE, session.secret, { - sameSite: "strict", - expires: new Date(session.expire), - secure: true, - httpOnly: true, - path: "/", - }); - - return redirect("/account"); -}; diff --git a/src/pages/api/email/send-verification.ts b/src/pages/api/email/send-verification.ts deleted file mode 100644 index 0189dba..0000000 --- a/src/pages/api/email/send-verification.ts +++ /dev/null @@ -1,15 +0,0 @@ -// When given all roles to ID that is used, the system says -// the role "applications" is still a missing scope. -import type { APIRoute } from "astro"; -import { createAdminClient, SESSION_COOKIE } from "../../../server/appwrite"; - -export const GET: APIRoute = async ({ cookies, redirect, url }) => { - const { account } = createAdminClient(); - - const result = await account.createVerification( - 'http://localhost:4321/account/' - ); - - console.log(result); - return redirect("/account"); -}; diff --git a/src/pages/oauth.ts b/src/pages/oauth.ts deleted file mode 100644 index d21cf08..0000000 --- a/src/pages/oauth.ts +++ /dev/null @@ -1,40 +0,0 @@ -import type { APIRoute } from "astro"; -import { createAdminClient, SESSION_COOKIE } from "../server/appwrite"; - -export const POST: APIRoute = async ({ redirect, url }) => { - const { account } = createAdminClient(); - - const redirectUrl = await account.createOAuth2Token( - "discord", - `${url.origin}/oauth`, - `${url.origin}/signin` - ); - - return redirect(redirectUrl); -}; - -export const GET: APIRoute = async ({ cookies, redirect, url }) => { - const userId = url.searchParams.get("userId"); - const secret = url.searchParams.get("secret"); - - if (!userId || !secret) { - throw new Error("OAuth2 did not provide userId or secret"); - } - - const { account } = createAdminClient(); - - const session = await account.createSession(userId, secret); - if (!session || !session.secret) { - throw new Error("Failed to create session from token"); - } - - cookies.set(SESSION_COOKIE, session.secret, { - sameSite: "strict", - expires: new Date(session.expire), - secure: true, - httpOnly: true, - path: "/", - }); - - return redirect("/account"); -}; \ No newline at end of file diff --git a/src/pages/settings/update-username.astro b/src/pages/settings/update-username.astro deleted file mode 100644 index a1880de..0000000 --- a/src/pages/settings/update-username.astro +++ /dev/null @@ -1,34 +0,0 @@ ---- -import { Users } from "node-appwrite"; -import { createAdminClient } from "../../server/appwrite"; - -if (Astro.request.method === "POST") { - const data = await Astro.request.formData(); - const name = data.get("name") as string; - - const { account } = createAdminClient(); - - const promise = await account.updateName(name); - - promise.then(function (response) { - console.log(response); - }, function (error) { - console.log(error); - }); - - - return Astro.redirect("/account"); -} ---- - -
- - - -
\ No newline at end of file diff --git a/src/pages/signout.astro b/src/pages/signout.astro deleted file mode 100644 index 3ab2b47..0000000 --- a/src/pages/signout.astro +++ /dev/null @@ -1,6 +0,0 @@ ---- -Astro.cookies.delete('session-token') -Astro.cookies.delete('anonymous') ---- - - \ No newline at end of file diff --git a/src/pages/signup.astro b/src/pages/signup.astro deleted file mode 100644 index 344e663..0000000 --- a/src/pages/signup.astro +++ /dev/null @@ -1,43 +0,0 @@ ---- -import SignInUp from "../layouts/SignInUp.astro"; - -import { ID } from "node-appwrite"; -import { SESSION_COOKIE, createAdminClient } from "../server/appwrite"; - - - -if (Astro.request.method === "POST") { - const data = await Astro.request.formData(); - - const email = data.get("email") as string; - const password = data.get("password") as string; - const name = data.get("name") as string; - - const { account } = createAdminClient(); - - await account.create(ID.unique(), email, password, name); - const session = await account.createEmailPasswordSession(email, password); - const promise = account.createVerification("http://localhost:4321/verify"); - - promise.then( - function (response) { - console.log('VERI:' + response); - }, - function (error) { - console.log(error); - }, - ); - - Astro.cookies.set(SESSION_COOKIE, session.secret, { - path: "/", - expires: new Date(session.expire), - sameSite: "strict", - secure: true, - httpOnly: true, - }); - - return Astro.redirect("/account"); - } ---- - - \ No newline at end of file diff --git a/src/server/appwrite.ts b/src/server/appwrite.ts deleted file mode 100644 index 2f9385c..0000000 --- a/src/server/appwrite.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Client, Account } from "node-appwrite"; - -export const SESSION_COOKIE = "session-token"; - -export function createAdminClient() { - const client = new Client() - .setEndpoint(import.meta.env.PUBLIC_APPWRITE_ENDPOINT) - .setProject(import.meta.env.PUBLIC_APPWRITE_PROJECT_ID) - .setKey(import.meta.env.APPWRITE_KEY); - - return { - get account() { - return new Account(client); - }, - }; -} - -export function createSessionClient(request: Request) { - const client = new Client() - .setEndpoint(import.meta.env.PUBLIC_APPWRITE_ENDPOINT) - .setProject(import.meta.env.PUBLIC_APPWRITE_PROJECT_ID); - - const cookies = parseCookies(request.headers.get("cookie") ?? ""); - const session = cookies.get(SESSION_COOKIE); - if (!session) { - throw new Error("No session"); - } - - client.setSession(session); - - return { - get account() { - return new Account(client); - }, - }; -} - -function parseCookies(cookies: string): Map { - const map = new Map(); - for (const cookie of cookies.split(";")) { - const [name, value] = cookie.split("="); - map.set(name.trim(), value ?? null); - } - return map; -}