Spaces:
Build error
Build error
V.0.2.1 (#25)
Browse files* Fixed 'Nonetype' is not subscriptable error
* Fixed not getting secure next-auth cookies
* Updated search to comply with document set selection
* Updated run.py to exit after CREATE_VECTOR_STORE
* Updated token limit for memory
* Bugfix in checking for wrong value types
* Better error handling
- backend/backend/app/api/routers/chat.py +1 -1
- backend/backend/app/api/routers/query.py +7 -3
- backend/backend/app/api/routers/search.py +6 -5
- backend/backend/app/utils/auth.py +13 -7
- backend/backend/app/utils/index.py +1 -1
- backend/backend/run.py +3 -3
- frontend/app/api/status/route.ts +25 -14
- frontend/app/components/header.tsx +2 -2
- frontend/app/components/query-section.tsx +11 -4
- frontend/app/components/search-section.tsx +1 -1
- frontend/app/components/ui/search/search-results.tsx +5 -6
- frontend/app/components/ui/search/useSearch.tsx +3 -3
- frontend/auth.ts +5 -3
- frontend/middleware.ts +1 -1
backend/backend/app/api/routers/chat.py
CHANGED
@@ -110,7 +110,7 @@ async def chat(
|
|
110 |
|
111 |
memory = ChatMemoryBuffer.from_defaults(
|
112 |
chat_history=messages,
|
113 |
-
token_limit=
|
114 |
)
|
115 |
|
116 |
logger.info(f"Memory: {memory.get()}")
|
|
|
110 |
|
111 |
memory = ChatMemoryBuffer.from_defaults(
|
112 |
chat_history=messages,
|
113 |
+
token_limit=4096,
|
114 |
)
|
115 |
|
116 |
logger.info(f"Memory: {memory.get()}")
|
backend/backend/app/api/routers/query.py
CHANGED
@@ -4,7 +4,6 @@ from typing import List
|
|
4 |
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
5 |
from fastapi.responses import StreamingResponse
|
6 |
from fastapi.websockets import WebSocketDisconnect
|
7 |
-
from llama_index import VectorStoreIndex
|
8 |
from llama_index.llms.types import MessageRole
|
9 |
from pydantic import BaseModel
|
10 |
|
@@ -28,6 +27,7 @@ class _Message(BaseModel):
|
|
28 |
|
29 |
class _ChatData(BaseModel):
|
30 |
messages: List[_Message]
|
|
|
31 |
|
32 |
|
33 |
@r.post("")
|
@@ -36,8 +36,13 @@ async def query(
|
|
36 |
# Note: To support clients sending a JSON object using content-type "text/plain",
|
37 |
# we need to use Depends(json_to_model(_ChatData)) here
|
38 |
data: _ChatData = Depends(json_to_model(_ChatData)),
|
39 |
-
index: VectorStoreIndex = Depends(get_index),
|
40 |
):
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
# check preconditions and get last message which is query
|
42 |
if len(data.messages) == 0:
|
43 |
raise HTTPException(
|
@@ -50,7 +55,6 @@ async def query(
|
|
50 |
status_code=status.HTTP_400_BAD_REQUEST,
|
51 |
detail="Last message must be from user",
|
52 |
)
|
53 |
-
logger = logging.getLogger("uvicorn")
|
54 |
logger.info(f"Query: {lastMessage}")
|
55 |
|
56 |
# Query index
|
|
|
4 |
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
5 |
from fastapi.responses import StreamingResponse
|
6 |
from fastapi.websockets import WebSocketDisconnect
|
|
|
7 |
from llama_index.llms.types import MessageRole
|
8 |
from pydantic import BaseModel
|
9 |
|
|
|
27 |
|
28 |
class _ChatData(BaseModel):
|
29 |
messages: List[_Message]
|
30 |
+
document: str
|
31 |
|
32 |
|
33 |
@r.post("")
|
|
|
36 |
# Note: To support clients sending a JSON object using content-type "text/plain",
|
37 |
# we need to use Depends(json_to_model(_ChatData)) here
|
38 |
data: _ChatData = Depends(json_to_model(_ChatData)),
|
|
|
39 |
):
|
40 |
+
logger = logging.getLogger("uvicorn")
|
41 |
+
# get the document set selected from the request body
|
42 |
+
document_set = data.document
|
43 |
+
logger.info(f"Document Set: {document_set}")
|
44 |
+
# get the index for the selected document set
|
45 |
+
index = get_index(collection_name=document_set)
|
46 |
# check preconditions and get last message which is query
|
47 |
if len(data.messages) == 0:
|
48 |
raise HTTPException(
|
|
|
55 |
status_code=status.HTTP_400_BAD_REQUEST,
|
56 |
detail="Last message must be from user",
|
57 |
)
|
|
|
58 |
logger.info(f"Query: {lastMessage}")
|
59 |
|
60 |
# Query index
|
backend/backend/app/api/routers/search.py
CHANGED
@@ -2,7 +2,6 @@ import logging
|
|
2 |
import re
|
3 |
|
4 |
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
5 |
-
from llama_index import VectorStoreIndex
|
6 |
from llama_index.postprocessor import SimilarityPostprocessor
|
7 |
from llama_index.retrievers import VectorIndexRetriever
|
8 |
|
@@ -22,16 +21,18 @@ Instead it returns the relevant information from the index.
|
|
22 |
@r.get("")
|
23 |
async def search(
|
24 |
request: Request,
|
25 |
-
index: VectorStoreIndex = Depends(get_index),
|
26 |
query: str = None,
|
|
|
27 |
):
|
28 |
# query = request.query_params.get("query")
|
29 |
logger = logging.getLogger("uvicorn")
|
30 |
-
logger.info(f"Search: {query}")
|
31 |
-
|
|
|
|
|
32 |
raise HTTPException(
|
33 |
status_code=status.HTTP_400_BAD_REQUEST,
|
34 |
-
detail="No search info provided",
|
35 |
)
|
36 |
|
37 |
# configure retriever
|
|
|
2 |
import re
|
3 |
|
4 |
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
|
|
5 |
from llama_index.postprocessor import SimilarityPostprocessor
|
6 |
from llama_index.retrievers import VectorIndexRetriever
|
7 |
|
|
|
21 |
@r.get("")
|
22 |
async def search(
|
23 |
request: Request,
|
|
|
24 |
query: str = None,
|
25 |
+
docSelected: str = None,
|
26 |
):
|
27 |
# query = request.query_params.get("query")
|
28 |
logger = logging.getLogger("uvicorn")
|
29 |
+
logger.info(f"Document Set: {docSelected} | Search: {query}")
|
30 |
+
# get the index for the selected document set
|
31 |
+
index = get_index(collection_name=docSelected)
|
32 |
+
if query is None or docSelected is None:
|
33 |
raise HTTPException(
|
34 |
status_code=status.HTTP_400_BAD_REQUEST,
|
35 |
+
detail="No search info/document set provided",
|
36 |
)
|
37 |
|
38 |
# configure retriever
|
backend/backend/app/utils/auth.py
CHANGED
@@ -71,16 +71,18 @@ def get_user_from_JWT(token: str):
|
|
71 |
)
|
72 |
|
73 |
payload = decodeJWT(token)
|
74 |
-
user_id = payload["sub"]
|
75 |
|
76 |
-
if
|
|
|
77 |
# Try to get the user from the database using the user_id
|
78 |
response = supabase.table("users").select("*").eq("id", user_id).execute()
|
79 |
# print(response.data)
|
80 |
if len(response.data) == 0:
|
81 |
return False
|
82 |
-
|
83 |
-
|
|
|
|
|
84 |
|
85 |
|
86 |
async def validate_user(
|
@@ -89,13 +91,17 @@ async def validate_user(
|
|
89 |
):
|
90 |
try:
|
91 |
logger = logging.getLogger("uvicorn")
|
92 |
-
# logger.
|
93 |
if auth_token is not None or api_key is not None:
|
94 |
# If the access token is empty, use the 'X-API-Key' from the header
|
95 |
-
if auth_token is None:
|
96 |
# Access the 'X-API-Key' header directly
|
97 |
if BACKEND_API_KEY is None:
|
98 |
raise ValueError("Backend API key is not set in Backend Service!")
|
|
|
|
|
|
|
|
|
99 |
# If the 'X-API-Key' does not match the backend API key, raise an error
|
100 |
if api_key != BACKEND_API_KEY:
|
101 |
raise ValueError(
|
@@ -123,7 +129,7 @@ async def validate_user(
|
|
123 |
"Invalid token scheme. Please use the format 'Bearer [token]'"
|
124 |
)
|
125 |
# Verify the JWT token is valid
|
126 |
-
if verify_jwt(jwtoken=jwtoken)
|
127 |
return "Invalid token. Please provide a valid token."
|
128 |
# Check if the user exists in the database
|
129 |
if get_user_from_JWT(token=jwtoken):
|
|
|
71 |
)
|
72 |
|
73 |
payload = decodeJWT(token)
|
|
|
74 |
|
75 |
+
if payload is not None:
|
76 |
+
user_id = payload["sub"]
|
77 |
# Try to get the user from the database using the user_id
|
78 |
response = supabase.table("users").select("*").eq("id", user_id).execute()
|
79 |
# print(response.data)
|
80 |
if len(response.data) == 0:
|
81 |
return False
|
82 |
+
else:
|
83 |
+
return True
|
84 |
+
else:
|
85 |
+
return False
|
86 |
|
87 |
|
88 |
async def validate_user(
|
|
|
91 |
):
|
92 |
try:
|
93 |
logger = logging.getLogger("uvicorn")
|
94 |
+
# logger.info(f"Auth Token: {auth_token} | API Key: {api_key}")
|
95 |
if auth_token is not None or api_key is not None:
|
96 |
# If the access token is empty, use the 'X-API-Key' from the header
|
97 |
+
if auth_token is None or "null" in auth_token:
|
98 |
# Access the 'X-API-Key' header directly
|
99 |
if BACKEND_API_KEY is None:
|
100 |
raise ValueError("Backend API key is not set in Backend Service!")
|
101 |
+
if "null" in api_key:
|
102 |
+
raise ValueError(
|
103 |
+
"Invalid API key provided in the 'X-API-Key' header!"
|
104 |
+
)
|
105 |
# If the 'X-API-Key' does not match the backend API key, raise an error
|
106 |
if api_key != BACKEND_API_KEY:
|
107 |
raise ValueError(
|
|
|
129 |
"Invalid token scheme. Please use the format 'Bearer [token]'"
|
130 |
)
|
131 |
# Verify the JWT token is valid
|
132 |
+
if verify_jwt(jwtoken=jwtoken):
|
133 |
return "Invalid token. Please provide a valid token."
|
134 |
# Check if the user exists in the database
|
135 |
if get_user_from_JWT(token=jwtoken):
|
backend/backend/app/utils/index.py
CHANGED
@@ -230,7 +230,7 @@ def load_existing_index(collection_name="PSSCOC"):
|
|
230 |
logger.info(f"Indexing [{collection_name}] vector store...")
|
231 |
vector_store._collection.create_index()
|
232 |
logger.info(f"Finished indexing [{collection_name}] vector store")
|
233 |
-
logger.info(vector_store._collection.name)
|
234 |
index = VectorStoreIndex.from_vector_store(vector_store=vector_store)
|
235 |
logger.info(f"Finished loading [{collection_name}] index from Supabase")
|
236 |
logger.info(f"Index ID: {index.index_id}")
|
|
|
230 |
logger.info(f"Indexing [{collection_name}] vector store...")
|
231 |
vector_store._collection.create_index()
|
232 |
logger.info(f"Finished indexing [{collection_name}] vector store")
|
233 |
+
# logger.info(f"Collection Name: {vector_store._collection.name}")
|
234 |
index = VectorStoreIndex.from_vector_store(vector_store=vector_store)
|
235 |
logger.info(f"Finished loading [{collection_name}] index from Supabase")
|
236 |
logger.info(f"Index ID: {index.index_id}")
|
backend/backend/run.py
CHANGED
@@ -31,11 +31,11 @@ if __name__ == "__main__":
|
|
31 |
# Create the vector store
|
32 |
from backend.app.utils.index import create_index
|
33 |
|
34 |
-
logger.info("Creating
|
35 |
create_index()
|
36 |
-
logger.info("Vector
|
37 |
# Run the app
|
38 |
-
run_app()
|
39 |
else:
|
40 |
# Run the app
|
41 |
run_app()
|
|
|
31 |
# Create the vector store
|
32 |
from backend.app.utils.index import create_index
|
33 |
|
34 |
+
logger.info("Indexing Documents & Creating Vector Stores...")
|
35 |
create_index()
|
36 |
+
logger.info("Vector Stores created successfully! Exiting...")
|
37 |
# Run the app
|
38 |
+
# run_app()
|
39 |
else:
|
40 |
# Run the app
|
41 |
run_app()
|
frontend/app/api/status/route.ts
CHANGED
@@ -1,28 +1,39 @@
|
|
1 |
-
|
|
|
|
|
2 |
const healthcheck_api = process.env.NEXT_PUBLIC_HEALTHCHECK_API as string;
|
3 |
|
4 |
// Retrieve the session token from the request headers
|
5 |
let session = request.headers.get('Authorization');
|
6 |
|
7 |
-
console.log('Status API - headers:', request.headers);
|
8 |
|
9 |
// Public API key
|
10 |
let api_key = null;
|
11 |
|
12 |
// If no session, use the public API key
|
13 |
-
if (
|
|
|
14 |
api_key = process.env.BACKEND_API_KEY as string;
|
|
|
15 |
}
|
16 |
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
}
|
|
|
1 |
+
import { NextRequest, NextResponse } from "next/server";
|
2 |
+
|
3 |
+
export async function GET(request: NextRequest) {
|
4 |
const healthcheck_api = process.env.NEXT_PUBLIC_HEALTHCHECK_API as string;
|
5 |
|
6 |
// Retrieve the session token from the request headers
|
7 |
let session = request.headers.get('Authorization');
|
8 |
|
9 |
+
// console.log('Status API - headers:', request.headers);
|
10 |
|
11 |
// Public API key
|
12 |
let api_key = null;
|
13 |
|
14 |
// If no session, use the public API key
|
15 |
+
if (session === null || session === undefined || session.includes('undefined')) {
|
16 |
+
console.log('No session token found, using public API key');
|
17 |
api_key = process.env.BACKEND_API_KEY as string;
|
18 |
+
session = null; // Clear the session token
|
19 |
}
|
20 |
|
21 |
+
try {
|
22 |
+
const res = await fetch(healthcheck_api, {
|
23 |
+
signal: AbortSignal.timeout(5000), // Abort the request if it takes longer than 5 seconds
|
24 |
+
headers: {
|
25 |
+
'Content-Type': 'application/json',
|
26 |
+
'Authorization': session,
|
27 |
+
'X-API-Key': api_key,
|
28 |
+
} as any,
|
29 |
+
})
|
30 |
+
const data = await res.json()
|
31 |
+
if (!res.ok) {
|
32 |
+
throw new Error(data.detail || 'Unknown Error');
|
33 |
+
}
|
34 |
+
return NextResponse.json({ data })
|
35 |
+
} catch (error : any) {
|
36 |
+
console.error(`${error}`);
|
37 |
+
return NextResponse.json({ error: error.message }, { status: 500 })
|
38 |
+
}
|
39 |
}
|
frontend/app/components/header.tsx
CHANGED
@@ -53,7 +53,7 @@ export default function Header() {
|
|
53 |
const signinPage = "/sign-in?callbackUrl=" + encodedPath;
|
54 |
|
55 |
// Get user session for conditional rendering of user profile and logout buttons and for fetching the API status
|
56 |
-
const { data: session, status } = useSession()
|
57 |
// console.log('session:', session, 'status:', status);
|
58 |
const supabaseAccessToken = session?.supabaseAccessToken;
|
59 |
// Use SWR for API status fetching
|
@@ -94,7 +94,7 @@ export default function Header() {
|
|
94 |
|
95 |
useEffect(() => {
|
96 |
setMounted(true);
|
97 |
-
}, []);
|
98 |
|
99 |
const [isMobileMenuOpen, setMobileMenuOpen] = useState(false);
|
100 |
|
|
|
53 |
const signinPage = "/sign-in?callbackUrl=" + encodedPath;
|
54 |
|
55 |
// Get user session for conditional rendering of user profile and logout buttons and for fetching the API status
|
56 |
+
const { data: session, status } = useSession()
|
57 |
// console.log('session:', session, 'status:', status);
|
58 |
const supabaseAccessToken = session?.supabaseAccessToken;
|
59 |
// Use SWR for API status fetching
|
|
|
94 |
|
95 |
useEffect(() => {
|
96 |
setMounted(true);
|
97 |
+
}, [session]);
|
98 |
|
99 |
const [isMobileMenuOpen, setMobileMenuOpen] = useState(false);
|
100 |
|
frontend/app/components/query-section.tsx
CHANGED
@@ -4,9 +4,12 @@ import { useChat } from "ai/react";
|
|
4 |
import { ChatInput, ChatMessages } from "@/app/components/ui/chat";
|
5 |
import { AutofillQuestion } from "./ui/autofill-prompt";
|
6 |
import { useSession } from "next-auth/react";
|
|
|
7 |
|
8 |
export default function QuerySection() {
|
9 |
const { data: session } = useSession();
|
|
|
|
|
10 |
const {
|
11 |
messages,
|
12 |
input,
|
@@ -15,12 +18,16 @@ export default function QuerySection() {
|
|
15 |
handleInputChange,
|
16 |
reload,
|
17 |
stop,
|
18 |
-
} = useChat({
|
19 |
api: process.env.NEXT_PUBLIC_QUERY_API,
|
20 |
-
// Add the access token to the request headers
|
21 |
headers: {
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
24 |
});
|
25 |
|
26 |
return (
|
|
|
4 |
import { ChatInput, ChatMessages } from "@/app/components/ui/chat";
|
5 |
import { AutofillQuestion } from "./ui/autofill-prompt";
|
6 |
import { useSession } from "next-auth/react";
|
7 |
+
import { useState } from "react";
|
8 |
|
9 |
export default function QuerySection() {
|
10 |
const { data: session } = useSession();
|
11 |
+
const supabaseAccessToken = session?.supabaseAccessToken;
|
12 |
+
const [docSelected, setDocSelected] = useState<string>('');
|
13 |
const {
|
14 |
messages,
|
15 |
input,
|
|
|
18 |
handleInputChange,
|
19 |
reload,
|
20 |
stop,
|
21 |
+
} = useChat({
|
22 |
api: process.env.NEXT_PUBLIC_QUERY_API,
|
|
|
23 |
headers: {
|
24 |
+
// Add the access token to the request headers
|
25 |
+
'Authorization': `Bearer ${supabaseAccessToken}`,
|
26 |
+
},
|
27 |
+
body: {
|
28 |
+
// Add the selected document to the request body
|
29 |
+
document: docSelected,
|
30 |
+
},
|
31 |
});
|
32 |
|
33 |
return (
|
frontend/app/components/search-section.tsx
CHANGED
@@ -19,7 +19,7 @@ const SearchSection: React.FC = () => {
|
|
19 |
const handleSearchSubmit = (e: FormEvent) => {
|
20 |
e.preventDefault();
|
21 |
setSearchButtonPressed(true);
|
22 |
-
handleSearch(query);
|
23 |
};
|
24 |
|
25 |
return (
|
|
|
19 |
const handleSearchSubmit = (e: FormEvent) => {
|
20 |
e.preventDefault();
|
21 |
setSearchButtonPressed(true);
|
22 |
+
handleSearch(query, docSelected);
|
23 |
};
|
24 |
|
25 |
return (
|
frontend/app/components/ui/search/search-results.tsx
CHANGED
@@ -6,8 +6,8 @@ import 'react-toastify/dist/ReactToastify.css';
|
|
6 |
import { SearchHandler, SearchResult } from "@/app/components/ui/search/search.interface";
|
7 |
|
8 |
export default function SearchResults(
|
9 |
-
|
10 |
-
|
11 |
const [sortedResults, setSortedResults] = useState<SearchResult[]>([]);
|
12 |
const [expandedResult, setExpandedResult] = useState<number | null>(null);
|
13 |
|
@@ -17,11 +17,10 @@ export default function SearchResults(
|
|
17 |
// Reset sortedResults when query is empty
|
18 |
setSortedResults([]);
|
19 |
} else if (props.query.trim() !== "" && props.searchButtonPressed) {
|
20 |
-
// if results are empty
|
21 |
-
if (props.results.length === 0) {
|
22 |
setSortedResults([]);
|
23 |
-
}
|
24 |
-
else {
|
25 |
// Sort results by similarity score
|
26 |
const sorted = props.results.slice().sort((a, b) => b.similarity_score - a.similarity_score);
|
27 |
// Update sortedResults state
|
|
|
6 |
import { SearchHandler, SearchResult } from "@/app/components/ui/search/search.interface";
|
7 |
|
8 |
export default function SearchResults(
|
9 |
+
props: Pick<SearchHandler, "query" | "results" | "isLoading" | "searchButtonPressed">
|
10 |
+
) {
|
11 |
const [sortedResults, setSortedResults] = useState<SearchResult[]>([]);
|
12 |
const [expandedResult, setExpandedResult] = useState<number | null>(null);
|
13 |
|
|
|
17 |
// Reset sortedResults when query is empty
|
18 |
setSortedResults([]);
|
19 |
} else if (props.query.trim() !== "" && props.searchButtonPressed) {
|
20 |
+
// if results are empty or not an array
|
21 |
+
if (!Array.isArray(props.results) || props.results.length === 0) {
|
22 |
setSortedResults([]);
|
23 |
+
} else {
|
|
|
24 |
// Sort results by similarity score
|
25 |
const sorted = props.results.slice().sort((a, b) => b.similarity_score - a.similarity_score);
|
26 |
// Update sortedResults state
|
frontend/app/components/ui/search/useSearch.tsx
CHANGED
@@ -7,7 +7,7 @@ import { useSession } from 'next-auth/react';
|
|
7 |
interface UseSearchResult {
|
8 |
searchResults: SearchResult[];
|
9 |
isLoading: boolean;
|
10 |
-
handleSearch: (query: string) => Promise<void>;
|
11 |
}
|
12 |
|
13 |
const search_api = process.env.NEXT_PUBLIC_SEARCH_API;
|
@@ -20,7 +20,7 @@ const useSearch = (): UseSearchResult => {
|
|
20 |
// console.log('session:', session, 'status:', status);
|
21 |
const supabaseAccessToken = session?.supabaseAccessToken;
|
22 |
|
23 |
-
const handleSearch = async (query: string): Promise<void> => {
|
24 |
setIsSearchButtonPressed(isSearchButtonPressed);
|
25 |
setIsLoading(true);
|
26 |
|
@@ -40,7 +40,7 @@ const useSearch = (): UseSearchResult => {
|
|
40 |
setIsLoading(false);
|
41 |
return;
|
42 |
}
|
43 |
-
const response = await fetch(`${search_api}?query=${query}`, {
|
44 |
signal: AbortSignal.timeout(120000), // Abort the request if it takes longer than 120 seconds
|
45 |
// Add the access token to the request headers
|
46 |
headers: {
|
|
|
7 |
interface UseSearchResult {
|
8 |
searchResults: SearchResult[];
|
9 |
isLoading: boolean;
|
10 |
+
handleSearch: (query: string, docSelected: string) => Promise<void>;
|
11 |
}
|
12 |
|
13 |
const search_api = process.env.NEXT_PUBLIC_SEARCH_API;
|
|
|
20 |
// console.log('session:', session, 'status:', status);
|
21 |
const supabaseAccessToken = session?.supabaseAccessToken;
|
22 |
|
23 |
+
const handleSearch = async (query: string, docSelected: string): Promise<void> => {
|
24 |
setIsSearchButtonPressed(isSearchButtonPressed);
|
25 |
setIsLoading(true);
|
26 |
|
|
|
40 |
setIsLoading(false);
|
41 |
return;
|
42 |
}
|
43 |
+
const response = await fetch(`${search_api}?query=${query}&docSelected=${docSelected}`, {
|
44 |
signal: AbortSignal.timeout(120000), // Abort the request if it takes longer than 120 seconds
|
45 |
// Add the access token to the request headers
|
46 |
headers: {
|
frontend/auth.ts
CHANGED
@@ -124,11 +124,12 @@ export const config = {
|
|
124 |
token.accessToken = account.access_token
|
125 |
token.id = profile?.sub
|
126 |
}
|
127 |
-
return token
|
128 |
},
|
129 |
async session({ session, token, user }) {
|
130 |
// Send properties to the client, like an access_token from a provider.
|
131 |
const signingSecret = process.env.SUPABASE_JWT_SECRET
|
|
|
132 |
if (signingSecret) {
|
133 |
const payload = {
|
134 |
aud: "authenticated",
|
@@ -137,11 +138,12 @@ export const config = {
|
|
137 |
// email: user.email,
|
138 |
role: "authenticated",
|
139 |
}
|
140 |
-
session.supabaseAccessToken = jwt.sign(payload, signingSecret)
|
|
|
141 |
// session.jwt = token.jwt as string;
|
142 |
// session.id = token.id as string;
|
143 |
}
|
144 |
-
return session
|
145 |
},
|
146 |
|
147 |
}
|
|
|
124 |
token.accessToken = account.access_token
|
125 |
token.id = profile?.sub
|
126 |
}
|
127 |
+
return token;
|
128 |
},
|
129 |
async session({ session, token, user }) {
|
130 |
// Send properties to the client, like an access_token from a provider.
|
131 |
const signingSecret = process.env.SUPABASE_JWT_SECRET
|
132 |
+
// console.log('Signing Secret:', signingSecret);
|
133 |
if (signingSecret) {
|
134 |
const payload = {
|
135 |
aud: "authenticated",
|
|
|
138 |
// email: user.email,
|
139 |
role: "authenticated",
|
140 |
}
|
141 |
+
session.supabaseAccessToken = jwt.sign(payload, signingSecret) as string;
|
142 |
+
// console.log('New Session:', session);
|
143 |
// session.jwt = token.jwt as string;
|
144 |
// session.id = token.id as string;
|
145 |
}
|
146 |
+
return session;
|
147 |
},
|
148 |
|
149 |
}
|
frontend/middleware.ts
CHANGED
@@ -8,7 +8,7 @@ export const middleware = async (request: NextRequest) => {
|
|
8 |
// Add callbackUrl params to the signinPage URL
|
9 |
signinPage.searchParams.set('callbackUrl', pathname);
|
10 |
// Retrieve the session token from the request cookies
|
11 |
-
const session = request.cookies.get('next-auth.session-token');
|
12 |
|
13 |
if (session) {
|
14 |
// console.log('session:', session);
|
|
|
8 |
// Add callbackUrl params to the signinPage URL
|
9 |
signinPage.searchParams.set('callbackUrl', pathname);
|
10 |
// Retrieve the session token from the request cookies
|
11 |
+
const session = request.cookies.get('next-auth.session-token') || request.cookies.get('__Secure-next-auth.session-token');
|
12 |
|
13 |
if (session) {
|
14 |
// console.log('session:', session);
|