Skip to content

Commit 35c5e76

Browse files
authored
Merge pull request #3 from SGAOperations/fix/calendar-deactivated-email-guard
SGA Space Calendar Rendering & Onboarding Bug Fixes
2 parents 74d4b8c + da6c950 commit 35c5e76

7 files changed

Lines changed: 40 additions & 6 deletions

File tree

app/(dashboard)/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ export default function DashboardLayout({
233233
<span className="text-[#c8102e] font-bold text-xl tracking-tight">Chambers</span>
234234
</div>
235235
<p className="text-slate-500 text-xs mt-0.5">NU Student Gov. Association</p>
236-
<p className="text-slate-600 text-xs mt-1">v1.12.0</p>
236+
<p className="text-slate-600 text-xs mt-1">v1.12.1</p>
237237
{userName && (
238238
<div className="flex items-start justify-between mt-2">
239239
<p className="text-slate-500 text-xs italic">{getGreeting()},<br />{userName}</p>

app/(dashboard)/sga-spaces/space-calendar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,10 @@ export default function SpaceCalendar({
302302
const totalHeight = TOTAL_SLOTS * SLOT_HEIGHT
303303

304304
return (
305-
<div className="rounded-xl border border-[#1e5080] overflow-hidden bg-[#0a1628] select-none">
305+
<div className="rounded-xl border border-[#1e5080] overflow-hidden bg-[#0a1628] select-none isolate">
306306
<div ref={scrollRef} className="overflow-y-auto" style={{ maxHeight: '648px' }}>
307307
{/* Sticky day header */}
308-
<div ref={headerRef} className="flex border-b border-[#1e5080] sticky top-0 z-10 bg-[#0a1628]">
308+
<div ref={headerRef} className="flex border-b border-[#1e5080] sticky top-0 z-[60] bg-[#0a1628]">
309309
<div className="w-14 flex-shrink-0 border-r border-[#1e5080]" />
310310
{dayLabels.map((dl, i) => (
311311
<div

app/api/administrator/users/route.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,20 @@ export async function POST(request: Request) {
5555

5656
const { email, full_name, admin_role, iems_role } = await request.json()
5757

58+
// Block re-inviting a deactivated account — admin must reactivate instead
59+
const { count: deactivatedCount } = await adminSupabase
60+
.from('users')
61+
.select('id', { count: 'exact', head: true })
62+
.eq('email', email.trim().toLowerCase())
63+
.eq('is_active', false)
64+
65+
if (deactivatedCount && deactivatedCount > 0) {
66+
return NextResponse.json(
67+
{ error: 'A deactivated account already exists for this email. Reactivate the account instead of sending a new invite.' },
68+
{ status: 400 }
69+
)
70+
}
71+
5872
const otp = randomBytes(8).toString('base64url').slice(0, 12)
5973
const otpHash = createHash('sha256').update(otp).digest('hex')
6074
const otpExpiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString()

app/api/onboarding/profile/route.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,11 @@ export async function PATCH(request: Request) {
3434

3535
if (error) return NextResponse.json({ error: error.message }, { status: 500 })
3636

37+
const { error: metaError } = await adminSupabase.auth.admin.updateUserById(user.id, {
38+
user_metadata: { full_name },
39+
})
40+
41+
if (metaError) return NextResponse.json({ error: metaError.message }, { status: 500 })
42+
3743
return NextResponse.json({ success: true })
3844
}

app/api/signup/request/route.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ export async function POST(request: Request) {
2323

2424
const normalizedEmail = email.trim().toLowerCase()
2525

26+
// Block deactivated accounts — generic message to avoid leaking account status
27+
const { count: deactivatedCount } = await adminSupabase
28+
.from('users')
29+
.select('id', { count: 'exact', head: true })
30+
.eq('email', normalizedEmail)
31+
.eq('is_active', false)
32+
33+
if (deactivatedCount && deactivatedCount > 0) {
34+
return NextResponse.json(
35+
{ error: 'This email is not eligible for registration. Please contact an administrator.' },
36+
{ status: 400 }
37+
)
38+
}
39+
2640
// Check if a fully set-up account already exists (head-only, no data returned)
2741
const { count: existingCount } = await adminSupabase
2842
.from('users')

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "chambers",
3-
"version": "1.12.0",
3+
"version": "1.12.1",
44
"private": true,
55
"scripts": {
66
"dev": "next dev",

0 commit comments

Comments
 (0)