Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move from next-auth to supabase-auth (On refactored code) #105

Open
wants to merge 24 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Follow the installation instructions in the [Getting Started](https://unsaged.co
- **Multi-User Support**: Easily switch between users and manage their respective conversations.
- **Cloud Sync**: Synchronize your conversations across different devices seamlessly with Supabase.
- **System Prompts**: Personalize your conversation context and the AI's personality with system prompts.
- **Message Templates**: Speed up message generation with support for variable templates.
- **Message Templates**: Speed up message generation with support for variable templates.

## 🤖 Supported AI Models

Expand Down
42 changes: 0 additions & 42 deletions apps/docs/docs/configuration/general-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,48 +48,6 @@ SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key

---

### SUPABASE_JWT_SECRET

#### Description

The JWT secret for your Supabase instance. This is a required environment variable.

#### Example

```sh
SUPABASE_JWT_SECRET=your_supabase_jwt_secret
```

---

### NEXTAUTH_SECRET

#### Description

The secret used to encrypt cookies. This is a required environment variable.

#### Example

```sh
NEXTAUTH_SECRET=your_nextauth_secret
```

---

### NEXTAUTH_URL

#### Description

The base url for your app. This is a required environment variable when running in production.

#### Example

```sh
NEXTAUTH_URL=https://yourdomain.com
```

---

### NEXT_PUBLIC_DEFAULT_MODEL

#### Description
Expand Down
32 changes: 4 additions & 28 deletions apps/docs/docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@ This will do the following:
- Enable Row Level Security for the tables required by unSAGED.
- Apply the Row Level Security policies required by unSAGED.

## Expose the `next_auth` schema

Expose the `next_auth` schema in the [API settings](https://app.supabase.com/project/_/settings/api) by adding `next_auth` to the "Exposed schemas" list.

More information [here](https://authjs.dev/reference/adapter/supabase#expose-the-nextauth-schema-in-supabase).

Then copy the output and save it for the next step.

## Switch to the `apps/unsaged` directory

Expand All @@ -42,28 +35,17 @@ cd apps/unsaged
The `.env.local` file is the main configuration file for unSAGED. It should be located in the `apps/unsaged` directory of the project.
Create the `apps/unsaged/.env.local` file to set your environment variables.

### Set Auth Secret

Create your secret with the following command:

```sh
openssl rand -base64 32
```

Set the `NEXTAUTH_SECRET` environment variable to the secret you just created.

```sh title="apps/unsaged/.env.local"
NEXTAUTH_SECRET=my_secret
```
## Supabase auth
Configure your auth provider in supabase including the allowed redirect URL. See [Auth.js Documentation](https://next-auth.js.org/configuration/providers#supabase-provider) for more information.

See [Auth.js Documentation](https://next-auth.js.org/configuration/options#nextauth_secret) for more information.
See https://supabase.com/dashboard/project/xxxxxxx/auth/url-configuration

### Set Supabase Variables

```sh title="apps/unsaged/.env.local"
NEXT_PUBLIC_SUPABASE_URL="https://xxxxxxxxxxxxxxxx.supabase.co"
NEXT_PUBLIC_SUPABASE_ANON_KEY=supabase_anon_key
SUPABASE_JWT_SECRET=supabase_jwt_secret
SUPABASE_SERVICE_ROLE_KEY=supabase_service_role_key
```

Expand Down Expand Up @@ -92,10 +74,4 @@ docker run --env-file=.env.local -p 127.0.0.1:3000:3000 --name unsaged unsaged

## Running in Production

To run in production, you will need to set the following environment variable.

See [Auth.js Documentation](https://next-auth.js.org/configuration/options#nextauth_url) for more information.

```sh title="apps/unsaged/.env.local"
NEXTAUTH_URL=https://yourdomain.com
```
Make sure the prod domain or vercel preview domain is added to the supabase auth provider and URL configuration
21 changes: 8 additions & 13 deletions apps/unsaged/.env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ NEXT_PUBLIC_DEFAULT_MODEL="gpt-3.5-turbo"
NEXT_PUBLIC_TITLE="unsaged"
NEXT_PUBLIC_DESCRIPTION="Open source chat kit engineered for seamless interaction with AI models"


#Model providers to enable. You should disable the ones that you are not using. //test
NEXT_PUBLIC_OPENAI_ENABLED=true
NEXT_PUBLIC_ANTHROPIC_ENABLED=true
NEXT_PUBLIC_GOOGLE_ENABLED=true
NEXT_PUBLIC_OLLAMA_ENABLED=true

# OpenAI
OPENAI_API_URL="https://api.openai.com/v1"
OPENAI_API_KEY=openai_key
Expand Down Expand Up @@ -52,19 +59,7 @@ PALM_API_KEY=palm_key
# NEXT_PUBLIC_DEFAULT_PALM_TOP_P=1.0
# NEXT_PUBLIC_DEFAULT_PALM_TOP_K=40

# NextAuth (Required)
NEXTAUTH_EMAIL_PATTERN=
NEXTAUTH_URL="http://localhost:3000"
# You can get secret with `openssl rand -base64 32`
NEXTAUTH_SECRET=nextauth_secret

# At least one provider is required
# Google Auth Provider
GOOGLE_CLIENT_ID="xxxxxxxxxxxxxxxxx.apps.googleusercontent.com"
GOOGLE_CLIENT_SECRET=google_client_secret

# Supabase (Required)
NEXT_PUBLIC_SUPABASE_URL="https://xxxxxxxxxxxxxxxx.supabase.co"
NEXT_PUBLIC_SUPABASE_ANON_KEY=supabase_anon_key
SUPABASE_JWT_SECRET=supabase_jwt_secret
SUPABASE_SERVICE_ROLE_KEY=supabase_service_role_key

44 changes: 0 additions & 44 deletions apps/unsaged/app/api/auth/[...nextauth]/route.ts

This file was deleted.

56 changes: 41 additions & 15 deletions apps/unsaged/app/api/models/route.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DEBUG_MODE } from '@/utils/app/const';
import { DEBUG_MODE,OPENAI_ENABLED,ANTHROPIC_ENABLED, GOOGLE_ENABLED, OLLAMA_ENABLED } from '@/utils/app/const';
import { printEnvVariables } from '@/utils/app/debug/env-vars';
import { getAvailableAnthropicModels } from '@/utils/server/ai_vendors/anthropic/models';
import { getAvailablePalm2Models } from '@/utils/server/ai_vendors/google/models';
Expand All @@ -10,10 +10,11 @@ import { AiModel } from '@/types/ai-models';
export const runtime = 'edge';

const handler = async (req: Request): Promise<Response> => {

try {
if (DEBUG_MODE) {
console.log('----------SERVER-SIDE ENVIRONMENT VARIABLES----------');
printEnvVariables();
// printEnvVariables();
}

const { openai_key, anthropic_key, palm_key } = (await req.json()) as {
Expand All @@ -23,29 +24,54 @@ const handler = async (req: Request): Promise<Response> => {
};

const models: AiModel[] = [];
const { error: openaiError, data: openaiModels } =
await getAvailableOpenAIModels(openai_key);
if (openaiError) {
console.error('Error getting OpenAI models');
} else {
models.push(...(openaiModels as AiModel[]));
}

const { data: anthropicModels } = await getAvailableAnthropicModels(
anthropic_key,
);
// Check if OpenAI provider is enabled
if (OPENAI_ENABLED === 'true') {
const response = await getAvailableOpenAIModels(openai_key);
let openaiModels;

if (response) {
// If response is not null, destructure the data.
openaiModels = response.data;
models.push(...(openaiModels as AiModel[]));
} else {
// Handle the null case appropriately.
openaiModels = null; // or set it to a default value like [] if that makes sense for your application.
}
}


// Check if Anthropic provider is enabled
if (ANTHROPIC_ENABLED === 'true') {
const { data: anthropicModels } = await getAvailableAnthropicModels(anthropic_key);
if (anthropicModels && anthropicModels.length > 0) { // Check if there are any models
models.push(...(anthropicModels as AiModel[]));
}
}

const { data: palm2Models } = await getAvailablePalm2Models(palm_key);
// Check if Google (Palm2) provider is enabled
if (GOOGLE_ENABLED === 'true') {
const { data: palm2Models } = await getAvailablePalm2Models(palm_key);
if (palm2Models && palm2Models.length > 0) { // Check if there are any models
models.push(...(palm2Models as AiModel[]));
}
}

const { data: ollamaModels } = await getAvailableOllamaModels();
// Check if Ollama provider is enabled
if (OLLAMA_ENABLED === 'true') {
const { data: ollamaModels } = await getAvailableOllamaModels();
if (ollamaModels && ollamaModels.length > 0) { // Check if there are any models
models.push(...(ollamaModels as AiModel[]));
}
}


return new Response(JSON.stringify(models), { status: 200 });
} catch (error) {
console.log('⭐⭐⭐⭐⭐⭐');
console.error(error);
return new Response('Error getting available models', { status: 500 });
const defaultResponse = { models: [] };
return new Response(JSON.stringify(defaultResponse), { status: 500 });
}
};

Expand Down
38 changes: 38 additions & 0 deletions apps/unsaged/app/auth/callback/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'
import { type CookieOptions, createBrowserClient } from '@supabase/ssr'

export async function GET(request: Request) {
const { searchParams, origin } = new URL(request.url)
const code = searchParams.get('code')
// if "next" is in param, use it as the redirect URL
const next = searchParams.get('next') ?? '/'

if (code) {
const cookieStore = cookies()
const supabase = createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value
},
set(name: string, value: string, options: CookieOptions) {
cookieStore.set({ name, value, ...options })
},
remove(name: string, options: CookieOptions) {
cookieStore.delete({ name, ...options })
},
},
}
)
const { error } = await supabase.auth.exchangeCodeForSession(code)
if (!error) {
return NextResponse.redirect(`${origin}${next}`)
}
}

// return the user to an error page with instructions
return NextResponse.redirect(`${origin}/auth/auth-code-error`)
}
32 changes: 32 additions & 0 deletions apps/unsaged/app/auth/signin/auth-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use client'
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs'
import { Database } from '@/types/supabase.types'
import { NEXT_PUBLIC_SITE_URL } from '@/utils/app/const';

export default function AuthForm() {
const supabase = createBrowserSupabaseClient<Database>()

return (
<Auth
supabaseClient={supabase}
view="magic_link"
appearance={{
theme: ThemeSupa,
variables: {
default: {
colors: {
brand: '#5b21b6',
brandAccent: '#7c3aed',
},
},
},
}}
theme="default"
showLinks={true}
providers={['google']}
redirectTo={`${NEXT_PUBLIC_SITE_URL}/auth/callback`} // Use the environment variable in the URL
/>
)
}
20 changes: 20 additions & 0 deletions apps/unsaged/app/auth/signin/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import AuthForm from './auth-form';

export default function Home() {
// Access the title from the environment variables
const title = process.env.NEXT_PUBLIC_TITLE || 'Default Title';

return (
<div className="min-h-screen flex items-center justify-center bg-white dark:bg-gray-900 dark:text-white">
<div className="bg-white dark:bg-gray-800 p-8 shadow-md rounded-lg w-96">
<h1 className="text-2xl font-bold mb-4">{title}</h1>
<p className="text-gray-600 dark:text-gray-300">
Please sign in to your account
</p>
<div className="mt-6">
<AuthForm />
</div>
</div>
</div>
);
}
Loading
Loading