d3ro-voice/server/supabase/functions/_shared/admin-auth.ts
2026-08-29 18:33:45 +09:00

74 lines
2.2 KiB
TypeScript

// server/supabase/functions/_shared/admin-auth.ts
// 3단계 권한 검증: manager < admin < super_admin
import type { User } from 'https://esm.sh/@supabase/supabase-js@2.39.7'
import { requireUser, type AuthError } from './auth.ts'
export type AdminRole = 'manager' | 'admin' | 'super_admin'
const ROLE_LEVEL: Record<string, number> = {
user: 0,
manager: 1,
admin: 2,
super_admin: 3,
}
function getUserRole(user: User): string {
return ((user.app_metadata as Record<string, unknown>)?.role as string) ?? 'user'
}
/**
* manager 이상 권한 필요 (manager, admin, super_admin).
*/
export async function requireManager(req: Request): Promise<User> {
const user = await requireUser(req)
const role = getUserRole(user)
if ((ROLE_LEVEL[role] ?? 0) < ROLE_LEVEL.manager) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw { status: 403, message: 'Manager access required' } as AuthError
}
return user
}
/**
* admin 이상 권한 필요 (admin, super_admin).
*/
export async function requireAdmin(req: Request): Promise<User> {
const user = await requireUser(req)
const role = getUserRole(user)
if ((ROLE_LEVEL[role] ?? 0) < ROLE_LEVEL.admin) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw { status: 403, message: 'Admin access required' } as AuthError
}
return user
}
/**
* super_admin 전용 권한 필요.
*/
export async function requireSuperAdmin(req: Request): Promise<User> {
const user = await requireUser(req)
const role = getUserRole(user)
if ((ROLE_LEVEL[role] ?? 0) < ROLE_LEVEL.super_admin) {
// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw { status: 403, message: 'Super admin access required' } as AuthError
}
return user
}
/**
* 현재 유저의 admin role 반환. manager 미만이면 null.
*/
export function getAdminRole(user: User): AdminRole | null {
const role = getUserRole(user)
if (role === 'manager' || role === 'admin' || role === 'super_admin') return role as AdminRole
return null
}
/**
* 유저가 특정 최소 레벨 이상인지 체크.
*/
export function hasMinRole(user: User, minRole: AdminRole): boolean {
const role = getUserRole(user)
return (ROLE_LEVEL[role] ?? 0) >= (ROLE_LEVEL[minRole] ?? 0)
}