mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-11 17:27:31 +02:00
Make user creation and deletion more robust and prevent data loss
Update user schema to make username and password mandatory, adjust email validation, and handle foreign key constraints during user deletion, including updating the database_backups table. Replit-Commit-Author: Agent Replit-Commit-Session-Id: a8a78c07-e900-425c-a577-5b4c5894379d Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/a8a78c07-e900-425c-a577-5b4c5894379d/vetH0Gp
This commit is contained in:
1 parent
7618fb1643
commit
e7fb2c66f1
9 files changed
+152
-4
No files matched your search
+133
@@ -0,0 +1,133 @@
|
||||
📊 User system groups: 0
|
||||
|
||||
📊 User AnneLaure groups: 1
|
||||
|
||||
🔍 Final users with roles and groups: 7
|
||||
|
||||
🔐 API /api/users - Returning: { isArray: true, length: 7 }
|
||||
|
||||
GET /api/users 200 in 80ms
|
||||
|
||||
Error deleting user: error: update or delete on table "users" violates foreign key constraint "database_backups_created_by_fkey" on table "database_backups"
|
||||
|
||||
at /app/node_modules/pg/lib/client.js:545:17
|
||||
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
|
||||
|
||||
at async file:///app/dist/index.js:1109:11
|
||||
|
||||
at async NodePgSession.transaction (file:///app/node_modules/drizzle-orm/node-postgres/session.js:142:22)
|
||||
|
||||
at async DatabaseStorage.deleteUser (file:///app/dist/index.js:1090:9)
|
||||
|
||||
at async file:///app/dist/index.js:4095:7 {
|
||||
|
||||
length: 327,
|
||||
|
||||
severity: 'ERROR',
|
||||
|
||||
code: '23503',
|
||||
|
||||
detail: 'Key (id)=(system) is still referenced from table "database_backups".',
|
||||
|
||||
hint: undefined,
|
||||
|
||||
position: undefined,
|
||||
|
||||
internalPosition: undefined,
|
||||
|
||||
internalQuery: undefined,
|
||||
|
||||
where: undefined,
|
||||
|
||||
schema: 'public',
|
||||
|
||||
table: 'database_backups',
|
||||
|
||||
column: undefined,
|
||||
|
||||
dataType: undefined,
|
||||
|
||||
constraint: 'database_backups_created_by_fkey',
|
||||
|
||||
file: 'ri_triggers.c',
|
||||
|
||||
line: '2609',
|
||||
|
||||
routine: 'ri_ReportViolation'
|
||||
|
||||
}
|
||||
|
||||
DELETE /api/users/system 500 in 28ms
|
||||
|
||||
HEAD /api/health 200 in 1ms
|
||||
|
||||
Error creating user: ZodError: [
|
||||
|
||||
{
|
||||
|
||||
"validation": "email",
|
||||
|
||||
"code": "invalid_string",
|
||||
|
||||
"message": "Invalid email",
|
||||
|
||||
"path": [
|
||||
|
||||
"email"
|
||||
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
at get error [as error] (file:///app/node_modules/zod/v3/types.js:39:31)
|
||||
|
||||
at ZodObject.parse (file:///app/node_modules/zod/v3/types.js:114:22)
|
||||
|
||||
at file:///app/dist/index.js:3988:41
|
||||
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
|
||||
|
||||
issues: [
|
||||
|
||||
{
|
||||
|
||||
validation: 'email',
|
||||
|
||||
code: 'invalid_string',
|
||||
|
||||
message: 'Invalid email',
|
||||
|
||||
path: [Array]
|
||||
|
||||
}
|
||||
|
||||
],
|
||||
|
||||
addIssue: [Function (anonymous)],
|
||||
|
||||
addIssues: [Function (anonymous)],
|
||||
|
||||
errors: [
|
||||
|
||||
{
|
||||
|
||||
validation: 'email',
|
||||
|
||||
code: 'invalid_string',
|
||||
|
||||
message: 'Invalid email',
|
||||
|
||||
path: [Array]
|
||||
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
POST /api/users 400 in 26ms
|
||||
|
||||
HEAD /api/health 200 in 1ms
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 223 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 230 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 230 KiB |
@@ -446,7 +446,7 @@ export default function UsersPage() {
|
||||
});
|
||||
|
||||
setShowCreateModal(false);
|
||||
setNewUser({ email: "", firstName: "", lastName: "", password: "", role: "employee" });
|
||||
setNewUser({ email: "", firstName: "", lastName: "", username: "", password: "", role: "employee" });
|
||||
setUserGroups([]);
|
||||
queryClient.invalidateQueries({ queryKey: ['/api/users'] });
|
||||
} catch (error) {
|
||||
|
||||
@@ -90,7 +90,7 @@ Preferred communication style: Simple, everyday language.
|
||||
- Ownership transfer of all user-created records to existing admin before deletion
|
||||
- Comprehensive handling of all foreign key relationships including role assignments
|
||||
- Graceful error handling when no admin user exists
|
||||
- **Tables Handled**: customer_orders, orders, deliveries, publicities, dlcProducts, tasks, nocodbConfig, userGroups, userRoles (both userId and assignedBy)
|
||||
- **Tables Handled**: customer_orders, orders, deliveries, publicities, dlcProducts, tasks, nocodbConfig, userGroups, userRoles (both userId and assignedBy), database_backups
|
||||
- **Result**: Safe user deletion while preserving business data integrity
|
||||
|
||||
#### User Name Fields Optional in Production
|
||||
|
||||
+3
-2
@@ -877,10 +877,11 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Schema création utilisateur SANS champs obligatoires pour résoudre le problème de production
|
||||
const createUserSchema = z.object({
|
||||
id: z.string().optional(),
|
||||
email: z.string().email().optional(),
|
||||
username: z.string().min(1, "L'identifiant est obligatoire"),
|
||||
email: z.union([z.string().email(), z.literal("")]).optional(),
|
||||
firstName: z.string().optional(),
|
||||
lastName: z.string().optional(),
|
||||
password: z.string().optional(),
|
||||
password: z.string().min(1, "Le mot de passe est obligatoire"),
|
||||
role: z.enum(['admin', 'manager', 'employee']).optional(),
|
||||
});
|
||||
|
||||
|
||||
@@ -419,6 +419,18 @@ export class DatabaseStorage implements IStorage {
|
||||
.update(nocodbConfig)
|
||||
.set({ createdBy: adminUserId })
|
||||
.where(eq(nocodbConfig.createdBy, id));
|
||||
|
||||
// Update database backups if the table exists (production feature)
|
||||
try {
|
||||
await tx.execute(sql`
|
||||
UPDATE database_backups
|
||||
SET created_by = ${adminUserId}
|
||||
WHERE created_by = ${id}
|
||||
`);
|
||||
} catch (error) {
|
||||
// Table might not exist in development, ignore the error
|
||||
console.log('Note: database_backups table not found or accessible');
|
||||
}
|
||||
|
||||
// Update role assignments made BY this user (assignedBy field)
|
||||
await tx
|
||||
|
||||
@@ -460,6 +460,8 @@ export const insertUserSchema = createInsertSchema(users).pick({
|
||||
password: true,
|
||||
role: true,
|
||||
passwordChanged: true,
|
||||
}).extend({
|
||||
email: z.union([z.string().email(), z.literal("")]).optional(),
|
||||
});
|
||||
|
||||
export const insertGroupSchema = createInsertSchema(groups).omit({
|
||||
|
||||
Reference in new issue
Block a user