feat: Entra ID login + settings page for integrations
- Add SQLite settings table with getSetting/setSetting/getAllSettings helpers - Implement Azure OAuth2 authorization code flow via @azure/msal-node - Add public GET /api/auth/config endpoint for frontend activation check - Add admin-only GET/PUT /api/settings API with masked secret fields - CheckMK sync reads credentials from DB settings (env vars as fallback) - New Settings.tsx: Entra ID and CheckMK configuration cards - LoginPage: "Sign in with Microsoft" button, shown only when Azure is active - App.tsx: OAuth callback handling (?token=/?auth_error=), Settings tab for admins
This commit is contained in:
34
server-db.ts
34
server-db.ts
@ -70,6 +70,12 @@ db.exec(`
|
||||
createdBy TEXT,
|
||||
createdAt TEXT NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
updated_at TEXT DEFAULT (datetime('now'))
|
||||
);
|
||||
`);
|
||||
|
||||
// Lightweight migrations for columns added after the initial release.
|
||||
@ -83,4 +89,32 @@ function ensureColumn(table: string, column: string, ddl: string) {
|
||||
|
||||
ensureColumn('devices', 'checkMkUrl', "checkMkUrl TEXT NOT NULL DEFAULT ''");
|
||||
|
||||
// Seed default settings (INSERT OR IGNORE = only if key absent)
|
||||
const _insertDefault = db.prepare('INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)');
|
||||
const _defaultSettings: [string, string][] = [
|
||||
['azure_enabled', 'false'],
|
||||
['azure_client_id', ''],
|
||||
['azure_tenant_id', ''],
|
||||
['azure_client_secret', ''],
|
||||
['azure_redirect_uri', ''],
|
||||
['checkmk_api_url', ''],
|
||||
['checkmk_api_secret', ''],
|
||||
['checkmk_sync_interval_ms', '60000'],
|
||||
];
|
||||
for (const [k, v] of _defaultSettings) _insertDefault.run(k, v);
|
||||
|
||||
export function getSetting(key: string): string {
|
||||
const row = db.prepare('SELECT value FROM settings WHERE key = ?').get(key) as { value: string } | undefined;
|
||||
return row?.value ?? '';
|
||||
}
|
||||
|
||||
export function setSetting(key: string, value: string): void {
|
||||
db.prepare("INSERT OR REPLACE INTO settings (key, value, updated_at) VALUES (?, ?, datetime('now'))").run(key, value);
|
||||
}
|
||||
|
||||
export function getAllSettings(): Record<string, string> {
|
||||
const rows = db.prepare('SELECT key, value FROM settings').all() as { key: string; value: string }[];
|
||||
return Object.fromEntries(rows.map(r => [r.key, r.value]));
|
||||
}
|
||||
|
||||
export default db;
|
||||
|
||||
Reference in New Issue
Block a user