@amerged/ohmyhost-runtime 0.1.29 → 0.1.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/database-kysely.d.ts +3 -1
- package/dist/database-kysely.d.ts.map +1 -1
- package/dist/database-kysely.js +60 -0
- package/dist/database-kysely.js.map +1 -1
- package/dist/database-rls.d.ts +12 -0
- package/dist/database-rls.d.ts.map +1 -0
- package/dist/database-rls.js +109 -0
- package/dist/database-rls.js.map +1 -0
- package/dist/database.d.ts +13 -0
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +113 -3
- package/dist/database.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/package.json +5 -1
- package/src/packages/customer-runtime/package.json +6 -1
- package/src/packages/customer-runtime/src/database-kysely.ts +67 -0
- package/src/packages/customer-runtime/src/database-rls.ts +134 -0
- package/src/packages/customer-runtime/src/database.ts +137 -2
- package/src/packages/customer-runtime/src/errors.ts +3 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type Dialect } from "kysely";
|
|
2
|
-
import { type CustomerDatabaseBinding } from "./database.js";
|
|
2
|
+
import { type CustomerDatabaseBinding, type CustomerDatabaseRlsTransaction } from "./database.js";
|
|
3
|
+
/** Compile Kysely queries inside an already-open withRls callback. The callback owns completion. */
|
|
4
|
+
export declare function createRlsTransactionDialect(transaction: CustomerDatabaseRlsTransaction): Dialect;
|
|
3
5
|
/** Kysely 0.29.5's PostgreSQL compiler and transactions over the private RPC binding. */
|
|
4
6
|
export declare function createPrivateDatabaseDialect(binding: CustomerDatabaseBinding): Dialect;
|
|
5
7
|
//# sourceMappingURL=database-kysely.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database-kysely.d.ts","sourceRoot":"","sources":["../src/database-kysely.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,OAAO,EAKb,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAEL,KAAK,uBAAuB,
|
|
1
|
+
{"version":3,"file":"database-kysely.d.ts","sourceRoot":"","sources":["../src/database-kysely.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,OAAO,EAKb,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAEL,KAAK,uBAAuB,EAG5B,KAAK,8BAA8B,EACpC,MAAM,eAAe,CAAC;AAOvB,oGAAoG;AACpG,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,8BAA8B,GAAG,OAAO,CAOhG;AA0DD,yFAAyF;AACzF,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAQtF"}
|
package/dist/database-kysely.js
CHANGED
|
@@ -1,5 +1,65 @@
|
|
|
1
1
|
import { PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler, CompiledQuery, } from "kysely";
|
|
2
2
|
import { createPrivateDatabaseClient, } from "./database.js";
|
|
3
|
+
/** Compile Kysely queries inside an already-open withRls callback. The callback owns completion. */
|
|
4
|
+
export function createRlsTransactionDialect(transaction) {
|
|
5
|
+
return Object.freeze({
|
|
6
|
+
createAdapter: () => new PostgresAdapter(),
|
|
7
|
+
createQueryCompiler: () => new PostgresQueryCompiler(),
|
|
8
|
+
createIntrospector: (kysely) => new PostgresIntrospector(kysely),
|
|
9
|
+
createDriver: () => new RlsTransactionDriver(transaction),
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
class RlsTransactionDriver {
|
|
13
|
+
transaction;
|
|
14
|
+
#connections = new Set();
|
|
15
|
+
#destroyed = false;
|
|
16
|
+
async init() { }
|
|
17
|
+
async acquireConnection() {
|
|
18
|
+
if (this.#destroyed)
|
|
19
|
+
throw new TypeError("The RLS database dialect is destroyed");
|
|
20
|
+
const connection = Object.freeze({
|
|
21
|
+
executeQuery: async (query) => {
|
|
22
|
+
if (!this.#connections.has(connection))
|
|
23
|
+
throw new TypeError("The RLS database connection is released");
|
|
24
|
+
const result = await this.transaction.query({
|
|
25
|
+
text: query.sql,
|
|
26
|
+
values: query.parameters,
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
rows: [...result.rows],
|
|
30
|
+
...(["INSERT", "UPDATE", "DELETE", "MERGE"].includes(result.command) &&
|
|
31
|
+
result.rowCount !== null
|
|
32
|
+
? { numAffectedRows: BigInt(result.rowCount) }
|
|
33
|
+
: {}),
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
streamQuery() {
|
|
37
|
+
throw new TypeError("RLS database streaming is not supported");
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
this.#connections.add(connection);
|
|
41
|
+
return connection;
|
|
42
|
+
}
|
|
43
|
+
async beginTransaction() {
|
|
44
|
+
throw new TypeError("RLS transaction lifecycle belongs to withRls");
|
|
45
|
+
}
|
|
46
|
+
async commitTransaction() {
|
|
47
|
+
throw new TypeError("RLS transaction lifecycle belongs to withRls");
|
|
48
|
+
}
|
|
49
|
+
async rollbackTransaction() {
|
|
50
|
+
throw new TypeError("RLS transaction lifecycle belongs to withRls");
|
|
51
|
+
}
|
|
52
|
+
async releaseConnection(connection) {
|
|
53
|
+
this.#connections.delete(connection);
|
|
54
|
+
}
|
|
55
|
+
async destroy() {
|
|
56
|
+
this.#destroyed = true;
|
|
57
|
+
this.#connections.clear();
|
|
58
|
+
}
|
|
59
|
+
constructor(transaction) {
|
|
60
|
+
this.transaction = transaction;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
3
63
|
/** Kysely 0.29.5's PostgreSQL compiler and transactions over the private RPC binding. */
|
|
4
64
|
export function createPrivateDatabaseDialect(binding) {
|
|
5
65
|
const database = createPrivateDatabaseClient(binding);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database-kysely.js","sourceRoot":"","sources":["../src/database-kysely.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,GAOd,MAAM,QAAQ,CAAC;AAEhB,OAAO,EACL,2BAA2B,
|
|
1
|
+
{"version":3,"file":"database-kysely.js","sourceRoot":"","sources":["../src/database-kysely.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CustomerDatabaseJson } from "./database.js";
|
|
2
|
+
export interface CustomerDatabaseRlsIdentity {
|
|
3
|
+
readonly subject: string;
|
|
4
|
+
readonly claims?: Readonly<Record<string, CustomerDatabaseJson>>;
|
|
5
|
+
}
|
|
6
|
+
export type CustomerDatabaseRlsClaims = Readonly<Record<string, CustomerDatabaseJson>> & {
|
|
7
|
+
readonly sub: string | null;
|
|
8
|
+
readonly role: "authenticated" | "anon";
|
|
9
|
+
};
|
|
10
|
+
/** Shared SDK/service validation. Identity is asserted by the trusted application backend. */
|
|
11
|
+
export declare function normalizeRlsIdentity(input: unknown): CustomerDatabaseRlsClaims;
|
|
12
|
+
//# sourceMappingURL=database-rls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-rls.d.ts","sourceRoot":"","sources":["../src/database-rls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC;CAClE;AAED,MAAM,MAAM,yBAAyB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,GAAG;IACvF,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAAC;CACzC,CAAC;AAEF,8FAA8F;AAC9F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,yBAAyB,CA+B9E"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/** Shared SDK/service validation. Identity is asserted by the trusted application backend. */
|
|
2
|
+
export function normalizeRlsIdentity(input) {
|
|
3
|
+
let subject = null;
|
|
4
|
+
const document = {};
|
|
5
|
+
if (input !== null) {
|
|
6
|
+
const identity = plainProperties(input);
|
|
7
|
+
if (Object.keys(identity).sort().join(",") !== "subject" &&
|
|
8
|
+
Object.keys(identity).sort().join(",") !== "claims,subject")
|
|
9
|
+
invalidIdentity();
|
|
10
|
+
const value = identity["subject"]?.value;
|
|
11
|
+
if (typeof value !== "string" ||
|
|
12
|
+
value.length === 0 ||
|
|
13
|
+
new TextEncoder().encode(value).byteLength > 512 ||
|
|
14
|
+
/\p{Cc}/u.test(value))
|
|
15
|
+
invalidIdentity();
|
|
16
|
+
subject = value;
|
|
17
|
+
if (Object.hasOwn(identity, "claims")) {
|
|
18
|
+
const claims = plainProperties(identity["claims"]?.value);
|
|
19
|
+
for (const [key, descriptor] of Object.entries(claims)) {
|
|
20
|
+
if (key === "sub" || key === "role")
|
|
21
|
+
invalidIdentity();
|
|
22
|
+
validateKey(key);
|
|
23
|
+
document[key] = descriptor.value;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
document["sub"] = subject;
|
|
28
|
+
document["role"] = subject === null ? "anon" : "authenticated";
|
|
29
|
+
return cloneJson(document, { nodes: 0, bytes: 0 }, 0);
|
|
30
|
+
}
|
|
31
|
+
function cloneJson(value, budget, depth) {
|
|
32
|
+
budget.nodes += 1;
|
|
33
|
+
if (budget.nodes > 1_000 || depth > 8)
|
|
34
|
+
invalidIdentity();
|
|
35
|
+
if (value === null ||
|
|
36
|
+
typeof value === "boolean" ||
|
|
37
|
+
typeof value === "string" ||
|
|
38
|
+
typeof value === "number") {
|
|
39
|
+
if (typeof value === "number" && !Number.isFinite(value))
|
|
40
|
+
invalidIdentity();
|
|
41
|
+
if (typeof value === "string")
|
|
42
|
+
validateJsonString(value);
|
|
43
|
+
consume(budget, JSON.stringify(value));
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
if (Object.getPrototypeOf(value) !== Array.prototype ||
|
|
48
|
+
Object.getOwnPropertySymbols(value).length !== 0 ||
|
|
49
|
+
Object.getOwnPropertyNames(value).length !== value.length + 1)
|
|
50
|
+
invalidIdentity();
|
|
51
|
+
consume(budget, "[]");
|
|
52
|
+
const output = [];
|
|
53
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
54
|
+
const property = Object.getOwnPropertyDescriptor(value, String(index));
|
|
55
|
+
if (property === undefined || !Object.hasOwn(property, "value") || !property.enumerable)
|
|
56
|
+
invalidIdentity();
|
|
57
|
+
if (index > 0)
|
|
58
|
+
consume(budget, ",");
|
|
59
|
+
output.push(cloneJson(property.value, budget, depth + 1));
|
|
60
|
+
}
|
|
61
|
+
return Object.freeze(output);
|
|
62
|
+
}
|
|
63
|
+
const properties = plainProperties(value);
|
|
64
|
+
consume(budget, "{}");
|
|
65
|
+
const output = {};
|
|
66
|
+
for (const [index, [key, property]] of Object.entries(properties).entries()) {
|
|
67
|
+
validateKey(key);
|
|
68
|
+
consume(budget, `${index > 0 ? "," : ""}${JSON.stringify(key)}:`);
|
|
69
|
+
output[key] = cloneJson(property.value, budget, depth + 1);
|
|
70
|
+
}
|
|
71
|
+
return Object.freeze(output);
|
|
72
|
+
}
|
|
73
|
+
function plainProperties(value) {
|
|
74
|
+
if (typeof value !== "object" ||
|
|
75
|
+
value === null ||
|
|
76
|
+
Object.getPrototypeOf(value) !== Object.prototype ||
|
|
77
|
+
Object.getOwnPropertySymbols(value).length !== 0)
|
|
78
|
+
invalidIdentity();
|
|
79
|
+
const properties = Object.getOwnPropertyDescriptors(value);
|
|
80
|
+
for (const property of Object.values(properties)) {
|
|
81
|
+
if (!Object.hasOwn(property, "value") || !property.enumerable)
|
|
82
|
+
invalidIdentity();
|
|
83
|
+
}
|
|
84
|
+
return properties;
|
|
85
|
+
}
|
|
86
|
+
function validateKey(key) {
|
|
87
|
+
validateJsonString(key);
|
|
88
|
+
if (key.length === 0 ||
|
|
89
|
+
new TextEncoder().encode(key).byteLength > 128 ||
|
|
90
|
+
/\p{Cc}/u.test(key) ||
|
|
91
|
+
key === "__proto__" ||
|
|
92
|
+
key === "constructor" ||
|
|
93
|
+
key === "prototype")
|
|
94
|
+
invalidIdentity();
|
|
95
|
+
}
|
|
96
|
+
function validateJsonString(value) {
|
|
97
|
+
// PostgreSQL jsonb rejects NUL and lone UTF-16 surrogates even when JSON.stringify escapes them.
|
|
98
|
+
if (!value.isWellFormed() || value.includes("\u0000"))
|
|
99
|
+
invalidIdentity();
|
|
100
|
+
}
|
|
101
|
+
function consume(budget, text) {
|
|
102
|
+
budget.bytes += new TextEncoder().encode(text).byteLength;
|
|
103
|
+
if (budget.bytes > 16 * 1024)
|
|
104
|
+
invalidIdentity();
|
|
105
|
+
}
|
|
106
|
+
function invalidIdentity() {
|
|
107
|
+
throw new TypeError("Invalid database RLS identity");
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=database-rls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-rls.js","sourceRoot":"","sources":["../src/database-rls.ts"],"names":[],"mappings":"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"}
|
package/dist/database.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type CustomerDatabaseRlsIdentity } from "./database-rls.js";
|
|
2
|
+
export type { CustomerDatabaseRlsIdentity } from "./database-rls.js";
|
|
1
3
|
export type CustomerDatabaseJson = string | number | boolean | null | readonly CustomerDatabaseJson[] | Readonly<{
|
|
2
4
|
[key: string]: CustomerDatabaseJson;
|
|
3
5
|
}>;
|
|
@@ -15,6 +17,15 @@ export interface CustomerDatabaseBinding {
|
|
|
15
17
|
query(input: unknown): Promise<unknown>;
|
|
16
18
|
transaction(input: unknown): Promise<unknown>;
|
|
17
19
|
open?(): Promise<CustomerDatabaseConnectionStub>;
|
|
20
|
+
openRls?(identity: CustomerDatabaseRlsIdentity | null): Promise<CustomerDatabaseRlsConnectionStub>;
|
|
21
|
+
}
|
|
22
|
+
/** Private lifecycle RPC. Only query is exposed to the application callback. */
|
|
23
|
+
export interface CustomerDatabaseRlsConnectionStub extends CustomerDatabaseConnectionStub {
|
|
24
|
+
commit(): Promise<unknown>;
|
|
25
|
+
}
|
|
26
|
+
/** An existing identity-scoped transaction owned by withRls. */
|
|
27
|
+
export interface CustomerDatabaseRlsTransaction {
|
|
28
|
+
query(input: CustomerDatabaseQuery): Promise<CustomerDatabaseQueryResult>;
|
|
18
29
|
}
|
|
19
30
|
/** The server-side held connection, reached through a stub. Never handed to customer code raw. */
|
|
20
31
|
export interface CustomerDatabaseConnectionStub {
|
|
@@ -26,6 +37,8 @@ export interface CustomerDatabaseConnection {
|
|
|
26
37
|
query(input: CustomerDatabaseQuery): Promise<CustomerDatabaseQueryResult>;
|
|
27
38
|
}
|
|
28
39
|
export interface CustomerDatabaseClient {
|
|
40
|
+
/** Authenticate in application code first; null explicitly selects anonymous policies. */
|
|
41
|
+
withRls<Result>(identity: CustomerDatabaseRlsIdentity | null, run: (transaction: CustomerDatabaseRlsTransaction) => Promise<Result>): Promise<Result>;
|
|
29
42
|
/**
|
|
30
43
|
* Run a read, a decision and a write on one connection. The callback shape is deliberate: the
|
|
31
44
|
* connection is always released, including when the callback throws, so a customer cannot leak
|
package/dist/database.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAE3F,YAAY,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAarE,MAAM,MAAM,oBAAoB,GAC5B,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,oBAAoB,EAAE,GAC/B,QAAQ,CAAC;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAAA;CAAE,CAAC,CAAC;AAEtD,MAAM,MAAM,yBAAyB,GAAG,oBAAoB,GAAG,IAAI,GAAG,UAAU,CAAC;AAEjF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IAC5D,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI,OAAO,CAAC,8BAA8B,CAAC,CAAC;IACjD,OAAO,CAAC,CACN,QAAQ,EAAE,2BAA2B,GAAG,IAAI,GAC3C,OAAO,CAAC,iCAAiC,CAAC,CAAC;CAC/C;AAED,gFAAgF;AAChF,MAAM,WAAW,iCAAkC,SAAQ,8BAA8B;IACvF,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5B;AAED,gEAAgE;AAChE,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;CAC3E;AAED,kGAAkG;AAClG,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,iGAAiG;AACjG,MAAM,WAAW,0BAA0B;IACzC,KAAK,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;CAC3E;AAED,MAAM,WAAW,sBAAsB;IACrC,0FAA0F;IAC1F,OAAO,CAAC,MAAM,EACZ,QAAQ,EAAE,2BAA2B,GAAG,IAAI,EAC5C,GAAG,EAAE,CAAC,WAAW,EAAE,8BAA8B,KAAK,OAAO,CAAC,MAAM,CAAC,GACpE,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB;;;;OAIG;IACH,cAAc,CAAC,MAAM,EACnB,GAAG,EAAE,CAAC,UAAU,EAAE,0BAA0B,KAAK,OAAO,CAAC,MAAM,CAAC,GAC/D,OAAO,CAAC,MAAM,CAAC,CAAC;IACnB,KAAK,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAC1E,WAAW,CACT,OAAO,EAAE,SAAS,qBAAqB,EAAE,GACxC,OAAO,CAAC,SAAS,2BAA2B,EAAE,CAAC,CAAC;CACpD;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,uBAAuB,GAC/B,sBAAsB,CA2ExB"}
|
package/dist/database.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CustomerDatabaseError, CustomerRuntimeError } from "./errors.js";
|
|
2
|
+
import { normalizeRlsIdentity } from "./database-rls.js";
|
|
2
3
|
const MAX_QUERY_BYTES = 64 * 1024;
|
|
3
4
|
const MAX_PARAMETERS = 100;
|
|
4
5
|
const MAX_PARAMETER_BYTES = 1024 * 1024;
|
|
@@ -17,6 +18,9 @@ export function createPrivateDatabaseClient(binding) {
|
|
|
17
18
|
throw new CustomerRuntimeError("database_binding_missing", false, "pass the OHMYHOST_DATABASE binding from the Worker env (Next.js: getCloudflareContext({ async: true }).env), not process.env. It exists only in server code of a deployment whose ohmyhost.yaml sets database.enabled: true.");
|
|
18
19
|
}
|
|
19
20
|
return Object.freeze({
|
|
21
|
+
withRls(identity, run) {
|
|
22
|
+
return runRlsTransaction(binding, identity, run);
|
|
23
|
+
},
|
|
20
24
|
async withConnection(run) {
|
|
21
25
|
if (typeof binding.open !== "function")
|
|
22
26
|
throw unavailable();
|
|
@@ -76,6 +80,111 @@ export function createPrivateDatabaseClient(binding) {
|
|
|
76
80
|
},
|
|
77
81
|
});
|
|
78
82
|
}
|
|
83
|
+
async function runRlsTransaction(binding, identity, run) {
|
|
84
|
+
let wireIdentity;
|
|
85
|
+
try {
|
|
86
|
+
const normalized = normalizeRlsIdentity(identity);
|
|
87
|
+
const sub = normalized.sub;
|
|
88
|
+
const claims = { ...normalized };
|
|
89
|
+
delete claims["sub"];
|
|
90
|
+
delete claims["role"];
|
|
91
|
+
wireIdentity = sub === null ? null : { subject: sub, claims };
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
throw new CustomerRuntimeError("database_rls_identity_invalid", false);
|
|
95
|
+
}
|
|
96
|
+
if (typeof binding.openRls !== "function")
|
|
97
|
+
throw unavailable();
|
|
98
|
+
let stub;
|
|
99
|
+
try {
|
|
100
|
+
stub = await binding.openRls(wireIdentity);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
throw unavailable();
|
|
104
|
+
}
|
|
105
|
+
let state = "active";
|
|
106
|
+
let poisoned = false;
|
|
107
|
+
let pending = Promise.resolve();
|
|
108
|
+
const transaction = Object.freeze({
|
|
109
|
+
query(input) {
|
|
110
|
+
// Validate and snapshot immediately, before the caller can change a queued query.
|
|
111
|
+
let parsed;
|
|
112
|
+
try {
|
|
113
|
+
if (state !== "active" || poisoned)
|
|
114
|
+
throw rlsTransactionFailed();
|
|
115
|
+
parsed = validateQuery(input, undefined, false, true);
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
if (state === "active")
|
|
119
|
+
poisoned = true;
|
|
120
|
+
const failed = Promise.reject(error);
|
|
121
|
+
// A fire-and-forget query must still roll the scope back without an unhandled rejection.
|
|
122
|
+
void failed.catch(() => undefined);
|
|
123
|
+
return failed;
|
|
124
|
+
}
|
|
125
|
+
const operation = pending.then(async () => {
|
|
126
|
+
if (poisoned)
|
|
127
|
+
throw rlsTransactionFailed();
|
|
128
|
+
let raw;
|
|
129
|
+
try {
|
|
130
|
+
raw = await stub.query(parsed);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
throw unavailable();
|
|
134
|
+
}
|
|
135
|
+
throwRlsFailure(raw);
|
|
136
|
+
throwStatementFailure(raw);
|
|
137
|
+
return validateResult(raw);
|
|
138
|
+
});
|
|
139
|
+
pending = operation.then(() => undefined, () => {
|
|
140
|
+
poisoned = true;
|
|
141
|
+
});
|
|
142
|
+
return operation;
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
try {
|
|
146
|
+
const result = await run(transaction);
|
|
147
|
+
state = "closing";
|
|
148
|
+
await pending;
|
|
149
|
+
if (poisoned)
|
|
150
|
+
throw rlsTransactionFailed();
|
|
151
|
+
let committed;
|
|
152
|
+
try {
|
|
153
|
+
committed = await stub.commit();
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
throw new CustomerRuntimeError("database_transaction_outcome_unknown", false);
|
|
157
|
+
}
|
|
158
|
+
throwRlsFailure(committed, true);
|
|
159
|
+
if (!isRecord(committed) ||
|
|
160
|
+
Object.keys(committed).join(",") !== "type" ||
|
|
161
|
+
committed["type"] !== "ohmyhost.database-rls-commit/v1") {
|
|
162
|
+
throw new CustomerRuntimeError("database_transaction_outcome_unknown", false);
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
state = "closing";
|
|
168
|
+
await pending;
|
|
169
|
+
state = "closed";
|
|
170
|
+
await stub.close().catch(() => undefined);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function rlsTransactionFailed() {
|
|
174
|
+
return new CustomerRuntimeError("database_rls_transaction_failed", false);
|
|
175
|
+
}
|
|
176
|
+
function throwRlsFailure(value, duringCommit = false) {
|
|
177
|
+
if (!isRecord(value) || value["type"] !== "ohmyhost.database-rls-error/v1")
|
|
178
|
+
return;
|
|
179
|
+
const code = value["code"];
|
|
180
|
+
if (Object.keys(value).sort().join(",") !== "code,type" ||
|
|
181
|
+
(code !== "database_rls_transaction_failed" && code !== "database_transaction_outcome_unknown")) {
|
|
182
|
+
if (duringCommit)
|
|
183
|
+
throw new CustomerRuntimeError("database_transaction_outcome_unknown", false);
|
|
184
|
+
invalidResponse();
|
|
185
|
+
}
|
|
186
|
+
throw new CustomerRuntimeError(code, false);
|
|
187
|
+
}
|
|
79
188
|
function throwStatementFailure(value) {
|
|
80
189
|
if (!isRecord(value) || value["type"] !== "ohmyhost.database-error/v1")
|
|
81
190
|
return;
|
|
@@ -86,7 +195,7 @@ function throwStatementFailure(value) {
|
|
|
86
195
|
invalidResponse();
|
|
87
196
|
throw new CustomerDatabaseError(sqlstate);
|
|
88
197
|
}
|
|
89
|
-
function validateQuery(value, aggregateBudget, inConnection = false) {
|
|
198
|
+
function validateQuery(value, aggregateBudget, inConnection = false, inRls = false) {
|
|
90
199
|
if (!isRecord(value) || Object.keys(value).sort().join(",") !== "text,values")
|
|
91
200
|
invalidQuery();
|
|
92
201
|
const text = value["text"];
|
|
@@ -98,7 +207,7 @@ function validateQuery(value, aggregateBudget, inConnection = false) {
|
|
|
98
207
|
values.length > MAX_PARAMETERS) {
|
|
99
208
|
invalidQuery();
|
|
100
209
|
}
|
|
101
|
-
validateSql(text, inConnection);
|
|
210
|
+
validateSql(text, inConnection, inRls);
|
|
102
211
|
const budget = aggregateBudget ?? { nodes: 1, bytes: 2 };
|
|
103
212
|
const parsedValues = values.map((parameter, index) => {
|
|
104
213
|
if (index > 0)
|
|
@@ -131,7 +240,7 @@ function validateTransaction(value) {
|
|
|
131
240
|
});
|
|
132
241
|
return Object.freeze(queries);
|
|
133
242
|
}
|
|
134
|
-
function validateSql(text, inConnection = false) {
|
|
243
|
+
function validateSql(text, inConnection = false, inRls = false) {
|
|
135
244
|
let visible = "";
|
|
136
245
|
let index = 0;
|
|
137
246
|
while (index < text.length) {
|
|
@@ -201,6 +310,7 @@ function validateSql(text, inConnection = false) {
|
|
|
201
310
|
const statement = statements[0];
|
|
202
311
|
if (statements.length !== 1 ||
|
|
203
312
|
semicolonCount > 1 ||
|
|
313
|
+
(inRls && /^call\b/iu.test(statement)) ||
|
|
204
314
|
(inConnection
|
|
205
315
|
? // Transaction control is the whole point of holding a connection; session-wide state and a
|
|
206
316
|
// chained transaction, which the database Worker refuses among the first six words, are not.
|
package/dist/database.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../src/database.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type CustomerRuntimeGatewayErrorCode = "gateway_configuration_invalid" | "gateway_request_invalid" | "gateway_response_invalid" | "gateway_timeout" | "gateway_unavailable" | "mail_content_expired" | "mail_attachment_too_large" | "mail_message_not_found" | "mail_rejected" | "mail_reputation_suspended" | "mail_send_conflict" | "mail_send_limit_exceeded" | "insufficient_organization_credits" | "paid_plan_required" | "project_budget_exceeded" | "storage_conflict" | "data_change_in_progress" | "storage_binding_data_changed" | "storage_delete_pending" | "storage_object_not_found" | "storage_quota_exceeded" | "storage_upload_expired" | "storage_upload_rejected" | "unauthorized";
|
|
2
|
-
export type CustomerRuntimeErrorCode = CustomerRuntimeGatewayErrorCode | "database_binding_missing" | "database_query_invalid" | "database_response_invalid" | "database_unavailable" | "scheduled_context_invalid";
|
|
2
|
+
export type CustomerRuntimeErrorCode = CustomerRuntimeGatewayErrorCode | "database_binding_missing" | "database_query_invalid" | "database_response_invalid" | "database_rls_identity_invalid" | "database_rls_transaction_failed" | "database_transaction_outcome_unknown" | "database_unavailable" | "scheduled_context_invalid";
|
|
3
3
|
export declare class CustomerRuntimeError extends Error {
|
|
4
4
|
readonly code: CustomerRuntimeErrorCode;
|
|
5
5
|
readonly retryable: boolean;
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,+BAA+B,GACvC,+BAA+B,GAC/B,yBAAyB,GACzB,0BAA0B,GAC1B,iBAAiB,GACjB,qBAAqB,GACrB,sBAAsB,GACtB,2BAA2B,GAC3B,wBAAwB,GACxB,eAAe,GACf,2BAA2B,GAC3B,oBAAoB,GACpB,0BAA0B,GAC1B,mCAAmC,GACnC,oBAAoB,GACpB,yBAAyB,GACzB,kBAAkB,GAClB,yBAAyB,GACzB,8BAA8B,GAC9B,wBAAwB,GACxB,0BAA0B,GAC1B,wBAAwB,GACxB,wBAAwB,GACxB,yBAAyB,GACzB,cAAc,CAAC;AAEnB,MAAM,MAAM,wBAAwB,GAChC,+BAA+B,GAC/B,0BAA0B,GAC1B,wBAAwB,GACxB,2BAA2B,GAC3B,sBAAsB,GACtB,2BAA2B,CAAC;AAEhC,qBAAa,oBAAqB,SAAQ,KAAK;aAG3B,IAAI,EAAE,wBAAwB;aAC9B,SAAS,EAAE,OAAO;IAHpC,gGAAgG;gBAE9E,IAAI,EAAE,wBAAwB,EAC9B,SAAS,EAAE,OAAO,EAClC,MAAM,CAAC,EAAE,MAAM;CAKlB;AAED,gGAAgG;AAChG,qBAAa,qBAAsB,SAAQ,KAAK;aAGX,IAAI,EAAE,MAAM;IAF/C,SAAgB,SAAS,EAAE,OAAO,CAAC;gBAEA,IAAI,EAAE,MAAM;CAMhD;AAED,qBAAa,2BAA4B,SAAQ,oBAAoB;aAGjD,MAAM,EAAE,MAAM,GAAG,IAAI;gBADrC,IAAI,EAAE,+BAA+B,EACrB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrC,SAAS,EAAE,OAAO,EAClB,MAAM,CAAC,EAAE,MAAM;CAKlB"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,+BAA+B,GACvC,+BAA+B,GAC/B,yBAAyB,GACzB,0BAA0B,GAC1B,iBAAiB,GACjB,qBAAqB,GACrB,sBAAsB,GACtB,2BAA2B,GAC3B,wBAAwB,GACxB,eAAe,GACf,2BAA2B,GAC3B,oBAAoB,GACpB,0BAA0B,GAC1B,mCAAmC,GACnC,oBAAoB,GACpB,yBAAyB,GACzB,kBAAkB,GAClB,yBAAyB,GACzB,8BAA8B,GAC9B,wBAAwB,GACxB,0BAA0B,GAC1B,wBAAwB,GACxB,wBAAwB,GACxB,yBAAyB,GACzB,cAAc,CAAC;AAEnB,MAAM,MAAM,wBAAwB,GAChC,+BAA+B,GAC/B,0BAA0B,GAC1B,wBAAwB,GACxB,2BAA2B,GAC3B,+BAA+B,GAC/B,iCAAiC,GACjC,sCAAsC,GACtC,sBAAsB,GACtB,2BAA2B,CAAC;AAEhC,qBAAa,oBAAqB,SAAQ,KAAK;aAG3B,IAAI,EAAE,wBAAwB;aAC9B,SAAS,EAAE,OAAO;IAHpC,gGAAgG;gBAE9E,IAAI,EAAE,wBAAwB,EAC9B,SAAS,EAAE,OAAO,EAClC,MAAM,CAAC,EAAE,MAAM;CAKlB;AAED,gGAAgG;AAChG,qBAAa,qBAAsB,SAAQ,KAAK;aAGX,IAAI,EAAE,MAAM;IAF/C,SAAgB,SAAS,EAAE,OAAO,CAAC;gBAEA,IAAI,EAAE,MAAM;CAMhD;AAED,qBAAa,2BAA4B,SAAQ,oBAAoB;aAGjD,MAAM,EAAE,MAAM,GAAG,IAAI;gBADrC,IAAI,EAAE,+BAA+B,EACrB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrC,SAAS,EAAE,OAAO,EAClB,MAAM,CAAC,EAAE,MAAM;CAKlB"}
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAqCA,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAG3B;IACA;IAHlB,gGAAgG;IAChG,YACkB,IAA8B,EAC9B,SAAkB,EAClC,MAAe;QAEf,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC;QAJ1C,SAAI,GAAJ,IAAI,CAA0B;QAC9B,cAAS,GAAT,SAAS,CAAS;QAIlC,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED,gGAAgG;AAChG,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAGX;IAFnB,SAAS,CAAU;IAEnC,YAAmC,IAAY;QAC7C,KAAK,CAAC,uCAAuC,IAAI,EAAE,CAAC,CAAC;QADpB,SAAI,GAAJ,IAAI,CAAQ;QAE7C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,kBAAkB,CAAC,CAAC;QAC1E,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,CAAC;IACxD,CAAC;CACF;AAED,MAAM,OAAO,2BAA4B,SAAQ,oBAAoB;IAGjD;IAFlB,YACE,IAAqC,EACrB,MAAqB,EACrC,SAAkB,EAClB,MAAe;QAEf,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAJf,WAAM,GAAN,MAAM,CAAe;QAKrC,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amerged/ohmyhost-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22"
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
"types": "./dist/database-kysely.d.ts",
|
|
31
31
|
"import": "./dist/database-kysely.js"
|
|
32
32
|
},
|
|
33
|
+
"./database-rls": {
|
|
34
|
+
"types": "./dist/database-rls.d.ts",
|
|
35
|
+
"import": "./dist/database-rls.js"
|
|
36
|
+
},
|
|
33
37
|
"./storage": {
|
|
34
38
|
"types": "./dist/storage.d.ts",
|
|
35
39
|
"import": "./dist/storage.js"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ohmyhost/customer-runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -25,6 +25,11 @@
|
|
|
25
25
|
"types": "./dist/database-kysely.d.ts",
|
|
26
26
|
"import": "./dist/database-kysely.js"
|
|
27
27
|
},
|
|
28
|
+
"./database-rls": {
|
|
29
|
+
"source": "./src/database-rls.ts",
|
|
30
|
+
"types": "./dist/database-rls.d.ts",
|
|
31
|
+
"import": "./dist/database-rls.js"
|
|
32
|
+
},
|
|
28
33
|
"./storage": {
|
|
29
34
|
"source": "./src/storage.ts",
|
|
30
35
|
"types": "./dist/storage.d.ts",
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
type CustomerDatabaseBinding,
|
|
17
17
|
type CustomerDatabaseClient,
|
|
18
18
|
type CustomerDatabaseParameter,
|
|
19
|
+
type CustomerDatabaseRlsTransaction,
|
|
19
20
|
} from "./database.js";
|
|
20
21
|
|
|
21
22
|
interface Lease {
|
|
@@ -23,6 +24,72 @@ interface Lease {
|
|
|
23
24
|
readonly closed: Promise<void>;
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
/** Compile Kysely queries inside an already-open withRls callback. The callback owns completion. */
|
|
28
|
+
export function createRlsTransactionDialect(transaction: CustomerDatabaseRlsTransaction): Dialect {
|
|
29
|
+
return Object.freeze({
|
|
30
|
+
createAdapter: () => new PostgresAdapter(),
|
|
31
|
+
createQueryCompiler: () => new PostgresQueryCompiler(),
|
|
32
|
+
createIntrospector: (kysely: Kysely<unknown>) => new PostgresIntrospector(kysely),
|
|
33
|
+
createDriver: () => new RlsTransactionDriver(transaction),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class RlsTransactionDriver implements Driver {
|
|
38
|
+
readonly #connections = new Set<DatabaseConnection>();
|
|
39
|
+
#destroyed = false;
|
|
40
|
+
|
|
41
|
+
public async init(): Promise<void> {}
|
|
42
|
+
|
|
43
|
+
public async acquireConnection(): Promise<DatabaseConnection> {
|
|
44
|
+
if (this.#destroyed) throw new TypeError("The RLS database dialect is destroyed");
|
|
45
|
+
const connection: DatabaseConnection = Object.freeze({
|
|
46
|
+
executeQuery: async <Row>(query: CompiledQuery): Promise<QueryResult<Row>> => {
|
|
47
|
+
if (!this.#connections.has(connection))
|
|
48
|
+
throw new TypeError("The RLS database connection is released");
|
|
49
|
+
const result = await this.transaction.query({
|
|
50
|
+
text: query.sql,
|
|
51
|
+
values: query.parameters as readonly CustomerDatabaseParameter[],
|
|
52
|
+
});
|
|
53
|
+
return {
|
|
54
|
+
rows: [...result.rows] as Row[],
|
|
55
|
+
...(["INSERT", "UPDATE", "DELETE", "MERGE"].includes(result.command) &&
|
|
56
|
+
result.rowCount !== null
|
|
57
|
+
? { numAffectedRows: BigInt(result.rowCount) }
|
|
58
|
+
: {}),
|
|
59
|
+
};
|
|
60
|
+
},
|
|
61
|
+
streamQuery<Row>(): AsyncIterableIterator<QueryResult<Row>> {
|
|
62
|
+
throw new TypeError("RLS database streaming is not supported");
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
this.#connections.add(connection);
|
|
66
|
+
return connection;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public async beginTransaction(): Promise<void> {
|
|
70
|
+
throw new TypeError("RLS transaction lifecycle belongs to withRls");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public async commitTransaction(): Promise<void> {
|
|
74
|
+
throw new TypeError("RLS transaction lifecycle belongs to withRls");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public async rollbackTransaction(): Promise<void> {
|
|
78
|
+
throw new TypeError("RLS transaction lifecycle belongs to withRls");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public async releaseConnection(connection: DatabaseConnection): Promise<void> {
|
|
82
|
+
this.#connections.delete(connection);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public async destroy(): Promise<void> {
|
|
86
|
+
this.#destroyed = true;
|
|
87
|
+
this.#connections.clear();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public constructor(private readonly transaction: CustomerDatabaseRlsTransaction) {}
|
|
91
|
+
}
|
|
92
|
+
|
|
26
93
|
/** Kysely 0.29.5's PostgreSQL compiler and transactions over the private RPC binding. */
|
|
27
94
|
export function createPrivateDatabaseDialect(binding: CustomerDatabaseBinding): Dialect {
|
|
28
95
|
const database = createPrivateDatabaseClient(binding);
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { CustomerDatabaseJson } from "./database.js";
|
|
2
|
+
|
|
3
|
+
export interface CustomerDatabaseRlsIdentity {
|
|
4
|
+
readonly subject: string;
|
|
5
|
+
readonly claims?: Readonly<Record<string, CustomerDatabaseJson>>;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type CustomerDatabaseRlsClaims = Readonly<Record<string, CustomerDatabaseJson>> & {
|
|
9
|
+
readonly sub: string | null;
|
|
10
|
+
readonly role: "authenticated" | "anon";
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** Shared SDK/service validation. Identity is asserted by the trusted application backend. */
|
|
14
|
+
export function normalizeRlsIdentity(input: unknown): CustomerDatabaseRlsClaims {
|
|
15
|
+
let subject: string | null = null;
|
|
16
|
+
const document: Record<string, unknown> = {};
|
|
17
|
+
if (input !== null) {
|
|
18
|
+
const identity = plainProperties(input);
|
|
19
|
+
if (
|
|
20
|
+
Object.keys(identity).sort().join(",") !== "subject" &&
|
|
21
|
+
Object.keys(identity).sort().join(",") !== "claims,subject"
|
|
22
|
+
)
|
|
23
|
+
invalidIdentity();
|
|
24
|
+
const value: unknown = identity["subject"]?.value;
|
|
25
|
+
if (
|
|
26
|
+
typeof value !== "string" ||
|
|
27
|
+
value.length === 0 ||
|
|
28
|
+
new TextEncoder().encode(value).byteLength > 512 ||
|
|
29
|
+
/\p{Cc}/u.test(value)
|
|
30
|
+
)
|
|
31
|
+
invalidIdentity();
|
|
32
|
+
subject = value;
|
|
33
|
+
if (Object.hasOwn(identity, "claims")) {
|
|
34
|
+
const claims = plainProperties(identity["claims"]?.value);
|
|
35
|
+
for (const [key, descriptor] of Object.entries(claims)) {
|
|
36
|
+
if (key === "sub" || key === "role") invalidIdentity();
|
|
37
|
+
validateKey(key);
|
|
38
|
+
document[key] = descriptor.value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
document["sub"] = subject;
|
|
43
|
+
document["role"] = subject === null ? "anon" : "authenticated";
|
|
44
|
+
return cloneJson(document, { nodes: 0, bytes: 0 }, 0) as CustomerDatabaseRlsClaims;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function cloneJson(
|
|
48
|
+
value: unknown,
|
|
49
|
+
budget: { nodes: number; bytes: number },
|
|
50
|
+
depth: number,
|
|
51
|
+
): CustomerDatabaseJson {
|
|
52
|
+
budget.nodes += 1;
|
|
53
|
+
if (budget.nodes > 1_000 || depth > 8) invalidIdentity();
|
|
54
|
+
if (
|
|
55
|
+
value === null ||
|
|
56
|
+
typeof value === "boolean" ||
|
|
57
|
+
typeof value === "string" ||
|
|
58
|
+
typeof value === "number"
|
|
59
|
+
) {
|
|
60
|
+
if (typeof value === "number" && !Number.isFinite(value)) invalidIdentity();
|
|
61
|
+
if (typeof value === "string") validateJsonString(value);
|
|
62
|
+
consume(budget, JSON.stringify(value));
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
if (
|
|
67
|
+
Object.getPrototypeOf(value) !== Array.prototype ||
|
|
68
|
+
Object.getOwnPropertySymbols(value).length !== 0 ||
|
|
69
|
+
Object.getOwnPropertyNames(value).length !== value.length + 1
|
|
70
|
+
)
|
|
71
|
+
invalidIdentity();
|
|
72
|
+
consume(budget, "[]");
|
|
73
|
+
const output: CustomerDatabaseJson[] = [];
|
|
74
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
75
|
+
const property = Object.getOwnPropertyDescriptor(value, String(index));
|
|
76
|
+
if (property === undefined || !Object.hasOwn(property, "value") || !property.enumerable)
|
|
77
|
+
invalidIdentity();
|
|
78
|
+
if (index > 0) consume(budget, ",");
|
|
79
|
+
output.push(cloneJson(property.value, budget, depth + 1));
|
|
80
|
+
}
|
|
81
|
+
return Object.freeze(output);
|
|
82
|
+
}
|
|
83
|
+
const properties = plainProperties(value);
|
|
84
|
+
consume(budget, "{}");
|
|
85
|
+
const output: Record<string, CustomerDatabaseJson> = {};
|
|
86
|
+
for (const [index, [key, property]] of Object.entries(properties).entries()) {
|
|
87
|
+
validateKey(key);
|
|
88
|
+
consume(budget, `${index > 0 ? "," : ""}${JSON.stringify(key)}:`);
|
|
89
|
+
output[key] = cloneJson(property.value, budget, depth + 1);
|
|
90
|
+
}
|
|
91
|
+
return Object.freeze(output);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function plainProperties(value: unknown): Record<string, PropertyDescriptor> {
|
|
95
|
+
if (
|
|
96
|
+
typeof value !== "object" ||
|
|
97
|
+
value === null ||
|
|
98
|
+
Object.getPrototypeOf(value) !== Object.prototype ||
|
|
99
|
+
Object.getOwnPropertySymbols(value).length !== 0
|
|
100
|
+
)
|
|
101
|
+
invalidIdentity();
|
|
102
|
+
const properties = Object.getOwnPropertyDescriptors(value);
|
|
103
|
+
for (const property of Object.values(properties)) {
|
|
104
|
+
if (!Object.hasOwn(property, "value") || !property.enumerable) invalidIdentity();
|
|
105
|
+
}
|
|
106
|
+
return properties;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function validateKey(key: string): void {
|
|
110
|
+
validateJsonString(key);
|
|
111
|
+
if (
|
|
112
|
+
key.length === 0 ||
|
|
113
|
+
new TextEncoder().encode(key).byteLength > 128 ||
|
|
114
|
+
/\p{Cc}/u.test(key) ||
|
|
115
|
+
key === "__proto__" ||
|
|
116
|
+
key === "constructor" ||
|
|
117
|
+
key === "prototype"
|
|
118
|
+
)
|
|
119
|
+
invalidIdentity();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function validateJsonString(value: string): void {
|
|
123
|
+
// PostgreSQL jsonb rejects NUL and lone UTF-16 surrogates even when JSON.stringify escapes them.
|
|
124
|
+
if (!value.isWellFormed() || value.includes("\u0000")) invalidIdentity();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function consume(budget: { bytes: number }, text: string): void {
|
|
128
|
+
budget.bytes += new TextEncoder().encode(text).byteLength;
|
|
129
|
+
if (budget.bytes > 16 * 1024) invalidIdentity();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function invalidIdentity(): never {
|
|
133
|
+
throw new TypeError("Invalid database RLS identity");
|
|
134
|
+
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { CustomerDatabaseError, CustomerRuntimeError } from "./errors.js";
|
|
2
|
+
import { normalizeRlsIdentity, type CustomerDatabaseRlsIdentity } from "./database-rls.js";
|
|
3
|
+
|
|
4
|
+
export type { CustomerDatabaseRlsIdentity } from "./database-rls.js";
|
|
2
5
|
|
|
3
6
|
const MAX_QUERY_BYTES = 64 * 1024;
|
|
4
7
|
const MAX_PARAMETERS = 100;
|
|
@@ -36,6 +39,19 @@ export interface CustomerDatabaseBinding {
|
|
|
36
39
|
query(input: unknown): Promise<unknown>;
|
|
37
40
|
transaction(input: unknown): Promise<unknown>;
|
|
38
41
|
open?(): Promise<CustomerDatabaseConnectionStub>;
|
|
42
|
+
openRls?(
|
|
43
|
+
identity: CustomerDatabaseRlsIdentity | null,
|
|
44
|
+
): Promise<CustomerDatabaseRlsConnectionStub>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Private lifecycle RPC. Only query is exposed to the application callback. */
|
|
48
|
+
export interface CustomerDatabaseRlsConnectionStub extends CustomerDatabaseConnectionStub {
|
|
49
|
+
commit(): Promise<unknown>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** An existing identity-scoped transaction owned by withRls. */
|
|
53
|
+
export interface CustomerDatabaseRlsTransaction {
|
|
54
|
+
query(input: CustomerDatabaseQuery): Promise<CustomerDatabaseQueryResult>;
|
|
39
55
|
}
|
|
40
56
|
|
|
41
57
|
/** The server-side held connection, reached through a stub. Never handed to customer code raw. */
|
|
@@ -50,6 +66,11 @@ export interface CustomerDatabaseConnection {
|
|
|
50
66
|
}
|
|
51
67
|
|
|
52
68
|
export interface CustomerDatabaseClient {
|
|
69
|
+
/** Authenticate in application code first; null explicitly selects anonymous policies. */
|
|
70
|
+
withRls<Result>(
|
|
71
|
+
identity: CustomerDatabaseRlsIdentity | null,
|
|
72
|
+
run: (transaction: CustomerDatabaseRlsTransaction) => Promise<Result>,
|
|
73
|
+
): Promise<Result>;
|
|
53
74
|
/**
|
|
54
75
|
* Run a read, a decision and a write on one connection. The callback shape is deliberate: the
|
|
55
76
|
* connection is always released, including when the callback throws, so a customer cannot leak
|
|
@@ -80,6 +101,12 @@ export function createPrivateDatabaseClient(
|
|
|
80
101
|
);
|
|
81
102
|
}
|
|
82
103
|
return Object.freeze({
|
|
104
|
+
withRls<Result>(
|
|
105
|
+
identity: CustomerDatabaseRlsIdentity | null,
|
|
106
|
+
run: (transaction: CustomerDatabaseRlsTransaction) => Promise<Result>,
|
|
107
|
+
): Promise<Result> {
|
|
108
|
+
return runRlsTransaction(binding, identity, run);
|
|
109
|
+
},
|
|
83
110
|
async withConnection<Result>(
|
|
84
111
|
run: (connection: CustomerDatabaseConnection) => Promise<Result>,
|
|
85
112
|
): Promise<Result> {
|
|
@@ -137,6 +164,112 @@ export function createPrivateDatabaseClient(
|
|
|
137
164
|
});
|
|
138
165
|
}
|
|
139
166
|
|
|
167
|
+
async function runRlsTransaction<Result>(
|
|
168
|
+
binding: CustomerDatabaseBinding,
|
|
169
|
+
identity: CustomerDatabaseRlsIdentity | null,
|
|
170
|
+
run: (transaction: CustomerDatabaseRlsTransaction) => Promise<Result>,
|
|
171
|
+
): Promise<Result> {
|
|
172
|
+
let wireIdentity: CustomerDatabaseRlsIdentity | null;
|
|
173
|
+
try {
|
|
174
|
+
const normalized = normalizeRlsIdentity(identity);
|
|
175
|
+
const sub = normalized.sub;
|
|
176
|
+
const claims: Record<string, CustomerDatabaseJson> = { ...normalized };
|
|
177
|
+
delete claims["sub"];
|
|
178
|
+
delete claims["role"];
|
|
179
|
+
wireIdentity = sub === null ? null : { subject: sub, claims };
|
|
180
|
+
} catch {
|
|
181
|
+
throw new CustomerRuntimeError("database_rls_identity_invalid", false);
|
|
182
|
+
}
|
|
183
|
+
if (typeof binding.openRls !== "function") throw unavailable();
|
|
184
|
+
let stub: CustomerDatabaseRlsConnectionStub;
|
|
185
|
+
try {
|
|
186
|
+
stub = await binding.openRls(wireIdentity);
|
|
187
|
+
} catch {
|
|
188
|
+
throw unavailable();
|
|
189
|
+
}
|
|
190
|
+
let state: "active" | "closing" | "closed" = "active";
|
|
191
|
+
let poisoned = false;
|
|
192
|
+
let pending: Promise<void> = Promise.resolve();
|
|
193
|
+
const transaction: CustomerDatabaseRlsTransaction = Object.freeze({
|
|
194
|
+
query(input: CustomerDatabaseQuery): Promise<CustomerDatabaseQueryResult> {
|
|
195
|
+
// Validate and snapshot immediately, before the caller can change a queued query.
|
|
196
|
+
let parsed: CustomerDatabaseQuery;
|
|
197
|
+
try {
|
|
198
|
+
if (state !== "active" || poisoned) throw rlsTransactionFailed();
|
|
199
|
+
parsed = validateQuery(input, undefined, false, true);
|
|
200
|
+
} catch (error) {
|
|
201
|
+
if (state === "active") poisoned = true;
|
|
202
|
+
const failed = Promise.reject<CustomerDatabaseQueryResult>(error);
|
|
203
|
+
// A fire-and-forget query must still roll the scope back without an unhandled rejection.
|
|
204
|
+
void failed.catch(() => undefined);
|
|
205
|
+
return failed;
|
|
206
|
+
}
|
|
207
|
+
const operation = pending.then(async () => {
|
|
208
|
+
if (poisoned) throw rlsTransactionFailed();
|
|
209
|
+
let raw: unknown;
|
|
210
|
+
try {
|
|
211
|
+
raw = await stub.query(parsed);
|
|
212
|
+
} catch {
|
|
213
|
+
throw unavailable();
|
|
214
|
+
}
|
|
215
|
+
throwRlsFailure(raw);
|
|
216
|
+
throwStatementFailure(raw);
|
|
217
|
+
return validateResult(raw);
|
|
218
|
+
});
|
|
219
|
+
pending = operation.then(
|
|
220
|
+
() => undefined,
|
|
221
|
+
() => {
|
|
222
|
+
poisoned = true;
|
|
223
|
+
},
|
|
224
|
+
);
|
|
225
|
+
return operation;
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
try {
|
|
229
|
+
const result = await run(transaction);
|
|
230
|
+
state = "closing";
|
|
231
|
+
await pending;
|
|
232
|
+
if (poisoned) throw rlsTransactionFailed();
|
|
233
|
+
let committed: unknown;
|
|
234
|
+
try {
|
|
235
|
+
committed = await stub.commit();
|
|
236
|
+
} catch {
|
|
237
|
+
throw new CustomerRuntimeError("database_transaction_outcome_unknown", false);
|
|
238
|
+
}
|
|
239
|
+
throwRlsFailure(committed, true);
|
|
240
|
+
if (
|
|
241
|
+
!isRecord(committed) ||
|
|
242
|
+
Object.keys(committed).join(",") !== "type" ||
|
|
243
|
+
committed["type"] !== "ohmyhost.database-rls-commit/v1"
|
|
244
|
+
) {
|
|
245
|
+
throw new CustomerRuntimeError("database_transaction_outcome_unknown", false);
|
|
246
|
+
}
|
|
247
|
+
return result;
|
|
248
|
+
} finally {
|
|
249
|
+
state = "closing";
|
|
250
|
+
await pending;
|
|
251
|
+
state = "closed";
|
|
252
|
+
await stub.close().catch(() => undefined);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function rlsTransactionFailed(): CustomerRuntimeError {
|
|
257
|
+
return new CustomerRuntimeError("database_rls_transaction_failed", false);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function throwRlsFailure(value: unknown, duringCommit = false): void {
|
|
261
|
+
if (!isRecord(value) || value["type"] !== "ohmyhost.database-rls-error/v1") return;
|
|
262
|
+
const code = value["code"];
|
|
263
|
+
if (
|
|
264
|
+
Object.keys(value).sort().join(",") !== "code,type" ||
|
|
265
|
+
(code !== "database_rls_transaction_failed" && code !== "database_transaction_outcome_unknown")
|
|
266
|
+
) {
|
|
267
|
+
if (duringCommit) throw new CustomerRuntimeError("database_transaction_outcome_unknown", false);
|
|
268
|
+
invalidResponse();
|
|
269
|
+
}
|
|
270
|
+
throw new CustomerRuntimeError(code, false);
|
|
271
|
+
}
|
|
272
|
+
|
|
140
273
|
function throwStatementFailure(value: unknown): void {
|
|
141
274
|
if (!isRecord(value) || value["type"] !== "ohmyhost.database-error/v1") return;
|
|
142
275
|
const sqlstate = value["sqlstate"];
|
|
@@ -153,6 +286,7 @@ function validateQuery(
|
|
|
153
286
|
value: unknown,
|
|
154
287
|
aggregateBudget?: { nodes: number; bytes: number },
|
|
155
288
|
inConnection = false,
|
|
289
|
+
inRls = false,
|
|
156
290
|
): CustomerDatabaseQuery {
|
|
157
291
|
if (!isRecord(value) || Object.keys(value).sort().join(",") !== "text,values") invalidQuery();
|
|
158
292
|
const text = value["text"];
|
|
@@ -166,7 +300,7 @@ function validateQuery(
|
|
|
166
300
|
) {
|
|
167
301
|
invalidQuery();
|
|
168
302
|
}
|
|
169
|
-
validateSql(text, inConnection);
|
|
303
|
+
validateSql(text, inConnection, inRls);
|
|
170
304
|
const budget = aggregateBudget ?? { nodes: 1, bytes: 2 };
|
|
171
305
|
const parsedValues = values.map((parameter, index) => {
|
|
172
306
|
if (index > 0) consume(budget, 1, MAX_PARAMETER_BYTES, invalidQuery);
|
|
@@ -200,7 +334,7 @@ function validateTransaction(value: unknown): readonly CustomerDatabaseQuery[] {
|
|
|
200
334
|
return Object.freeze(queries);
|
|
201
335
|
}
|
|
202
336
|
|
|
203
|
-
function validateSql(text: string, inConnection = false): void {
|
|
337
|
+
function validateSql(text: string, inConnection = false, inRls = false): void {
|
|
204
338
|
let visible = "";
|
|
205
339
|
let index = 0;
|
|
206
340
|
while (index < text.length) {
|
|
@@ -266,6 +400,7 @@ function validateSql(text: string, inConnection = false): void {
|
|
|
266
400
|
if (
|
|
267
401
|
statements.length !== 1 ||
|
|
268
402
|
semicolonCount > 1 ||
|
|
403
|
+
(inRls && /^call\b/iu.test(statement)) ||
|
|
269
404
|
(inConnection
|
|
270
405
|
? // Transaction control is the whole point of holding a connection; session-wide state and a
|
|
271
406
|
// chained transaction, which the database Worker refuses among the first six words, are not.
|
|
@@ -29,6 +29,9 @@ export type CustomerRuntimeErrorCode =
|
|
|
29
29
|
| "database_binding_missing"
|
|
30
30
|
| "database_query_invalid"
|
|
31
31
|
| "database_response_invalid"
|
|
32
|
+
| "database_rls_identity_invalid"
|
|
33
|
+
| "database_rls_transaction_failed"
|
|
34
|
+
| "database_transaction_outcome_unknown"
|
|
32
35
|
| "database_unavailable"
|
|
33
36
|
| "scheduled_context_invalid";
|
|
34
37
|
|