mirror of
https://github.com/PeterMaquiran/tvone.git
synced 2026-04-22 20:15:51 +00:00
login to next backend
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
||||
// Importe o componente que criámos (ajuste o caminho se necessário)
|
||||
import MultiAspectEditor from '../../components/MultiAspectEditor';
|
||||
import dynamic from "next/dynamic";
|
||||
import { keycloak } from '@/app/feature/auth/keycloak-config';
|
||||
// import { keycloak } from '@/app/feature/auth/keycloak-config';
|
||||
const Editor = dynamic(
|
||||
() => import("@tinymce/tinymce-react").then((mod) => mod.Editor),
|
||||
{ ssr: false }
|
||||
@@ -100,36 +100,43 @@ const CreateNewsPage = () => {
|
||||
};
|
||||
|
||||
// Avoid hydration mismatch by waiting for mount
|
||||
useEffect(() => {
|
||||
keycloak.init({
|
||||
onLoad: "check-sso",
|
||||
pkceMethod: "S256",
|
||||
}).then(async (authenticated) => {
|
||||
if (authenticated) {
|
||||
const token = keycloak.token!;
|
||||
localStorage.setItem("token", token);
|
||||
|
||||
const res = await fetch("http://localhost:3001/profile/", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
const profile = await res.json();
|
||||
|
||||
var keycloakData : {
|
||||
email: string,
|
||||
email_verified: boolean,
|
||||
name: string,
|
||||
picture: string,
|
||||
roles: string[]
|
||||
} = profile.keycloak
|
||||
// useEffect(() => {
|
||||
// keycloak.init({
|
||||
// onLoad: "check-sso",
|
||||
// pkceMethod: "S256",
|
||||
// }).then(async (authenticated) => {
|
||||
// if (authenticated) {
|
||||
// const token = keycloak.token!;
|
||||
// localStorage.setItem("token", token);
|
||||
|
||||
setUser(keycloakData);
|
||||
console.log("Profile:", keycloakData);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
// // 👉 send token to Next.js backend
|
||||
// fetch("/api/session", {
|
||||
// method: "POST",
|
||||
// body: JSON.stringify({ token }),
|
||||
// });
|
||||
|
||||
|
||||
// const res = await fetch("http://localhost:3001/profile/", {
|
||||
// headers: {
|
||||
// //Authorization: `Bearer ${token}`,
|
||||
// },
|
||||
// });
|
||||
|
||||
// const profile = await res.json();
|
||||
|
||||
// var keycloakData : {
|
||||
// email: string,
|
||||
// email_verified: boolean,
|
||||
// name: string,
|
||||
// picture: string,
|
||||
// roles: string[]
|
||||
// } = profile.keycloak
|
||||
|
||||
// setUser(keycloakData);
|
||||
// console.log("Profile:", keycloakData);
|
||||
// }
|
||||
// });
|
||||
// }, []);
|
||||
|
||||
return (
|
||||
<div className="flex h-screen bg-slate-100/50 text-slate-900 font-sans">
|
||||
|
||||
@@ -4,7 +4,7 @@ import React, { useState, useEffect } from "react";
|
||||
import { useGoogleLogin } from "@react-oauth/google";
|
||||
import { useTheme } from 'next-themes';
|
||||
import { Sun, Moon } from 'lucide-react'; // Optional: install lucide-react for clean icons
|
||||
import { keycloak } from '@/app/feature/auth/keycloak-config';
|
||||
//import { keycloak } from '@/app/feature/auth/keycloak-config';
|
||||
|
||||
interface GoogleAuthResponse {
|
||||
access_token: string;
|
||||
@@ -33,27 +33,6 @@ export default function AppleStyleAuth() {
|
||||
const { theme, setTheme } = useTheme();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
// Avoid hydration mismatch by waiting for mount
|
||||
useEffect(() => {
|
||||
keycloak.init({
|
||||
onLoad: "check-sso", // or "login-required"
|
||||
pkceMethod: "S256",
|
||||
}).then((authenticated) => {
|
||||
if (authenticated) {
|
||||
localStorage.setItem("token", keycloak.token!);
|
||||
console.log("Logged in", keycloak.token);
|
||||
localStorage.setItem("token", keycloak.token as string);
|
||||
|
||||
fetch("http://localhost:3001/profile/", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${localStorage.getItem("token")}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
const handleExchange = async (googleResponse: GoogleAuthResponse): Promise<void> => {
|
||||
try {
|
||||
const details: Record<string, string> = {
|
||||
@@ -190,11 +169,7 @@ export default function AppleStyleAuth() {
|
||||
|
||||
{/* 4. BOTÃO GOOGLE */}
|
||||
<button
|
||||
onClick={() =>
|
||||
keycloak.login({
|
||||
redirectUri: `${window.location.origin}/create-news`,
|
||||
})
|
||||
}
|
||||
onClick={() => (window.location.href = "/api/auth/login")}
|
||||
className="group flex w-full items-center justify-center gap-3 rounded-2xl border border-neutral-200 bg-white px-6 py-3.5 transition-all hover:bg-neutral-50 active:scale-[0.98] dark:border-neutral-800 dark:bg-transparent dark:hover:bg-neutral-900"
|
||||
>
|
||||
<svg className="h-5 w-5" viewBox="0 0 24 24">
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function GET(req: Request) {
|
||||
const url = new URL(req.url);
|
||||
const code = url.searchParams.get("code");
|
||||
|
||||
// exchange code for token (Keycloak token endpoint)
|
||||
const tokenRes = await fetch("https://keycloak.petermaquiran.xyz/realms/tvone/protocol/openid-connect/token", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: new URLSearchParams({
|
||||
client_id: "tvone-web",
|
||||
client_secret: "7jQUciQCCf2WRFRe170UANKzGKVWFIkY",
|
||||
grant_type: "authorization_code",
|
||||
code: code!,
|
||||
redirect_uri: "http://localhost:3000/api/auth/callback",
|
||||
}),
|
||||
});
|
||||
|
||||
const text = await tokenRes.text();
|
||||
var data = JSON.parse(text);
|
||||
|
||||
const res = NextResponse.redirect("http://localhost:3000/dashboard");
|
||||
|
||||
res.cookies.set("access_token", data.access_token, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
path: "/",
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export async function GET() {
|
||||
const redirect = encodeURIComponent(
|
||||
"http://localhost:3000/api/auth/callback"
|
||||
);
|
||||
|
||||
const keycloakUrl =
|
||||
`https://keycloak.petermaquiran.xyz/realms/tvone/protocol/openid-connect/auth` +
|
||||
`?client_id=tvone-web` +
|
||||
`&response_type=code` +
|
||||
`&scope=openid` +
|
||||
`&redirect_uri=${redirect}`;
|
||||
|
||||
return Response.redirect(keycloakUrl);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
export async function GET() {
|
||||
const redirect = encodeURIComponent(
|
||||
"http://localhost:3000/api/auth/callback"
|
||||
);
|
||||
|
||||
const keycloakUrl =
|
||||
`https://keycloak.petermaquiran.xyz/auth/realms/tvone/protocol/openid-connect/auth` +
|
||||
`?client_id=tvone-web` +
|
||||
`&response_type=code` +
|
||||
`&scope=openid` +
|
||||
`&redirect_uri=${redirect}`;
|
||||
|
||||
return Response.redirect(keycloakUrl);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
const { token } = await req.json();
|
||||
|
||||
const res = NextResponse.json({ ok: true });
|
||||
|
||||
res.cookies.set("auth_token", token, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
path: "/",
|
||||
});
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1,29 +1,29 @@
|
||||
import Keycloak from "keycloak-js";
|
||||
// import Keycloak from "keycloak-js";
|
||||
|
||||
/**
|
||||
* KEYCLOAK CONFIGURATION
|
||||
* Logic: Environment variable validation and OIDC configuration.
|
||||
*/
|
||||
// /**
|
||||
// * KEYCLOAK CONFIGURATION
|
||||
// * Logic: Environment variable validation and OIDC configuration.
|
||||
// */
|
||||
|
||||
export const keycloakConfig = {
|
||||
clientId: process.env.KEYCLOAK_CLIENT_ID!,
|
||||
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!,
|
||||
issuer: `${process.env.KEYCLOAK_ISSUER_URL}/realms/${process.env.KEYCLOAK_REALM}`,
|
||||
// export const keycloakConfig = {
|
||||
// clientId: process.env.KEYCLOAK_CLIENT_ID!,
|
||||
// clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!,
|
||||
// issuer: `${process.env.KEYCLOAK_ISSUER_URL}/realms/${process.env.KEYCLOAK_REALM}`,
|
||||
|
||||
// Scopes needed for OIDC and profile access
|
||||
scope: 'openid profile email',
|
||||
// // Scopes needed for OIDC and profile access
|
||||
// scope: 'openid profile email',
|
||||
|
||||
// Endpoint for global logout
|
||||
endSessionEndpoint: `${process.env.KEYCLOAK_ISSUER_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/logout`,
|
||||
};
|
||||
// // Endpoint for global logout
|
||||
// endSessionEndpoint: `${process.env.KEYCLOAK_ISSUER_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/logout`,
|
||||
// };
|
||||
|
||||
// Simple check to ensure environment variables are present
|
||||
if (!process.env.KEYCLOAK_CLIENT_ID || !process.env.KEYCLOAK_ISSUER_URL) {
|
||||
console.warn("Auth Warning: Keycloak environment variables are missing.");
|
||||
}
|
||||
// // Simple check to ensure environment variables are present
|
||||
// if (!process.env.KEYCLOAK_CLIENT_ID || !process.env.KEYCLOAK_ISSUER_URL) {
|
||||
// console.warn("Auth Warning: Keycloak environment variables are missing.");
|
||||
// }
|
||||
|
||||
export const keycloak = new Keycloak({
|
||||
url: "https://keycloak.petermaquiran.xyz",
|
||||
realm: "tvone", // ✅ IMPORTANT
|
||||
clientId: "tvone-web", // must match Keycloak client
|
||||
});
|
||||
// export const keycloak = new Keycloak({
|
||||
// url: "https://keycloak.petermaquiran.xyz",
|
||||
// realm: "tvone", // ✅ IMPORTANT
|
||||
// clientId: "tvone-web", // must match Keycloak client
|
||||
// });
|
||||
Reference in New Issue
Block a user