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

add dynamic navbar dependding on user login session #97

Merged
merged 16 commits into from
Oct 5, 2024
Merged
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
1 change: 0 additions & 1 deletion blotztask-ui/.env.production
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
NEXT_PUBLIC_API_BASE_URL=https://wapp-blotztaskapp.azurewebsites.net
NEXT_PUBLIC_API_BASE_URL_WITH_API=https://wapp-blotztaskapp.azurewebsites.net/api
nets7snipper marked this conversation as resolved.
Show resolved Hide resolved

3 changes: 3 additions & 0 deletions blotztask-ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# vscode
.vscode
8 changes: 0 additions & 8 deletions blotztask-ui/.vscode/settings.json

This file was deleted.

503 changes: 503 additions & 0 deletions blotztask-ui/public/assets/images/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
165 changes: 81 additions & 84 deletions blotztask-ui/src/app/api/auth/[...nextauth]/options.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { cookies } from "next/headers";
import { NextAuthOptions } from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import { cookies } from 'next/headers';

interface Credentials {
email: string;
Expand All @@ -15,97 +15,94 @@ interface LoginApiResponse {
}

export const authOptions: NextAuthOptions = {
// Configure one or more authentication providers
providers: [
CredentialsProvider({
// The name to display on the sign in form (e.g. "Sign in with...")
name: "Credentials",
// `credentials` is used to generate a form on the sign in page.
// You can specify which fields should be submitted, by adding keys to the `credentials` object.
// e.g. domain, username, password, 2FA token, etc.
// You can pass any HTML attribute to the <input> tag through the object.
credentials: {
email: { label: "Email", type: "text", placeholder: "your email" },
password: { label: "Password", type: "password" }
},
async authorize(credentials: Credentials) {

const { email, password } = credentials;
// console.log(email, password,req);

try {
//TODO : Remove reject unauthorized set to false
if (process.env.NODE_ENV !== 'production') {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
}
//TODO :Also fix the fetch url for login in prod
const response = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/login/`, {
// Configure one or more authentication providers
providers: [
CredentialsProvider({
// The name to display on the sign in form (e.g. "Sign in with...")
name: 'Credentials',
// `credentials` is used to generate a form on the sign in page.
// You can specify which fields should be submitted, by adding keys to the `credentials` object.
// e.g. domain, username, password, 2FA token, etc.
// You can pass any HTML attribute to the <input> tag through the object.
credentials: {
email: { label: 'Email', type: 'text', placeholder: 'your email' },
password: { label: 'Password', type: 'password' },
},

async authorize(credentials: Credentials) {
const { email, password } = credentials;

try {
//TODO : Remove reject unauthorized set to false
if (process.env.NODE_ENV !== 'production') {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
}
//TODO :Also fix the fetch url for login in prod
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/login/`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
},
body: JSON.stringify({ email, password })
});

if (!response.ok) {
console.error('Failed to authenticate:', response);
return null;
body: JSON.stringify({ email, password }),
}

const data: LoginApiResponse = await response.json();
);

cookies().set('authToken', data.accessToken, {
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict'
});

if (data.accessToken) {
return {
id: email || 'placeholder-id',
email: email,
accessToken: data.accessToken, // Include the access token here
refreshToken: data.refreshToken,
expiresIn: data.expiresIn,
};
} else {
console.error('Access token not found in response');
return null;
}
} catch (error) {
console.error('Unhandled error:', error);
if (!response.ok) {
console.error('Failed to authenticate:', response);
return null;
}

}
})
],
secret: process.env.NEXTAUTH_SECRET,
callbacks: {
async signIn({ user, account }) {
if (user?.access_token) {
account.access_token = user?.access_token as string

const data: LoginApiResponse = await response.json();

cookies().set('authToken', data.accessToken, {
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
});

if (data.accessToken) {
return {
id: email || 'placeholder-id',
email: email,
accessToken: data.accessToken, // Include the access token here
refreshToken: data.refreshToken,
expiresIn: data.expiresIn,
};
} else {
console.error('Access token not found in response');
return null;
}
} catch (error) {
console.error('Unhandled error:', error);
return null;
}
if (user?.refresh_token) {
account.refresh_token = user?.refresh_token as string
}

return true
},
async jwt({ token, session }) {
console.log('jwt callback', token, session);
return token;
},
async session({ session, token, user }) {
console.log('session callback', session, token, user);


return session
}),
],
secret: process.env.NEXTAUTH_SECRET,
callbacks: {
async signIn({ user, account }) {
if (user?.access_token) {
account.access_token = user?.access_token as string;
}
if (user?.refresh_token) {
account.refresh_token = user?.refresh_token as string;
}

return true;
},
session: {
strategy: "jwt"
async jwt({ token, session }) {
console.log('jwt callback', token, session);
return token;
},
async session({ session, token, user }) {
console.log('session callback', session, token, user);

return session;
},

}
},
session: {
strategy: 'jwt',
},
};
9 changes: 4 additions & 5 deletions blotztask-ui/src/app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import NextAuth from "next-auth"
import { authOptions } from "./options"
import NextAuth from 'next-auth';
import { authOptions } from './options';


const handler = NextAuth(authOptions)
export { handler as GET, handler as POST }
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
24 changes: 10 additions & 14 deletions blotztask-ui/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@

import { cn } from '@/lib/utils';
import type { Metadata } from 'next';
import { ThemeProvider } from 'next-themes';
import { Inter as FontSans } from 'next/font/google';
import '../styles/globals.css';
import { cn } from '@/lib/utils';
import { ThemeProvider } from 'next-themes';
import SessionProvider from './provider';
import { getServerSession } from 'next-auth';
import { authOptions } from './api/auth/[...nextauth]/options';
import { MainNav } from './navbar/main-nav';
import Provider from './provider';

const fontSans = FontSans({
subsets: ['latin'],
Expand All @@ -19,14 +16,11 @@ export const metadata: Metadata = {
description: 'Efficiently organize and track users tasks',
};

export default async function RootLayout({
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {

const session = await getServerSession(authOptions);

return (
<html lang="en">
<body
Expand All @@ -35,18 +29,20 @@ export default async function RootLayout({
fontSans.variable
)}
>
<SessionProvider session={session}>
<Provider>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
disableTransitionOnChange
>
<MainNav/>
<MainNav />
{/* <Navbar /> TODO: Implement navbar to navigate between pages*/}
<section className="container mx-auto px-12 py-4">{children}</section>
<section className="container mx-auto px-12 py-4">
{children}
</section>
</ThemeProvider>
</SessionProvider>
</Provider>
</body>
</html>
);
Expand Down
Loading
Loading