Secure PHP + JS layer connecting page-builder and pb_admin to the SQLite database system managed by the C db-browser tool.
| File | Purpose |
|---|---|
connection.php |
PDO factory — WAL/cache/mmap settings matching the C layer |
query_guard.php |
Allowlist dispatcher — no raw SQL from clients, ever |
api.php |
Central HTTP endpoint (POST JSON) |
db-client.js |
Browser ES module — DbClient class + factory helpers |
schema/pages.sql |
Pages database schema (WAL, history trigger) |
setup.sh |
One-shot database initialiser |
| Caller | Auth method |
|---|---|
| pb_admin front-end | xcm_auth session cookie (set by pb_admin/auth.php) |
| page-builder front-end | Bearer <stage-token> from .stage-token file OR xcm_auth session |
Admin actions (admin.*) |
xcm_auth session only — stage-token is NOT accepted |
| Action | Params | Returns |
|---|---|---|
pages.list |
limit, offset |
Array of page rows |
pages.get |
slug |
Single page row |
pages.upsert |
slug, title, status, css_overrides (JSON), meta (JSON) |
{affected, slug} |
pages.history |
slug, limit |
Array of history rows |
pages.delete |
slug |
{affected} |
| Action | Params | Returns |
|---|---|---|
admin.db_list |
— | All workspace .db files |
admin.table_list |
— | Tables in selected db |
admin.table_read |
table, limit, offset |
Rows |
admin.table_count |
table |
{table, count} |
<meta name="stage-token" content="<?php echo htmlspecialchars(trim(file_get_contents(__DIR__.'/.stage-token'))); ?>">
<script type="module">
import { getPageBuilderClient } from '/db_bridge/db-client.js';
const db = getPageBuilderClient();
const { ok, data } = await db.listPages(20);
if (ok) console.log(data);
</script>import { getAdminClient } from '/db_bridge/db-client.js';
const db = getAdminClient();
const { ok, data } = await db.listTables();require_once __DIR__ . '/../db_bridge/connection.php';
require_once __DIR__ . '/../db_bridge/query_guard.php';
$pdo = db_connect(db_resolve_path('dev-tools/db-browser/databases/pages'));
$result = db_dispatch('pages.list', ['limit' => 10], $pdo);The pages database lives at:
dev-tools/db-browser/databases/pages.db
Re-initialise (preserves existing data via IF NOT EXISTS):
bash db_bridge/setup.shForce rebuild (destructive):
bash db_bridge/setup.sh --force- All client input passes through typed guard functions in
query_guard.phpbefore ever touching a query. - Table/column identifiers are validated against
sqlite_masterbefore interpolation — no dynamic SQL from untrusted strings. - JSON fields are decoded and re-encoded to strip any injected content.
- Stage-token comparison uses
hash_equals()to prevent timing attacks. - The
db_resolve_path()function rejects..traversal and enforces that all resolved paths remain under the workspace root.