From 13c6b6cf8ac4cc8d2758720c325ee3fa33a2f659 Mon Sep 17 00:00:00 2001 From: wwwc Date: Tue, 4 Jun 2024 12:03:50 +0800 Subject: [PATCH] add supabase auth --- .env.example | 6 +++ .vscode/settings.json | 2 +- README.md | 4 ++ README_SUPABASE_AUTH.md | 60 +++++++++++++++++++++++++++ app/page.tsx | 89 ++++++++++++++++++++++++++++++++++++----- config/index.ts | 4 +- docker-compose.yml | 13 ++++++ package.json | 11 +++-- utils/supabaseClient.ts | 10 +++++ 9 files changed, 181 insertions(+), 18 deletions(-) create mode 100644 README_SUPABASE_AUTH.md create mode 100644 docker-compose.yml create mode 100644 utils/supabaseClient.ts diff --git a/.env.example b/.env.example index 49b936df..d42c7be3 100644 --- a/.env.example +++ b/.env.example @@ -4,3 +4,9 @@ NEXT_PUBLIC_APP_ID= NEXT_PUBLIC_APP_KEY= # API url prefix NEXT_PUBLIC_API_URL= +# Enable Supabase auth +NEXT_PUBLIC_ENABLE_SUPABASE_AUTH=false +# Supabase url +NEXT_PUBLIC_SUPABASE_URL=http://localhost:8000 +# Superbase anon key +NEXT_PUBLIC_SUPABASE_ANON_KEY= \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 45d5fcfa..0a9763d6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,7 +4,7 @@ "prettier.enable": false, "editor.formatOnSave": true, "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, "[python]": { "editor.formatOnType": true diff --git a/README.md b/README.md index e50f82e3..756fd880 100644 --- a/README.md +++ b/README.md @@ -74,3 +74,7 @@ You can check out [the Next.js GitHub repository](https://github.com/vercel/next The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. + +## Using Supabase Auth (Email & Password Login) + +Details can be found in [README_SUPABASE_AUTH.md](./README_SUPABASE_AUTH.md) \ No newline at end of file diff --git a/README_SUPABASE_AUTH.md b/README_SUPABASE_AUTH.md new file mode 100644 index 00000000..14c3e29d --- /dev/null +++ b/README_SUPABASE_AUTH.md @@ -0,0 +1,60 @@ +# Conversation Web App with Supabase Auth Setup Guide + +This README will guide you through the necessary steps to create and configure a project using Supabase, then set up those configurations for your Next.js application. + +## Step 1: Config App +Create a file named `.env.local` in the current directory and copy the contents from `.env.example`. Setting the following content: +``` +# APP ID +NEXT_PUBLIC_APP_ID= +# APP API key +NEXT_PUBLIC_APP_KEY= +# APP URL +NEXT_PUBLIC_API_URL= +``` + +[`Developing with APIs guide`](https://docs.dify.ai/user-guide/launching-dify-apps/developing-with-apis) will walk you through how to retrieve the API URL, App ID, and App Key. + +## Step 2: Register and Create Supabase Project +- Visit [Supabase](https://supabase.com/dashboard/sign-in) +- Register and create an account, if you haven't already. +- Once you've signed in, click on '+ New Project'. +- Fill in the details such as project name and password under the "Project details" section. +- Click 'Create new project'. + +## Step 3: Create User in Supabase +- Go to the Authentication section in the left side panel on your Supabase project dashboard. +- Navigate to the 'Authentication' tab. +- Click the 'Add user' button and fill in the required user information. +- Click 'Create user' to create the user. + +## Step 4: Get Supabase URL and Anon Key +- On your project dashboard, click 'Connect'. +- Under the 'App Frameworks' tab, you'll find the URL and anon key listed. +- Take a note of the project URL and anon key, these will be used later. + +## Step 5: Copy the URL and Anon Key as ENV Variables +- Create a `.env.local` file in the root directory of your Next.js project. +- Paste the following environment variables in the `.env.local` file: + + ``` + # Enable Supabase auth + NEXT_PUBLIC_ENABLE_SUPABASE_AUTH=true + # Supabase url + NEXT_PUBLIC_SUPABASE_URL= + # Supabase anon key + NEXT_PUBLIC_SUPABASE_ANON_KEY= + ``` + +- Replace `` with your Supabase project URL. +- Replace `` with your Supabase anon key. + +## Step 6: Build and Start the Next App +- Open your terminal. +- Navigate to your project directory. +- Run `npm install` or `yarn install` to install all dependencies. +- To build the app, run `npm run build` or `yarn build`. +- To start the app, run `npm start` or `yarn start`. +- Your app should now be running on `http://localhost:3000`. + +You have completed the basic setup and configuration needed for connecting and running your Next.js application with Supabase. \ No newline at end of file diff --git a/app/page.tsx b/app/page.tsx index 832abaab..68ffd807 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,15 +1,82 @@ -import type { FC } from 'react' -import React from 'react' +'use client'; +import React, { FC, useEffect, useState } from 'react'; +import { Auth } from '@supabase/auth-ui-react'; +import { ThemeSupa } from '@supabase/auth-ui-shared'; +import type { IMainProps } from '@/app/components'; +import Main from '@/app/components'; +import { supabase } from '@/utils/supabaseClient'; -import type { IMainProps } from '@/app/components' -import Main from '@/app/components' +const App: FC = ({ params }: any) => { + const enableSupabaseAuth = process.env.NEXT_PUBLIC_ENABLE_SUPABASE_AUTH === 'true'; + // Initialize authenticated to true if the feature is disabled + const [authenticated, setAuthenticated] = useState(!enableSupabaseAuth); + + useEffect(() => { + if (enableSupabaseAuth) { + const checkSession = async () => { + const { data: { session } } = await supabase.auth.getSession(); + setAuthenticated(!!session); + }; + + checkSession(); + + const { data: { subscription } } = supabase.auth.onAuthStateChange((event, session) => { + setAuthenticated(!!session); + }); + + return () => { + subscription.unsubscribe(); + }; + } + }, [enableSupabaseAuth]); -const App: FC = ({ - params, -}: any) => { return ( -
- ) -} + <> + {authenticated ? ( +
+ ) : ( +
+
+ +
+
+ )} + + ); +}; + +export default React.memo(App); + +const styles = { + loginContainer: { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + height: '100vh', + backgroundColor: '#f5f5f5', + } as React.CSSProperties, -export default React.memo(App) + loginCard: { + maxWidth: '400px', + width: '100%', + padding: '2rem', + boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)', + borderRadius: '8px', + backgroundColor: 'white', + } as React.CSSProperties, +}; \ No newline at end of file diff --git a/config/index.ts b/config/index.ts index 1dc745b2..d664dcd8 100644 --- a/config/index.ts +++ b/config/index.ts @@ -7,11 +7,11 @@ export const APP_INFO: AppInfo = { description: '', copyright: '', privacy_policy: '', - default_language: 'zh-Hans', + default_language: 'en', } export const isShowPrompt = false -export const promptTemplate = 'I want you to act as a javascript console.' +export const promptTemplate = '' export const API_PREFIX = '/api' diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..84180cd8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' + +services: + next-app: + platform: linux/amd64 + container_name: next-app + image: node:19-bullseye-slim + volumes: + - .:/app + ports: + - 3000:3000 + command: | + npm start \ No newline at end of file diff --git a/package.json b/package.json index d0059b6d..5fafff6a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,9 @@ "@mdx-js/loader": "^2.3.0", "@mdx-js/react": "^2.3.0", "@monaco-editor/react": "^4.6.0", + "@supabase/auth-ui-react": "^0.4.7", + "@supabase/auth-ui-shared": "^0.1.8", + "@supabase/supabase-js": "^2.43.4", "@tailwindcss/line-clamp": "^0.4.2", "@types/node": "18.15.0", "@types/react": "18.0.28", @@ -39,10 +42,10 @@ "js-cookie": "^3.0.1", "katex": "^0.16.7", "negotiator": "^0.6.3", - "next": "^14.0.4", + "next": "^14.2.3", "rc-textarea": "^1.5.3", - "react": "18.2.0", - "react-dom": "18.2.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", "react-error-boundary": "^4.0.2", "react-headless-pagination": "^1.1.4", "react-i18next": "^12.2.0", @@ -81,4 +84,4 @@ "eslint --fix" ] } -} \ No newline at end of file +} diff --git a/utils/supabaseClient.ts b/utils/supabaseClient.ts new file mode 100644 index 00000000..944d60d9 --- /dev/null +++ b/utils/supabaseClient.ts @@ -0,0 +1,10 @@ +import { createClient } from '@supabase/supabase-js' + +const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL +const SUPABASE_ANON_KEY = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY + +if (!SUPABASE_URL || !SUPABASE_ANON_KEY) { + throw new Error("Missing Supabase URL or ANON KEY") +} + +export const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY) \ No newline at end of file