@@ -2,9 +2,7 @@ import { type NextRequest, NextResponse } from "next/server"
22import { mkdir , appendFile } from "fs/promises"
33import path from "path"
44import { getPool } from "@/lib/db"
5- import type { Role } from "@/lib/roles"
6-
7- const ALLOWED_ROLES : Role [ ] = [ "admin" , "advisor" , "ir" ]
5+ import { canAccess , type Role } from "@/lib/roles"
86
97const LOGS_DIR = path . join ( process . cwd ( ) , "logs" )
108const LOG_FILE = path . join ( LOGS_DIR , "query-history.jsonl" )
@@ -21,7 +19,7 @@ export async function GET(
2119
2220 // Role check
2321 const role = request . headers . get ( "x-user-role" ) as Role | null
24- if ( ! role || ! ALLOWED_ROLES . includes ( role ) ) {
22+ if ( ! role || ! canAccess ( "/api/students" , role ) ) {
2523 return NextResponse . json ( { error : "Forbidden" } , { status : 403 } )
2624 }
2725
@@ -30,6 +28,8 @@ export async function GET(
3028 return NextResponse . json ( { error : "Missing student GUID" } , { status : 400 } )
3129 }
3230
31+ let url : string
32+
3333 try {
3434 // Look up SIS ID from mapping table
3535 const pool = getPool ( )
@@ -45,24 +45,28 @@ export async function GET(
4545 // Build URL server-side — SIS ID never reaches the client
4646 const sisIdParam = process . env . SIS_ID_PARAM || "id"
4747 const sisId = result . rows [ 0 ] . sis_id
48- const url = `${ sisBaseUrl } ?${ encodeURIComponent ( sisIdParam ) } =${ encodeURIComponent ( sisId ) } `
49-
50- // Audit log — GUID and role only, never the SIS ID
51- const logEntry = {
52- event : "sis_link_accessed" ,
53- guid,
54- role,
55- timestamp : new Date ( ) . toISOString ( ) ,
56- }
57- await mkdir ( LOGS_DIR , { recursive : true } )
58- await appendFile ( LOG_FILE , JSON . stringify ( logEntry ) + "\n" , "utf8" )
59-
60- return NextResponse . json ( { url } )
48+ url = `${ sisBaseUrl } ?${ encodeURIComponent ( sisIdParam ) } =${ encodeURIComponent ( sisId ) } `
6149 } catch ( error ) {
6250 console . error ( "SIS link lookup error:" , error )
6351 return NextResponse . json (
6452 { error : "Failed to look up SIS link" } ,
6553 { status : 500 }
6654 )
6755 }
56+
57+ // Audit log — GUID and role only, never the SIS ID
58+ const logEntry = {
59+ event : "sis_link_accessed" ,
60+ guid,
61+ role,
62+ timestamp : new Date ( ) . toISOString ( ) ,
63+ }
64+ try {
65+ await mkdir ( LOGS_DIR , { recursive : true } )
66+ await appendFile ( LOG_FILE , JSON . stringify ( logEntry ) + "\n" , "utf8" )
67+ } catch ( auditErr ) {
68+ console . error ( "SIS audit log write failed:" , auditErr )
69+ }
70+
71+ return NextResponse . json ( { url } )
6872}
0 commit comments