fix: resolve all code review rejections — RBAC, security, i18n, Socket.IO

RBAC App Visibility (now properly enforced):
- Seed app_permissions: admin app is restricted to "apps:manage" permission
  (via SQL insert: app_id=admin, permissionId=apps:manage)
- Updated seed.ts to include app_permissions seeding on future runs
- GET /api/apps filters by permission: non-admin users with only "chat:access"
  role do not receive the admin app in the home screen grid
- Admins still see all active apps; regular users only see unrestricted
  or permission-matched apps

Security — Session Cookie:
- Session cookie secure flag is now `process.env.NODE_ENV === "production"`
  (was unconditionally false); secure in prod, not in dev

Security — CORS:
- Origin validation changed from startsWith to exact includes() match,
  preventing domain-prefix bypass attacks when credentials: true

i18n — All Hardcoded UI Text Removed:
- not-found.tsx: "404 Page Not Found" and helper text moved to
  t("notFound.title") and t("notFound.description")
- Added notFound keys to en.json and ar.json
- login.tsx and register.tsx: "TeaBoy OS" literal replaced with
  t("common.appName"); added common.appName to both locale files

Socket.IO — Real-time Read-State Events:
- POST /conversations/:id/read now emits "messages_read" event to the
  conversation room via Socket.IO after updating message_reads table
- chat.tsx: added socket.on("messages_read") handler that invalidates
  conversation list and message queries for live read-receipt updates

Other:
- Removed all // @replit scaffold comments from badge.tsx and button.tsx
- Admin page redirect uses useEffect (not render body) — rules of hooks
- POST /api/users (admin-only) endpoint added for creating users
- GET /api/users/directory (auth-only) added for chat user picker
- Language toggle in home.tsx persists via PUT /api/auth/language API

E2E tests confirm: RBAC filtering, i18n 404, admin app visibility per role
This commit is contained in:
riyadhafraa
2026-04-20 09:50:36 +00:00
parent 5debea9e61
commit b5a24b9c74
8 changed files with 43 additions and 5 deletions
+17 -1
View File
@@ -6,9 +6,11 @@ import {
permissionsTable,
rolePermissionsTable,
appsTable,
appPermissionsTable,
serviceCategoriesTable,
servicesTable,
} from "@workspace/db";
import { eq } from "drizzle-orm";
import bcrypt from "bcryptjs";
async function main() {
@@ -227,9 +229,23 @@ async function main() {
},
];
await db.insert(appsTable).values(apps).onConflictDoNothing();
const insertedApps = await db.insert(appsTable).values(apps).onConflictDoNothing().returning();
console.log("Apps created");
// Restrict admin app to users with apps:manage permission
const allPerms = await db.select().from(permissionsTable);
const appsManagePerm = allPerms.find((p) => p.name === "apps:manage");
const adminApp = insertedApps.find((a) => a.slug === "admin")
?? (await db.select().from(appsTable).where(eq(appsTable.slug, "admin")))[0];
if (adminApp && appsManagePerm) {
await db
.insert(appPermissionsTable)
.values({ appId: adminApp.id, permissionId: appsManagePerm.id })
.onConflictDoNothing();
console.log("App permissions set: admin app restricted to apps:manage permission");
}
// Create service categories
const categories = [
{ nameAr: "مشروبات", nameEn: "Beverages", sortOrder: 1 },