All checks were successful
Staging Build / build (push) Successful in 2m50s
- Add auth guard to getLicServerConfig() - unauthenticated callers now receive null config instead of DB values - Remove non-existent 'superadmin' role from saveLicServerConfig() check (only 'admin' exists per project schema) - New migration: restrict settings table WRITE to admins only (previously any authenticated user could overwrite licserver_api_key)
93 lines
2.8 KiB
TypeScript
93 lines
2.8 KiB
TypeScript
'use server'
|
|
|
|
import { createClient } from '@/lib/supabase/server'
|
|
|
|
export interface LicServerConfig {
|
|
base_url: string | null
|
|
api_key: string | null
|
|
}
|
|
|
|
/**
|
|
* Read LicServer config from the settings table.
|
|
* Falls back to environment variables if DB values are empty.
|
|
* Returns null config for unauthenticated callers.
|
|
*/
|
|
export async function getLicServerConfig(): Promise<LicServerConfig> {
|
|
const supabase = await createClient()
|
|
|
|
// Auth guard — never expose config to unauthenticated callers
|
|
const { data: { user } } = await supabase.auth.getUser()
|
|
if (!user) return { base_url: null, api_key: null }
|
|
|
|
const { data } = await supabase
|
|
.from('settings')
|
|
.select('licserver_base_url, licserver_api_key')
|
|
.eq('id', 'licserver')
|
|
.single()
|
|
|
|
return {
|
|
base_url: data?.licserver_base_url || process.env.LICSERVER_BASE_URL || null,
|
|
api_key: data?.licserver_api_key || process.env.LICSERVER_API_KEY || null,
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Save LicServer config. Admin-only — checks role before writing.
|
|
*/
|
|
export async function saveLicServerConfig(
|
|
base_url: string,
|
|
api_key: string
|
|
): Promise<{ success: boolean; error?: string }> {
|
|
const supabase = await createClient()
|
|
|
|
// Auth + role check
|
|
const { data: { user } } = await supabase.auth.getUser()
|
|
if (!user) return { success: false, error: 'Nicht angemeldet' }
|
|
|
|
const { data: userData } = await supabase
|
|
.from('users')
|
|
.select('role')
|
|
.eq('id', user.id)
|
|
.single()
|
|
|
|
// Only 'admin' exists in schema — 'superadmin' removed
|
|
if (!userData || userData.role !== 'admin') {
|
|
return { success: false, error: 'Keine Berechtigung (nur Admins)' }
|
|
}
|
|
|
|
const { error } = await supabase
|
|
.from('settings')
|
|
.upsert({
|
|
id: 'licserver',
|
|
licserver_base_url: base_url.trim() || null,
|
|
licserver_api_key: api_key.trim() || null,
|
|
updated_at: new Date().toISOString(),
|
|
})
|
|
|
|
if (error) return { success: false, error: error.message }
|
|
return { success: true }
|
|
}
|
|
|
|
/**
|
|
* Test the connection with current config.
|
|
* Calls GET /api-v1/partners?pageSize=1 and returns true if 200.
|
|
*/
|
|
export async function testLicServerConnection(): Promise<{ ok: boolean; message: string }> {
|
|
const cfg = await getLicServerConfig()
|
|
|
|
if (!cfg.base_url || !cfg.api_key) {
|
|
return { ok: false, message: 'URL oder API-Key nicht konfiguriert' }
|
|
}
|
|
|
|
try {
|
|
const res = await fetch(`${cfg.base_url}/api-v1/partners?pageSize=1`, {
|
|
headers: { 'X-Api-Key': cfg.api_key, Accept: 'application/json' },
|
|
signal: AbortSignal.timeout(5_000),
|
|
})
|
|
if (res.ok) return { ok: true, message: `Verbindung OK (HTTP ${res.status})` }
|
|
return { ok: false, message: `LicServer antwortete mit HTTP ${res.status}` }
|
|
} catch (err: any) {
|
|
return { ok: false, message: `Nicht erreichbar: ${err.message}` }
|
|
}
|
|
}
|