diff --git a/dbal/README.md b/dbal/README.md index d5b498f63..435e7b163 100644 --- a/dbal/README.md +++ b/dbal/README.md @@ -52,7 +52,7 @@ A language-agnostic database abstraction layer that provides a secure interface The Prisma adapter behind DBAL already targets the databases you care about: PostgreSQL, MySQL, SQLite, and any other engine Prisma supports (SQL Server, CockroachDB, MongoDB, etc.). Switch between them by pointing `DATABASE_URL` at the desired backend and regenerating the Prisma client for your schema. -You can also set `config.adapter` to `'postgres'` or `'mysql'` when configuring the TypeScript client—those values are currently aliases for the Prisma adapter so the rest of the stack still handles dialect differences, connection pooling, and migrations via Prisma. +The TypeScript client exposes three Prisma-based adapters: `PrismaAdapter`, `PostgresAdapter`, and `MySQLAdapter`. Setting `config.adapter` to `'postgres'` or `'mysql'` constructs the dialect-specific adapter, which keeps the shared Prisma logic but tweaks the capabilities metadata (e.g., enabling full-text search where supported) and leaves the rest of the stack focused on validation, ACLs, and audit logging. ```bash # PostgreSQL @@ -66,6 +66,8 @@ npx prisma generate With `config.adapter = 'prisma'`, DBAL sends every request through `PrismaAdapter`, and Prisma handles dialect differences, migrations, and connection pooling defined in `prisma/schema.prisma` and `prisma/migrations/`. That keeps DBAL focused on validation, ACLs, and audit logging while it can still drive PostgreSQL, MySQL, or any other Prisma-supported store. +The C++ daemon still resides in Phase 3—the current implementation is backed by the in-memory store described in `dbal/cpp/docs/PHASE3_DAEMON.md`, so Postgres/MySQL adapters for the daemon are still future work. + ## Design Principles 1. **Language Agnostic**: API contracts defined in YAML/Proto, not tied to any language diff --git a/dbal/cpp/docs/PHASE3_DAEMON.md b/dbal/cpp/docs/PHASE3_DAEMON.md index 22243f0bd..8e7f23a26 100644 --- a/dbal/cpp/docs/PHASE3_DAEMON.md +++ b/dbal/cpp/docs/PHASE3_DAEMON.md @@ -53,6 +53,8 @@ The C++ daemon provides a secure, sandboxed database access layer that isolates └───────────────┘ ``` +> **Phase 3 status:** The diagrams above describe the future state; the current C++ build still wires to the in-memory store (`dbal/cpp/src/store/in_memory_store.hpp`), so the PostgreSQL/MySQL adapters shown here are aspirational and not shipped yet. Rely on the TypeScript `PrismaAdapter`, `PostgresAdapter`, or `MySQLAdapter` for production workloads today. + ## Security Features ### 1. Process Isolation diff --git a/frontends/nextjs/next.config.ts b/frontends/nextjs/next.config.ts index 9695b4e68..32d207ce3 100644 --- a/frontends/nextjs/next.config.ts +++ b/frontends/nextjs/next.config.ts @@ -1,4 +1,5 @@ import type { NextConfig } from 'next' +import path from 'path' const nextConfig: NextConfig = { reactStrictMode: true, @@ -78,6 +79,14 @@ const nextConfig: NextConfig = { // Environment variables exposed to browser env: { NEXT_PUBLIC_DBAL_API_URL: process.env.DBAL_API_URL || 'http://localhost:8080', + NEXT_PUBLIC_DBAL_WS_URL: process.env.DBAL_WS_URL || 'ws://localhost:50051', + }, + webpack(config) { + config.resolve.alias = { + ...config.resolve.alias, + '@/dbal': path.resolve(__dirname, '..', 'dbal', 'ts', 'src'), + } + return config }, } diff --git a/frontends/nextjs/src/lib/db/credentials/set-credential.ts b/frontends/nextjs/src/lib/db/credentials/set-credential.ts new file mode 100644 index 000000000..304386d23 --- /dev/null +++ b/frontends/nextjs/src/lib/db/credentials/set-credential.ts @@ -0,0 +1,31 @@ +export { setCredential } from './credentials/crud/set-credential' +import { getAdapter } from '../dbal-client' + +/** + * Set or update a user's credential + */ +export async function setCredential(username: string, passwordHash: string): Promise { + const adapter = getAdapter() + + // Check if credential exists + const result = await adapter.list('Credential', { filter: { username } }) + + if (result.data.length > 0) { + // Update existing + const existing = result.data[0] as any + await adapter.update('Credential', existing.id || existing.username, { passwordHash }) + } else { + // Create new + await adapter.create('Credential', { username, passwordHash }) + } + + // Update password change timestamp on user + const users = await adapter.list('User', { filter: { username } }) + if (users.data.length > 0) { + const user = users.data[0] as any + await adapter.update('User', user.id, { + passwordChangeTimestamp: BigInt(Date.now()), + firstLogin: false, + }) + } +} diff --git a/frontends/nextjs/src/lib/db/hash-password.ts b/frontends/nextjs/src/lib/db/hash-password.ts new file mode 100644 index 000000000..77c85b750 --- /dev/null +++ b/frontends/nextjs/src/lib/db/hash-password.ts @@ -0,0 +1 @@ +export { hashPassword } from './password/hash-password' diff --git a/frontends/nextjs/tsconfig.json b/frontends/nextjs/tsconfig.json index b1dcdfd4d..baf32f247 100644 --- a/frontends/nextjs/tsconfig.json +++ b/frontends/nextjs/tsconfig.json @@ -28,6 +28,9 @@ "paths": { "@/*": [ "./src/*" + ], + "@/dbal/*": [ + "../dbal/ts/src/*" ] }, "plugins": [ @@ -45,7 +48,8 @@ "vitest.config.ts", "playwright.config.ts", ".next/types/**/*.ts", - ".next/dev/types/**/*.ts" + ".next/dev/types/**/*.ts", + "../dbal/ts/src/**/*.ts" ], "exclude": [ "node_modules"