Neah version calendar fix 3 debuger ???? ??????????
This commit is contained in:
parent
a1e910e866
commit
bc7231efa3
@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { SessionProvider } from "next-auth/react";
|
import { SessionProvider } from "next-auth/react";
|
||||||
|
import { authOptions } from "@/lib/auth";
|
||||||
|
|
||||||
interface ProvidersProps {
|
interface ProvidersProps {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
@ -8,7 +9,7 @@ interface ProvidersProps {
|
|||||||
|
|
||||||
export function Providers({ children }: ProvidersProps) {
|
export function Providers({ children }: ProvidersProps) {
|
||||||
return (
|
return (
|
||||||
<SessionProvider>
|
<SessionProvider session={null} refetchInterval={5 * 60} refetchOnWindowFocus={true}>
|
||||||
{children}
|
{children}
|
||||||
</SessionProvider>
|
</SessionProvider>
|
||||||
);
|
);
|
||||||
|
|||||||
87
lib/auth.ts
87
lib/auth.ts
@ -5,17 +5,38 @@ declare module 'next-auth' {
|
|||||||
interface User {
|
interface User {
|
||||||
id: string;
|
id: string;
|
||||||
email: string;
|
email: string;
|
||||||
name?: string;
|
name?: string | null;
|
||||||
role: string[];
|
role: string[];
|
||||||
}
|
}
|
||||||
interface Session {
|
interface Session {
|
||||||
user: User;
|
user: {
|
||||||
|
id: string;
|
||||||
|
email: string;
|
||||||
|
name?: string | null;
|
||||||
|
role: string[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
interface Profile {
|
interface Profile {
|
||||||
|
sub: string;
|
||||||
|
email?: string;
|
||||||
|
name?: string;
|
||||||
roles?: string[];
|
roles?: string[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module 'next-auth/jwt' {
|
||||||
|
interface JWT {
|
||||||
|
id: string;
|
||||||
|
email: string;
|
||||||
|
name?: string;
|
||||||
|
role: string[];
|
||||||
|
accessToken?: string;
|
||||||
|
refreshToken?: string;
|
||||||
|
accessTokenExpires?: number;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const authOptions: NextAuthOptions = {
|
export const authOptions: NextAuthOptions = {
|
||||||
providers: [
|
providers: [
|
||||||
KeycloakProvider({
|
KeycloakProvider({
|
||||||
@ -26,28 +47,76 @@ export const authOptions: NextAuthOptions = {
|
|||||||
],
|
],
|
||||||
session: {
|
session: {
|
||||||
strategy: 'jwt',
|
strategy: 'jwt',
|
||||||
|
maxAge: 30 * 24 * 60 * 60, // 30 days
|
||||||
},
|
},
|
||||||
pages: {
|
pages: {
|
||||||
signIn: '/login',
|
signIn: '/signin',
|
||||||
|
error: '/signin',
|
||||||
},
|
},
|
||||||
callbacks: {
|
callbacks: {
|
||||||
async jwt({ token, account, profile }) {
|
async jwt({ token, account, profile }) {
|
||||||
if (account && profile) {
|
if (account && profile) {
|
||||||
// Store the Keycloak user ID
|
|
||||||
token.id = profile.sub;
|
token.id = profile.sub;
|
||||||
token.email = profile.email || '';
|
token.email = profile.email || '';
|
||||||
token.name = profile.name;
|
token.name = profile.name;
|
||||||
token.role = profile.roles || ['user'];
|
token.role = profile.roles || ['user'];
|
||||||
|
token.accessToken = account.access_token;
|
||||||
|
token.refreshToken = account.refresh_token;
|
||||||
|
token.accessTokenExpires = account.expires_at! * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return previous token if not expired
|
||||||
|
if (Date.now() < (token.accessTokenExpires as number)) {
|
||||||
return token;
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token expired, try to refresh
|
||||||
|
try {
|
||||||
|
const response = await fetch(
|
||||||
|
`${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/token`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
body: new URLSearchParams({
|
||||||
|
grant_type: 'refresh_token',
|
||||||
|
client_id: process.env.KEYCLOAK_CLIENT_ID!,
|
||||||
|
client_secret: process.env.KEYCLOAK_CLIENT_SECRET!,
|
||||||
|
refresh_token: token.refreshToken as string,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const tokens = await response.json();
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('RefreshAccessTokenError');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...token,
|
||||||
|
accessToken: tokens.access_token,
|
||||||
|
refreshToken: tokens.refresh_token ?? token.refreshToken,
|
||||||
|
accessTokenExpires: Date.now() + tokens.expires_in * 1000,
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
...token,
|
||||||
|
error: 'RefreshAccessTokenError',
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
async session({ session, token }) {
|
async session({ session, token }) {
|
||||||
if (token) {
|
if (token.error) {
|
||||||
session.user.id = token.id as string;
|
throw new Error('RefreshAccessTokenError');
|
||||||
session.user.email = token.email as string;
|
|
||||||
session.user.name = token.name as string;
|
|
||||||
session.user.role = token.role as string[];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.user.id = token.id;
|
||||||
|
session.user.email = token.email;
|
||||||
|
session.user.name = token.name;
|
||||||
|
session.user.role = token.role;
|
||||||
|
|
||||||
return session;
|
return session;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user