Lock student profile editing to admins only
Parents and teachers are now view-only on student data (profile, guardians, pickups, curriculum logins). Writes restricted to admins in RLS and the UI; read access unchanged. Portal logins for parents/students are view-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -62,7 +62,7 @@ function StudentDetail() {
|
||||
const { id } = Route.useParams();
|
||||
const { roles } = useAuth();
|
||||
const isAdmin = roles.includes("admin");
|
||||
const canEdit = isAdmin || roles.includes("parent"); // parents can fill out their own child's profile (RLS-scoped)
|
||||
const canEdit = isAdmin; // student profile data is admin-edit-only; parents/teachers view only
|
||||
|
||||
const { data: student } = useQuery({
|
||||
queryKey: ["student", id],
|
||||
@@ -355,7 +355,7 @@ function ParentAccessSection({ studentId }: { studentId: string }) {
|
||||
});
|
||||
return (
|
||||
<div className="space-y-3 border-t pt-6">
|
||||
<div><h3 className="font-semibold flex items-center gap-2"><UserPlus className="h-4 w-4" /> Portal access</h3><p className="text-xs text-muted-foreground">Create logins so a parent (can edit this profile) or the student (view-only grades) can sign in.</p></div>
|
||||
<div><h3 className="font-semibold flex items-center gap-2"><UserPlus className="h-4 w-4" /> Portal access</h3><p className="text-xs text-muted-foreground">Create view-only logins so a parent or the student can sign in to see this student's info and grades.</p></div>
|
||||
<div className="bg-card border rounded-lg divide-y">
|
||||
{studentLogin && <div className="p-3"><div className="font-medium text-sm">{studentLogin.full_name || "Student"} <span className="text-[10px] uppercase tracking-wide bg-primary/10 text-primary rounded px-1.5 py-0.5">Student</span></div><div className="text-xs text-muted-foreground">{studentLogin.email}</div></div>}
|
||||
{(parents ?? []).map((p) => <div key={p.id} className="p-3"><div className="font-medium text-sm">{p.full_name || "—"} <span className="text-[10px] uppercase tracking-wide bg-muted rounded px-1.5 py-0.5">Parent</span></div><div className="text-xs text-muted-foreground">{p.email}</div></div>)}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
-- Student profile data (guardians, pickups, curriculum logins) is admin-edit-only.
|
||||
-- Reads are unchanged (parents/teachers/students keep their "... read" policies);
|
||||
-- the students table itself is already admin-write via "admins manage students".
|
||||
|
||||
DROP POLICY IF EXISTS "guardians write parent or admin" ON public.student_guardians;
|
||||
CREATE POLICY "guardians write admin" ON public.student_guardians FOR ALL TO authenticated
|
||||
USING (public.current_user_has_role('admin')) WITH CHECK (public.current_user_has_role('admin'));
|
||||
|
||||
DROP POLICY IF EXISTS "pickups write parent or admin" ON public.authorized_pickups;
|
||||
CREATE POLICY "pickups write admin" ON public.authorized_pickups FOR ALL TO authenticated
|
||||
USING (public.current_user_has_role('admin')) WITH CHECK (public.current_user_has_role('admin'));
|
||||
|
||||
DROP POLICY IF EXISTS "curriculum write parent or admin" ON public.student_curriculum_logins;
|
||||
CREATE POLICY "curriculum write admin" ON public.student_curriculum_logins FOR ALL TO authenticated
|
||||
USING (public.current_user_has_role('admin')) WITH CHECK (public.current_user_has_role('admin'));
|
||||
Reference in New Issue
Block a user