Migracao Logto + Supabase - backend e frontend atualizados para nova autenticação

This commit is contained in:
2026-03-30 20:50:10 +00:00
parent 9d3958b82b
commit f89d5571f4
22 changed files with 1266 additions and 1047 deletions
+24 -55
View File
@@ -1,72 +1,41 @@
import PaintingScheme from '../models/PaintingScheme.js';
import { PaintingScheme } from '../lib/compat.js';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const createPaintingScheme = async (data: any & { organizationId?: string }) => {
const newScheme = new PaintingScheme({ ...data, organizationId: data.organizationId });
const saved = await newScheme.save();
return { ...saved.toObject(), id: saved._id.toString() };
return await PaintingScheme.create({ ...data, organization_id: data.organizationId });
};
export const getPaintingSchemesByProject = async (projectId: string, organizationId?: string) => {
const query = { projectId, ...(organizationId ? { organizationId } : {}) };
const schemes = await PaintingScheme.find(query).lean();
return schemes.map(s => ({ ...s, id: s._id.toString() }));
const filter: any = { project_id: projectId };
if (organizationId) {
filter.organization_id = organizationId;
}
return await PaintingScheme.find(filter);
};
export const getPaintingSchemeById = async (id: string) => {
return await PaintingScheme.findById(id);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const updatePaintingScheme = async (id: string, data: any, organizationId?: string) => {
// SECURITY FIX: Allow update if:
// 1. Matches ID AND Matches Organization
// 2. OR Matches ID AND Record has NO organization (legacy/orphan) -> Adopt it!
let query: any = { _id: id };
// First, check if the record exists and what is its state
const existing = await PaintingScheme.findById(id);
if (!existing) return null;
// Check ownership
if (organizationId && existing.organizationId && existing.organizationId !== organizationId) {
// Exists but belongs to ANOTHER organization -> Deny
console.warn(`Access Denied: Scheme ${id} belongs to ${existing.organizationId}, user is ${organizationId}`);
return null; // Return null effectively hides it or acts as fail
if (organizationId && existing.organization_id && existing.organization_id !== organizationId) {
return null;
}
// If we passed the check, we perform the update.
// Ensure we "adopt" the record if it didn't have an orgId
if (organizationId && !data.organizationId) {
data.organizationId = organizationId;
}
const updated = await PaintingScheme.findOneAndUpdate({ _id: id }, data, { new: true }).lean();
if (updated) {
return { ...updated, id: updated._id.toString() };
}
return null;
return await PaintingScheme.findByIdAndUpdate(id, data);
};
export const deletePaintingScheme = async (id: string, organizationId?: string) => {
// Find first to check permissions
const existing = await PaintingScheme.findById(id);
if (!existing) return;
// Permissions:
// If user has org, and item has OTHER org, deny.
if (organizationId && existing.organizationId && existing.organizationId !== organizationId) {
console.warn(`[Delete PaintingScheme] Access Denied. User Org: ${organizationId}, Scheme Org: ${existing.organizationId}`);
return;
}
await PaintingScheme.findByIdAndDelete(id);
export const deletePaintingScheme = async (id: string) => {
return await PaintingScheme.findByIdAndDelete(id);
};
export const getAllSchemes = async (organizationId?: string) => {
const query = organizationId ? { organizationId } : {};
const schemes = await PaintingScheme.find(query).lean();
return schemes.map(s => ({ ...s, id: s._id.toString() }));
export const clonePaintingScheme = async (id: string, newData: any) => {
const original = await PaintingScheme.findById(id);
if (!original) return null;
return await PaintingScheme.create({ ...original, ...newData, id: undefined });
};
console.log('✅ PaintingSchemeService loaded with compatibility');