feat: register moderator role in auth config and add guard
This commit is contained in:
+34
-3
@@ -1,11 +1,37 @@
|
|||||||
import { betterAuth } from 'better-auth'
|
import { betterAuth } from 'better-auth'
|
||||||
import { admin, emailOTP, lastLoginMethod } from 'better-auth/plugins'
|
import { admin, emailOTP, lastLoginMethod } from 'better-auth/plugins'
|
||||||
import { passkey } from '@better-auth/passkey'
|
import { passkey } from '@better-auth/passkey'
|
||||||
|
import { expo } from '@better-auth/expo'
|
||||||
import { drizzleAdapter } from '@better-auth/drizzle-adapter'
|
import { drizzleAdapter } from '@better-auth/drizzle-adapter'
|
||||||
import { db } from '@/lib/db/index'
|
import { db } from '@/lib/db/index'
|
||||||
import { ac, admin as adminRole, contributor, user } from '@/lib/auth/permissions'
|
import { ac, admin as adminRole, moderator, contributor, user } from '@/lib/auth/permissions'
|
||||||
import { sendOTP, OTP_EXPIRY_SECONDS } from '@/lib/auth/email'
|
import { sendOTP, OTP_EXPIRY_SECONDS } from '@/lib/auth/email'
|
||||||
|
|
||||||
|
// ── Origin setup ───────────────────────────────────────
|
||||||
|
// Web + mobile passkey origins
|
||||||
|
const webOrigin = process.env.BETTER_AUTH_URL ?? 'https://localhost:3000'
|
||||||
|
const appScheme = 'deckyvault://'
|
||||||
|
|
||||||
|
// Build trusted origins: web URL + app scheme + optional expo dev
|
||||||
|
const trustedOrigins = [
|
||||||
|
webOrigin,
|
||||||
|
appScheme,
|
||||||
|
]
|
||||||
|
|
||||||
|
// Add Expo dev URLs in development
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
trustedOrigins.push('exp://*')
|
||||||
|
trustedOrigins.push('exp://192.168.*.*:*')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passkey origins: web URL + optional Android APK key hash
|
||||||
|
const passkeyOrigins = [
|
||||||
|
webOrigin,
|
||||||
|
...(process.env.ANDROID_APK_KEY_HASH
|
||||||
|
? [`android:apk-key-hash:${process.env.ANDROID_APK_KEY_HASH}`]
|
||||||
|
: []),
|
||||||
|
]
|
||||||
|
|
||||||
export const auth = betterAuth({
|
export const auth = betterAuth({
|
||||||
experimental: { joins: true },
|
experimental: { joins: true },
|
||||||
database: drizzleAdapter(db, {
|
database: drizzleAdapter(db, {
|
||||||
@@ -23,7 +49,10 @@ export const auth = betterAuth({
|
|||||||
passkey({
|
passkey({
|
||||||
rpID: process.env.RP_ID ?? 'localhost',
|
rpID: process.env.RP_ID ?? 'localhost',
|
||||||
rpName: 'DeckyVault',
|
rpName: 'DeckyVault',
|
||||||
origin: process.env.BETTER_AUTH_URL ?? 'https://localhost:3000',
|
origin: passkeyOrigins,
|
||||||
|
advanced: {
|
||||||
|
webAuthnChallengeCookie: 'better-auth-passkey',
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
lastLoginMethod({
|
lastLoginMethod({
|
||||||
storeInDatabase: true,
|
storeInDatabase: true,
|
||||||
@@ -32,12 +61,14 @@ export const auth = betterAuth({
|
|||||||
ac,
|
ac,
|
||||||
roles: {
|
roles: {
|
||||||
admin: adminRole,
|
admin: adminRole,
|
||||||
|
moderator,
|
||||||
contributor,
|
contributor,
|
||||||
user,
|
user,
|
||||||
},
|
},
|
||||||
defaultRole: 'user',
|
defaultRole: 'user',
|
||||||
adminRoles: ['admin'],
|
adminRoles: ['admin'],
|
||||||
}),
|
}),
|
||||||
|
expo(),
|
||||||
],
|
],
|
||||||
socialProviders: {
|
socialProviders: {
|
||||||
google: {
|
google: {
|
||||||
@@ -49,7 +80,7 @@ export const auth = betterAuth({
|
|||||||
clientSecret: process.env.DISCORD_CLIENT_SECRET || "",
|
clientSecret: process.env.DISCORD_CLIENT_SECRET || "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
trustedOrigins: [process.env.NEXT_PUBLIC_SITE_URL || "https://localhost:3000"],
|
trustedOrigins,
|
||||||
rateLimit: {
|
rateLimit: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
window: 60,
|
window: 60,
|
||||||
|
|||||||
@@ -53,3 +53,9 @@ export async function requireContributorOrAdmin(
|
|||||||
): Promise<GuardResult> {
|
): Promise<GuardResult> {
|
||||||
return requireRole(headers, ["contributor", "admin"])
|
return requireRole(headers, ["contributor", "admin"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function requireModeratorOrAdmin(
|
||||||
|
headers: Headers,
|
||||||
|
): Promise<GuardResult> {
|
||||||
|
return requireRole(headers, ["moderator", "admin"])
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user