diff --git a/back/src/app/Http/Middleware/TrustProxies.php b/back/src/app/Http/Middleware/TrustProxies.php index 3391630..559dd2f 100755 --- a/back/src/app/Http/Middleware/TrustProxies.php +++ b/back/src/app/Http/Middleware/TrustProxies.php @@ -12,7 +12,7 @@ class TrustProxies extends Middleware * * @var array|string|null */ - protected $proxies; + protected $proxies = '*'; /** * The headers that should be used to detect proxies. diff --git a/back/src/config/cors.php b/back/src/config/cors.php index 3430618..fd32127 100755 --- a/back/src/config/cors.php +++ b/back/src/config/cors.php @@ -19,7 +19,7 @@ 'allowed_methods' => ['*'], - 'allowed_origins' => [env('FRONTEND_URL', 'http://localhost:5173')], + 'allowed_origins' => explode(',', env('FRONTEND_URL', 'http://localhost:5173')), 'allowed_origins_patterns' => [], diff --git a/back/src/config/session.php b/back/src/config/session.php index 16cc15a..b02b68d 100755 --- a/back/src/config/session.php +++ b/back/src/config/session.php @@ -155,7 +155,7 @@ | */ - 'domain' => env('SESSION_DOMAIN', 'localhost'), + 'domain' => env('SESSION_DOMAIN') === '' ? null : env('SESSION_DOMAIN', 'localhost'), /* |-------------------------------------------------------------------------- @@ -168,7 +168,7 @@ | */ - 'secure' => env('SESSION_SECURE_COOKIE'), + 'secure' => env('SESSION_SECURE_COOKIE', false), /* |-------------------------------------------------------------------------- diff --git a/front/src/components/Header.tsx b/front/src/components/Header.tsx index 53c9f0e..6a743b2 100644 --- a/front/src/components/Header.tsx +++ b/front/src/components/Header.tsx @@ -86,11 +86,11 @@ export default function Header() { async function handleLogout() { try { - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true, }); await axios.post( - `${import.meta.env.VITE_API_URL}/logout`, + `/logout`, {}, { headers: { diff --git a/front/src/context/UserContext.tsx b/front/src/context/UserContext.tsx index 1460257..90a2fd4 100644 --- a/front/src/context/UserContext.tsx +++ b/front/src/context/UserContext.tsx @@ -17,13 +17,13 @@ export function UserProvider({ children }: { children: React.ReactNode }) { const token = localStorage.getItem("auth_token"); if (token) { Promise.all([ - axios.get(`${import.meta.env.VITE_API_URL}/api/user`, { + axios.get(`/api/user`, { headers: { Authorization: `Bearer ${token}`, Accept: "application/json" } }), - axios.get(`${import.meta.env.VITE_API_URL}/api/user/roles`, { + axios.get(`/api/user/roles`, { headers: { Authorization: `Bearer ${token}`, Accept: "application/json" diff --git a/front/src/main.tsx b/front/src/main.tsx index 52aade6..d6067b9 100644 --- a/front/src/main.tsx +++ b/front/src/main.tsx @@ -8,7 +8,7 @@ import RealtimeNotifications from "./components/RealtimeNotifications.tsx"; import axios from "axios"; // Configure axios defaults for the app: base URL and send credentials (for Sanctum) -const API_URL = import.meta.env?.VITE_API_URL || "http://localhost:8000"; +const API_URL = import.meta.env?.VITE_API_URL || ""; axios.defaults.baseURL = API_URL; axios.defaults.withCredentials = true; diff --git a/front/src/pages/login/Login.tsx b/front/src/pages/login/Login.tsx index f588df0..6ad8771 100644 --- a/front/src/pages/login/Login.tsx +++ b/front/src/pages/login/Login.tsx @@ -47,13 +47,13 @@ export default function Login() { localStorage.setItem("auth_token", token); const [userRes, rolesRes] = await Promise.all([ - axios.get(`${import.meta.env.VITE_API_URL}/api/user`, { + axios.get(`/api/user`, { headers: { Authorization: `Bearer ${token}`, Accept: "application/json", }, }), - axios.get(`${import.meta.env.VITE_API_URL}/api/user/roles`, { + axios.get(`/api/user/roles`, { headers: { Authorization: `Bearer ${token}`, Accept: "application/json", diff --git a/front/src/pages/perfil/ProfileView.tsx b/front/src/pages/perfil/ProfileView.tsx index f5974dd..1bbf985 100644 --- a/front/src/pages/perfil/ProfileView.tsx +++ b/front/src/pages/perfil/ProfileView.tsx @@ -109,10 +109,9 @@ function ProfileHeader({ user, setUser, setNotification }: ProfileHeaderProps) { const userInitial = displayName.charAt(0).toUpperCase(); async function onSave() { - const token = localStorage.getItem("auth_token") || ""; try { setSaving(true); - const data = await updateName(name, token); + const data = await updateName(name); setUser({ ...user, name: data.name }); setEditing(false); setNotification({ type: "success", message: "Nome atualizado com sucesso." }); diff --git a/front/src/services/ActivitiesService.ts b/front/src/services/ActivitiesService.ts index cf34121..10b15cb 100644 --- a/front/src/services/ActivitiesService.ts +++ b/front/src/services/ActivitiesService.ts @@ -4,7 +4,7 @@ import { fakePageActivities } from "../mocks"; import axios from "axios"; import Cookies from "js-cookie"; -const API_URL = import.meta.env.VITE_API_URL; +const API_URL = ""; function getHeaders() { return { diff --git a/front/src/services/ChangePasswordService.ts b/front/src/services/ChangePasswordService.ts index ec5b8d7..ceb83aa 100644 --- a/front/src/services/ChangePasswordService.ts +++ b/front/src/services/ChangePasswordService.ts @@ -8,11 +8,11 @@ export async function changePassword({ newPasswordConfirmation }: ChangePasswordRequest): Promise { - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true }); - await axios.post(`${import.meta.env.VITE_API_URL}/api/user/change-password`, { + await axios.post(`/api/user/change-password`, { current_password: currentPassword, new_password: newPassword, new_password_confirmation: newPasswordConfirmation diff --git a/front/src/services/ClassesService.ts b/front/src/services/ClassesService.ts index 66efd46..d3e212d 100644 --- a/front/src/services/ClassesService.ts +++ b/front/src/services/ClassesService.ts @@ -8,7 +8,7 @@ import type { AddStudentToClassDTO, } from "@/types/classes"; -const API_URL = import.meta.env.VITE_API_URL || "http://localhost:8000/api"; +const API_URL = import.meta.env?.VITE_API_URL || ""; const api = axios.create({ baseURL: API_URL, @@ -39,7 +39,7 @@ function handleAuthError(error: unknown) { // Interceptor para adicionar token se necessário api.interceptors.request.use((config) => { - const token = localStorage.getItem("token"); + const token = localStorage.getItem("auth_token"); if (token) { config.headers.Authorization = `Bearer ${token}`; } @@ -49,7 +49,7 @@ api.interceptors.request.use((config) => { export const ClassesService = { // Listar todas as turmas getAllClasses: async (): Promise => { - const response = await api.get("api/turmas", { + const response = await api.get("/api/turmas", { headers:getAuthHeaders(), withCredentials:true }); @@ -58,7 +58,7 @@ export const ClassesService = { // Buscar turma por ID getClassById: async (id: number): Promise => { - const response = await api.get(`api/turmas/${id}`, { + const response = await api.get(`/api/turmas/${id}`, { headers:getAuthHeaders(), withCredentials:true }); @@ -67,7 +67,7 @@ export const ClassesService = { // Criar nova turma createClass: async (data: CreateClassDTO): Promise => { - const response = await api.post("api/turmas", data, { + const response = await api.post("/api/turmas", data, { headers:getAuthHeaders(), withCredentials:true }); @@ -76,7 +76,7 @@ export const ClassesService = { // Atualizar turma updateClass: async (id: number, data: UpdateClassDTO): Promise => { - const response = await api.put(`api/turmas/${id}`, data, { + const response = await api.put(`/api/turmas/${id}`, data, { headers:getAuthHeaders(), withCredentials:true }); @@ -85,7 +85,7 @@ export const ClassesService = { // Deletar turma deleteClass: async (id: number): Promise => { - await api.delete(`api/turmas/${id}`, { + await api.delete(`/api/turmas/${id}`, { headers:getAuthHeaders(), withCredentials:true }); @@ -93,7 +93,7 @@ export const ClassesService = { // Buscar turmas de um professor getClassesByTeacher: async (): Promise => { - const response = await api.get(`api/turmas`, { + const response = await api.get(`/api/turmas`, { headers:getAuthHeaders(), withCredentials:true }); @@ -102,7 +102,7 @@ export const ClassesService = { // Buscar turmas de um aluno getClassesByStudent: async (): Promise => { - const response = await api.get(`api/turmas`, { + const response = await api.get(`/api/turmas`, { headers:getAuthHeaders(), withCredentials:true }); @@ -112,7 +112,7 @@ export const ClassesService = { // Buscar alunos de uma turma getClassStudents: async (id: number): Promise => { try { - const response = await api.get(`api/turmas/${id}`, { + const response = await api.get(`/api/turmas/${id}`, { headers: getAuthHeaders(), withCredentials: true }); @@ -139,7 +139,7 @@ export const ClassesService = { // Adicionar aluno a uma turma addStudentToClass: async (classId: number, data: AddStudentToClassDTO): Promise => { try { - await api.post(`api/turmas/${classId}/vincular-aluno/${data.studentId}`, {}, { + await api.post(`/api/turmas/${classId}/vincular-aluno/${data.studentId}`, {}, { headers: getAuthHeaders(), withCredentials: true }); @@ -152,7 +152,7 @@ export const ClassesService = { // Remover aluno de uma turma removeStudentFromClass: async (classId: number, studentId: number): Promise => { try { - await api.delete(`api/turmas/${classId}/desvincular-aluno/${studentId}`, { + await api.delete(`/api/turmas/${classId}/desvincular-aluno/${studentId}`, { headers: getAuthHeaders(), withCredentials: true }); diff --git a/front/src/services/CoursesService.ts b/front/src/services/CoursesService.ts index 65b8bc3..fc1c50f 100644 --- a/front/src/services/CoursesService.ts +++ b/front/src/services/CoursesService.ts @@ -32,7 +32,7 @@ function handleAuthError(error: unknown) { */ export async function getAllCourses(): Promise { try { - const response = await axios.get(`${import.meta.env.VITE_API_URL}/api/cursos`, { + const response = await axios.get(`/api/cursos`, { headers: getAuthHeaders(), withCredentials: true, }); diff --git a/front/src/services/ForgotPasswordService.ts b/front/src/services/ForgotPasswordService.ts index d3a84ae..ac95bc3 100644 --- a/front/src/services/ForgotPasswordService.ts +++ b/front/src/services/ForgotPasswordService.ts @@ -2,11 +2,11 @@ import axios from "axios"; import Cookies from "js-cookie"; export async function sendForgotPasswordEmail(email: string): Promise { - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true }); - await axios.post(`${import.meta.env.VITE_API_URL}/api/forgot-password-temp`, { + await axios.post(`/api/forgot-password-temp`, { email }, { withCredentials: true, @@ -24,11 +24,11 @@ export async function resetPassword(data: { password: string; password_confirmation: string; }): Promise { - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true }); - await axios.post(`${import.meta.env.VITE_API_URL}/reset-password`, data, { + await axios.post(`/reset-password`, data, { withCredentials: true, headers: { 'Content-Type': 'application/json', diff --git a/front/src/services/JamSessionService.ts b/front/src/services/JamSessionService.ts index c75aff0..d9b7de1 100644 --- a/front/src/services/JamSessionService.ts +++ b/front/src/services/JamSessionService.ts @@ -2,7 +2,7 @@ import axios from "axios"; import Cookies from "js-cookie"; import type { JamSession, CreateJamSessionDTO, JamParticipant } from "@/types/jam"; -const API_URL = import.meta.env.VITE_API_URL || "http://localhost:8000/api"; +const API_URL = import.meta.env?.VITE_API_URL || ""; const WS_URL = import.meta.env.VITE_WS_URL || "ws://localhost:3002"; const api = axios.create({ @@ -24,7 +24,7 @@ function getAuthHeaders() { export const JamSessionService = { getByTurma: async (turmaId: number): Promise => { - const response = await api.get(`api/jam-sessions?turma_id=${turmaId}`, { + const response = await api.get(`/api/jam-sessions?turma_id=${turmaId}`, { headers: getAuthHeaders(), withCredentials: true, }); @@ -32,7 +32,7 @@ export const JamSessionService = { }, getById: async (id: number): Promise => { - const response = await api.get(`api/jam-sessions/${id}`, { + const response = await api.get(`/api/jam-sessions/${id}`, { headers: getAuthHeaders(), withCredentials: true, }); @@ -40,7 +40,7 @@ export const JamSessionService = { }, create: async (data: CreateJamSessionDTO): Promise => { - const response = await api.post("api/jam-sessions", data, { + const response = await api.post("/api/jam-sessions", data, { headers: getAuthHeaders(), withCredentials: true, }); @@ -48,7 +48,7 @@ export const JamSessionService = { }, start: async (id: number): Promise => { - const response = await api.post(`api/jam-sessions/${id}/start`, {}, { + const response = await api.post(`/api/jam-sessions/${id}/start`, {}, { headers: getAuthHeaders(), withCredentials: true, }); @@ -56,7 +56,7 @@ export const JamSessionService = { }, finish: async (id: number): Promise => { - const response = await api.post(`api/jam-sessions/${id}/finish`, {}, { + const response = await api.post(`/api/jam-sessions/${id}/finish`, {}, { headers: getAuthHeaders(), withCredentials: true, }); @@ -64,7 +64,7 @@ export const JamSessionService = { }, join: async (id: number): Promise => { - const response = await api.post(`api/jam-sessions/${id}/join`, {}, { + const response = await api.post(`/api/jam-sessions/${id}/join`, {}, { headers: getAuthHeaders(), withCredentials: true, }); @@ -72,7 +72,7 @@ export const JamSessionService = { }, getActiveForTurma: async (turmaId: number): Promise => { - const response = await api.get(`api/turmas/${turmaId}/jam-session/active`, { + const response = await api.get(`/api/turmas/${turmaId}/jam-session/active`, { headers: getAuthHeaders(), withCredentials: true, }); diff --git a/front/src/services/LoginService.ts b/front/src/services/LoginService.ts index 9940c5a..8e66714 100644 --- a/front/src/services/LoginService.ts +++ b/front/src/services/LoginService.ts @@ -4,12 +4,12 @@ import Cookies from "js-cookie"; export async function login({ email, password }: LoginRequest): Promise{ - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true }); - const res = await axios.post(`${import.meta.env.VITE_API_URL}/login`, { + const res = await axios.post(`/login`, { email, password }, { diff --git a/front/src/services/ProblemsServices.ts b/front/src/services/ProblemsServices.ts index 5dc01dc..dfe125f 100644 --- a/front/src/services/ProblemsServices.ts +++ b/front/src/services/ProblemsServices.ts @@ -1,8 +1,19 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import type { Problem } from "../types"; import axios from "axios"; +import Cookies from "js-cookie"; -const API_URL = (import.meta as any).env?.VITE_API_URL || "http://localhost:8000"; +const API_URL = (import.meta as any).env?.VITE_API_URL || ""; + +function getAuthHeaders() { + const token = localStorage.getItem("auth_token"); + return { + Authorization: `Bearer ${token}`, + Accept: "application/json", + "Content-Type": "application/json", + "X-XSRF-TOKEN": Cookies.get("XSRF-TOKEN") || "", + }; +} /** * Simula uma chamada de API para buscar um problema pelo id. @@ -12,14 +23,11 @@ const API_URL = (import.meta as any).env?.VITE_API_URL || "http://localhost:8000 export async function getProblemById(id: string): Promise { try { const response = await axios.get(`${API_URL}/api/problemas/${id}`, { - headers: { - Authorization: `Bearer ${localStorage.getItem("auth_token")}`, - 'Content-Type': 'application/json', - 'Accept': 'application/json', - }, + headers: getAuthHeaders(), + withCredentials: true, }); - const problema = response.data; + const problema = response.data.data || response.data; return { id: problema.id, title: problema.titulo, @@ -42,14 +50,11 @@ export async function getProblemById(id: string): Promise { export async function getAllProblems(): Promise { try { const response = await axios.get(`${API_URL}/api/problemas`, { - headers: { - Authorization: `Bearer ${localStorage.getItem("auth_token")}`, - 'Content-Type': 'application/json', - 'Accept': 'application/json', - }, + headers: getAuthHeaders(), + withCredentials: true, }); - const problemas = Array.isArray(response.data) ? response.data : response.data[0] || []; + const problemas = response.data.data || (Array.isArray(response.data) ? response.data : response.data[0] || []); return problemas.map((problema: any) => ({ id: problema.id, @@ -85,15 +90,16 @@ export async function createProblem(problemData: { }): Promise { try { + await axios.get(`${API_URL}/sanctum/csrf-cookie`, { + withCredentials: true, + }); + const response = await axios.post(`${API_URL}/api/problemas`, problemData, { - headers: { - Authorization: `Bearer ${localStorage.getItem("auth_token")}`, - 'Content-Type': 'application/json', - 'Accept': 'application/json', - }, + headers: getAuthHeaders(), + withCredentials: true, }); - const problema = response.data; + const problema = response.data.data || response.data; return { id: problema.id, title: problema.titulo, @@ -119,15 +125,16 @@ export async function updateProblem(id: number, problemData: { }>; }): Promise { try { + await axios.get(`${API_URL}/sanctum/csrf-cookie`, { + withCredentials: true, + }); + const response = await axios.put(`${API_URL}/api/problemas/${id}`, problemData, { - headers: { - Authorization: `Bearer ${localStorage.getItem("auth_token")}`, - 'Content-Type': 'application/json', - 'Accept': 'application/json', - }, + headers: getAuthHeaders(), + withCredentials: true, }); - const problema = response.data; + const problema = response.data.data || response.data; return { id: problema.id, title: problema.titulo, @@ -143,12 +150,13 @@ export async function updateProblem(id: number, problemData: { export async function deleteProblem(id: number): Promise { try { + await axios.get(`${API_URL}/sanctum/csrf-cookie`, { + withCredentials: true, + }); + await axios.delete(`${API_URL}/api/problemas/${id}`, { - headers: { - Authorization: `Bearer ${localStorage.getItem("auth_token")}`, - 'Content-Type': 'application/json', - 'Accept': 'application/json', - }, + headers: getAuthHeaders(), + withCredentials: true, }); return true; } catch (error) { diff --git a/front/src/services/ProfessorsService.ts b/front/src/services/ProfessorsService.ts index e74764c..e2dfc50 100644 --- a/front/src/services/ProfessorsService.ts +++ b/front/src/services/ProfessorsService.ts @@ -28,7 +28,7 @@ function handleAuthError(error: unknown) { */ export async function getAllProfessors(): Promise { try { - const response = await axios.get(`${import.meta.env.VITE_API_URL}/api/professores`, { + const response = await axios.get(`/api/professores`, { headers: getAuthHeaders(), withCredentials: true, }); @@ -48,7 +48,7 @@ export async function getAllProfessors(): Promise { */ export async function getProfessorById(id: number): Promise { try { - const response = await axios.get(`${import.meta.env.VITE_API_URL}/api/professores/${id}`, { + const response = await axios.get(`/api/professores/${id}`, { headers: getAuthHeaders(), withCredentials: true, }); @@ -68,12 +68,12 @@ export async function getProfessorById(id: number): Promise): Promise { try { // Obter CSRF token antes de criar - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true, }); const response = await axios.post( - `${import.meta.env.VITE_API_URL}/api/professores`, + `/api/professores`, professor, { headers: getAuthHeaders(), @@ -96,12 +96,12 @@ export async function createProfessor(professor: Omit): Promise export async function updateProfessor(id: number, professor: Partial): Promise { try { // Obter CSRF token antes de atualizar - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true, }); const response = await axios.put( - `${import.meta.env.VITE_API_URL}/api/professores/${id}`, + `/api/professores/${id}`, professor, { headers: getAuthHeaders(), @@ -123,11 +123,11 @@ export async function updateProfessor(id: number, professor: Partial) export async function deleteProfessor(id: number): Promise { try { // Obter CSRF token antes de deletar - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true, }); - await axios.delete(`${import.meta.env.VITE_API_URL}/api/professores/${id}`, { + await axios.delete(`/api/professores/${id}`, { headers: getAuthHeaders(), withCredentials: true, }); diff --git a/front/src/services/ProfileService.ts b/front/src/services/ProfileService.ts index bb39ecd..d76a6ba 100644 --- a/front/src/services/ProfileService.ts +++ b/front/src/services/ProfileService.ts @@ -1,14 +1,16 @@ import axios from "axios"; -export async function updateName(name: string, token: string) { +export async function updateName(name: string) { + const token = localStorage.getItem("auth_token"); const res = await axios.patch( - `${import.meta.env.VITE_API_URL}/api/user`, + `/api/user`, { name }, { headers: { Authorization: `Bearer ${token}`, Accept: "application/json", }, + withCredentials: true, } ); diff --git a/front/src/services/StudentsService.ts b/front/src/services/StudentsService.ts index 4611449..5fec97d 100644 --- a/front/src/services/StudentsService.ts +++ b/front/src/services/StudentsService.ts @@ -28,7 +28,7 @@ function handleAuthError(error: unknown) { */ export async function getAllStudents(): Promise { try { - const response = await axios.get(`${import.meta.env.VITE_API_URL}/api/alunos`, { + const response = await axios.get(`/api/alunos`, { headers: getAuthHeaders(), withCredentials: true, }); @@ -61,7 +61,7 @@ export async function getAllStudents(): Promise { */ export async function getStudentById(id: number): Promise { try { - const response = await axios.get(`${import.meta.env.VITE_API_URL}/api/alunos/${id}`, { + const response = await axios.get(`/api/alunos/${id}`, { headers: getAuthHeaders(), withCredentials: true, }); @@ -81,12 +81,12 @@ export async function getStudentById(id: number): Promise { export async function createStudent(student: Omit): Promise { try { // Obter CSRF token antes de criar - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true, }); const response = await axios.post( - `${import.meta.env.VITE_API_URL}/api/alunos`, + `/api/alunos`, student, { headers: getAuthHeaders(), @@ -109,12 +109,12 @@ export async function createStudent(student: Omit): Promise): Promise { try { // Obter CSRF token antes de atualizar - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true, }); const response = await axios.put( - `${import.meta.env.VITE_API_URL}/api/alunos/${id}`, + `/api/alunos/${id}`, student, { headers: getAuthHeaders(), @@ -136,11 +136,11 @@ export async function updateStudent(id: number, student: Partial): Prom export async function deleteStudent(id: number): Promise { try { // Obter CSRF token antes de deletar - await axios.get(`${import.meta.env.VITE_API_URL}/sanctum/csrf-cookie`, { + await axios.get(`/sanctum/csrf-cookie`, { withCredentials: true, }); - await axios.delete(`${import.meta.env.VITE_API_URL}/api/alunos/${id}`, { + await axios.delete(`/api/alunos/${id}`, { headers: getAuthHeaders(), withCredentials: true, }); diff --git a/front/src/services/SubmissionsService.ts b/front/src/services/SubmissionsService.ts index 195da35..b846caa 100644 --- a/front/src/services/SubmissionsService.ts +++ b/front/src/services/SubmissionsService.ts @@ -28,7 +28,7 @@ import { fakeSubmissions } from "../mocks"; import axios from "axios"; import Cookies from "js-cookie"; -const API_URL = (import.meta as any).env?.VITE_API_URL || "http://localhost:8000"; +const API_URL = (import.meta as any).env?.VITE_API_URL || ""; /** * Mapeia language_id do Judge0 para slug usado no frontend diff --git a/front/vite.config.ts b/front/vite.config.ts index c9652ef..300ba48 100644 --- a/front/vite.config.ts +++ b/front/vite.config.ts @@ -12,7 +12,25 @@ export default defineConfig(({ mode }) => ({ }, }, server: { - allowedHosts: ["ifcodes.cloud"], + allowedHosts: ["localhost", "127.0.0.1"], + proxy: { + '/api': { + target: 'http://backend_app:8000', + changeOrigin: true, + }, + '/sanctum': { + target: 'http://backend_app:8000', + changeOrigin: true, + }, + '/login': { + target: 'http://backend_app:8000', + changeOrigin: true, + }, + '/logout': { + target: 'http://backend_app:8000', + changeOrigin: true, + }, + }, watch: mode === "development" ? { usePolling: true } : undefined, }, define: { diff --git a/provision.sh b/provision.sh index 30ef6bf..6095cf9 100755 --- a/provision.sh +++ b/provision.sh @@ -56,28 +56,76 @@ if [ ! -f "back/src/.env" ] || [ ! -f "judge0.conf" ] || [ ! -f "front/.env" ]; read -p "Porta do Backend [8000]: " APP_PORT APP_PORT=${APP_PORT:-"8000"} + # Obtendo o IP da máquina na rede local (ignorando IPs de Docker default e loopback, e forçando IPv4) + if [ "$(uname)" = "Darwin" ]; then + DETECTED_IP=$(ipconfig getifaddr en0 2>/dev/null || ipconfig getifaddr en1 2>/dev/null) + else + # Filtra apenas IPv4, remove loopback (127.) e a subnet default do Docker (172.17.), + # mas preserva outras possíveis LANs (como 172.16., 172.18., etc) + DETECTED_IP=$(hostname -I 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | grep -v '^127\.' | grep -v '^172\.17\.' | head -n 1) + if [ -z "$DETECTED_IP" ]; then + # Fallback pegando o primeiro IPv4 caso o filtro acima falhe + DETECTED_IP=$(hostname -I 2>/dev/null | tr ' ' '\n' | grep -E '^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$' | head -n 1) + fi + fi + + echo -e "${YELLOW}Aviso: Se você estiver rodando em uma VPS, utilize o IP/DNS público.${NC}" + echo -e "${YELLOW} Se for rede local, confirme o IP LAN correto.${NC}" + read -p "IP da máquina [$DETECTED_IP]: " MACHINE_IP + MACHINE_IP=${MACHINE_IP:-$DETECTED_IP} + + if [ -z "$MACHINE_IP" ]; then + MACHINE_IP="127.0.0.1" + echo -e "${YELLOW}Aviso: IP não detectado/fornecido. Utilizando $MACHINE_IP como fallback.${NC}" + fi + + echo -e "\n${YELLOW}--- Configuração de Domínio/Tunnel (Opcional) ---${NC}" + echo -e "${YELLOW}Se você usa ngrok ou tem um domínio público, insira-o aqui.${NC}" + read -p "Domínio/Tunnel (ex: meudominio.com ou tunnel.ngrok-free.dev): " PUBLIC_DOMAIN + # 2. Criação dos arquivos .env echo -e "\n${BLUE}[1/4] Configurando arquivos .env...${NC}" # Backend cp back/src/.env.example back/src/.env - sedi "s|APP_URL=.*|APP_URL=http://localhost:$APP_PORT|" back/src/.env + sedi "s|APP_URL=.*|APP_URL=http://$MACHINE_IP:$APP_PORT|" back/src/.env sedi "s|DB_PASSWORD=.*|DB_PASSWORD=$DB_PASSWORD|" back/src/.env sedi "s|APP_NAME=.*|APP_NAME=\"$APP_NAME\"|" back/src/.env + if [ -n "$PUBLIC_DOMAIN" ]; then + sedi "s|SESSION_DOMAIN=.*|SESSION_DOMAIN=|" back/src/.env + sedi "s|SANCTUM_STATEFUL_DOMAINS=.*|SANCTUM_STATEFUL_DOMAINS=$MACHINE_IP:5173,$MACHINE_IP,$PUBLIC_DOMAIN|" back/src/.env + sedi "s|FRONTEND_URL=.*|FRONTEND_URL=http://$MACHINE_IP:5173,https://$PUBLIC_DOMAIN|" back/src/.env + sedi "s|allowedHosts:.*|allowedHosts: [\"localhost\", \"127.0.0.1\", \"$MACHINE_IP\", \"$PUBLIC_DOMAIN\"],|" front/vite.config.ts + sedi "s|SESSION_SECURE_COOKIE=.*|SESSION_SECURE_COOKIE=true|" back/src/.env + sedi "s|changeOrigin: false|changeOrigin: true|g" front/vite.config.ts + else + sedi "s|SESSION_DOMAIN=.*|SESSION_DOMAIN=$MACHINE_IP|" back/src/.env + sedi "s|SANCTUM_STATEFUL_DOMAINS=.*|SANCTUM_STATEFUL_DOMAINS=$MACHINE_IP:5173,$MACHINE_IP|" back/src/.env + sedi "s|FRONTEND_URL=.*|FRONTEND_URL=http://$MACHINE_IP:5173|" back/src/.env + sedi "s|allowedHosts:.*|allowedHosts: [\"localhost\", \"127.0.0.1\", \"$MACHINE_IP\"],|" front/vite.config.ts + fi + # Judge0 cp judge0.conf.example judge0.conf sedi "s|POSTGRES_PASSWORD=.*|POSTGRES_PASSWORD=$DB_PASSWORD|" judge0.conf # Frontend cp front/.env.example front/.env - sedi "s|VITE_API_URL=.*|VITE_API_URL=http://localhost:$APP_PORT|" front/.env + sedi "s|VITE_API_URL=.*|VITE_API_URL=|" front/.env + sedi "s|VITE_WS_URL=.*|VITE_WS_URL=ws://$MACHINE_IP:3002|" front/.env sedi "s|VITE_APP_NAME=.*|VITE_APP_NAME=\"$APP_NAME\"|" front/.env else echo -e "\n${GREEN}Configurações já existentes encontradas. Iniciando sistema...${NC}" - # Tenta extrair a porta do Backend do .env, assumindo 8000 como fallback - APP_PORT=$(grep "APP_URL=" back/src/.env | grep -o '[0-9]\+$') - APP_PORT=${APP_PORT:-"8000"} + # Tenta extrair a porta e o IP do Backend do .env + APP_URL_VAL=$(grep "^APP_URL=" back/src/.env | cut -d '=' -f2) + APP_PORT=$(echo "$APP_URL_VAL" | sed -E 's|.*://[^:]+:([0-9]+).*|\1|') + if ! [[ "$APP_PORT" =~ ^[0-9]+$ ]]; then + APP_PORT="8000" + fi + + MACHINE_IP=$(echo "$APP_URL_VAL" | sed -E 's|https?://||' | sed -E 's|[:/].*||') + MACHINE_IP=${MACHINE_IP:-"127.0.0.1"} echo -e "${BLUE}[1/4] Arquivos .env carregados com sucesso.${NC}" fi @@ -106,8 +154,8 @@ fi echo -e "\n${GREEN}==========================================================${NC}" echo -e "${GREEN} SISTEMA INICIADO COM SUCESSO! ${NC}" echo -e "${GREEN}==========================================================${NC}" -echo -e "Frontend: http://localhost:5173" -echo -e "Backend: http://localhost:$APP_PORT" +echo -e "Frontend: http://$MACHINE_IP:5173" +echo -e "Backend: http://$MACHINE_IP:$APP_PORT" if [ "$IS_FIRST_RUN" = true ]; then echo -e "Credenciais Padrão: admin@admin.com / 12345678" fi