Walrus blob · testnet
On-chain registration not yet visible.
The aggregator served this blob, but we couldn't locate a matching BlobRegistered event in our scan window. It may not be certified yet, or live further back than we paged.
Lifecycle data is unavailable until the blob registration is visible on-chain.
import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '../auth/[...nextauth]/route';
import { query } from '@/lib/db';
import type { User } from '@/lib/types';
export async function GET() {
const session = await getServerSession(authOptions);
if (!session) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
const users = await query<User>(
'SELECT id, name, email, is_admin, avatar_url, created_at FROM users ORDER BY name',
);
return NextResponse.json(users);
}
export async function POST(req: NextRequest) {
const session = await getServerSession(authOptions);
if (!session?.user?.is_admin) return NextResponse.json({ error: 'Admin only' }, { status: 403 });
const { name, email, is_admin } = await req.json();
if (!name?.trim() || !email?.trim()) {
return NextResponse.json({ error: 'name and email are required' }, { status: 400 });
}
if (!email.endsWith('@levukalabs.com')) {
return NextResponse.json({ error: 'Email must be @levukalabs.com' }, { status: 400 });
}
await query(
`INSERT INTO users (name, email, is_admin) VALUES (?, ?, ?)
ON DUPLICATE KEY UPDATE name = VALUES(name), is_admin = VALUES(is_admin)`,
[name.trim(), email.trim().toLowerCase(), is_admin ? 1 : 0],
);
return NextResponse.json({ ok: true }, { status: 201 });
}