@constructive-io/express-context 0.14.2 → 0.15.0
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 +5 -5
- package/context.d.ts +2 -0
- package/context.js +1 -0
- package/esm/context.js +1 -0
- package/esm/loaders/cors.js +14 -29
- package/esm/loaders/database-settings.js +5 -4
- package/esm/loaders/index.js +5 -5
- package/esm/loaders/pubkey.js +8 -27
- package/esm/loaders/rls.js +8 -42
- package/esm/loaders/types.js +14 -1
- package/esm/loaders/webauthn.js +4 -3
- package/index.d.ts +1 -1
- package/loaders/cors.d.ts +2 -2
- package/loaders/cors.js +14 -29
- package/loaders/database-settings.js +5 -4
- package/loaders/index.d.ts +5 -5
- package/loaders/index.js +5 -5
- package/loaders/pubkey.d.ts +2 -2
- package/loaders/pubkey.js +8 -27
- package/loaders/rls.d.ts +2 -2
- package/loaders/rls.js +8 -42
- package/loaders/types.d.ts +11 -1
- package/loaders/types.js +16 -0
- package/loaders/webauthn.js +4 -3
- package/package.json +2 -2
- package/types.d.ts +0 -25
package/README.md
CHANGED
|
@@ -63,11 +63,11 @@ Each loader encapsulates a SQL query + type transform + per-databaseId LRU cache
|
|
|
63
63
|
|
|
64
64
|
| Loader | Source | Description |
|
|
65
65
|
|--------|--------|-------------|
|
|
66
|
-
| `rlsLoader` | `
|
|
67
|
-
| `corsLoader` | `
|
|
68
|
-
| `databaseSettingsLoader` | `
|
|
69
|
-
| `pubkeyLoader` | `
|
|
70
|
-
| `webauthnLoader` | `
|
|
66
|
+
| `rlsLoader` | `routing_public.rls_settings` | RLS module (authenticate functions, schema refs) |
|
|
67
|
+
| `corsLoader` | `routing_public.cors_settings` | CORS allowed origins |
|
|
68
|
+
| `databaseSettingsLoader` | `routing_public.database_settings` | Feature flags (aggregates, search, uploads, etc.) |
|
|
69
|
+
| `pubkeyLoader` | `routing_public.pubkey_settings` | Public key challenge auth settings |
|
|
70
|
+
| `webauthnLoader` | `routing_public.webauthn_settings` | WebAuthn/passkey configuration |
|
|
71
71
|
| `authSettingsLoader` | `metaschema_modules_public.sessions_module` | Cookie/captcha settings (two-step tenant DB discovery) |
|
|
72
72
|
|
|
73
73
|
### Custom loaders
|
package/context.d.ts
CHANGED
|
@@ -22,6 +22,8 @@ export interface ContextMiddlewareOptions {
|
|
|
22
22
|
pg?: PgpmOptions['pg'];
|
|
23
23
|
/** Module loader registry for per-database cached lookups */
|
|
24
24
|
loaders?: LoaderRegistry;
|
|
25
|
+
/** Routing-plane schema loaders query (defaults to routing_public) */
|
|
26
|
+
routingSchema?: string;
|
|
25
27
|
}
|
|
26
28
|
/**
|
|
27
29
|
* Build the ConstructiveContext from the current request state.
|
package/context.js
CHANGED
package/esm/context.js
CHANGED
package/esm/loaders/cors.js
CHANGED
|
@@ -2,54 +2,39 @@
|
|
|
2
2
|
* CORS Origins Loader
|
|
3
3
|
*
|
|
4
4
|
* Resolves allowed CORS origins for a database+API combination from the
|
|
5
|
-
* scoped routing plane. Checks per-API settings first, falls back to
|
|
6
|
-
* database-level default
|
|
5
|
+
* scoped routing plane. Checks per-API settings first, falls back to the
|
|
6
|
+
* database-level default.
|
|
7
7
|
*/
|
|
8
8
|
import { createModuleLoader } from './create-loader';
|
|
9
|
+
import { routingSchemaOf } from './types';
|
|
9
10
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
10
|
-
const
|
|
11
|
+
const corsSettingsSql = (schema) => `
|
|
11
12
|
SELECT allowed_origins
|
|
12
|
-
FROM
|
|
13
|
+
FROM "${schema}".cors_settings
|
|
13
14
|
WHERE database_id = $1 AND api_id = $2
|
|
14
15
|
LIMIT 1
|
|
15
16
|
`;
|
|
16
|
-
const
|
|
17
|
+
const corsSettingsDbDefaultSql = (schema) => `
|
|
17
18
|
SELECT allowed_origins
|
|
18
|
-
FROM
|
|
19
|
+
FROM "${schema}".cors_settings
|
|
19
20
|
WHERE database_id = $1 AND api_id IS NULL
|
|
20
21
|
LIMIT 1
|
|
21
22
|
`;
|
|
22
|
-
const CORS_MODULE_SQL = `
|
|
23
|
-
SELECT data
|
|
24
|
-
FROM constructive_routing_public.api_modules
|
|
25
|
-
WHERE api_id = $1 AND name = 'cors'
|
|
26
|
-
LIMIT 1
|
|
27
|
-
`;
|
|
28
23
|
// ─── Loader ─────────────────────────────────────────────────────────────────
|
|
29
24
|
export const corsLoader = createModuleLoader({
|
|
30
25
|
name: 'corsOrigins',
|
|
31
26
|
ttlMs: 5 * 60_000,
|
|
32
27
|
async resolve(ctx) {
|
|
33
28
|
const { routingPool, databaseId, apiId } = ctx;
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
if (apiId) {
|
|
37
|
-
const perApi = await routingPool.query(CORS_SETTINGS_SQL, [databaseId, apiId]);
|
|
38
|
-
if (perApi.rows[0])
|
|
39
|
-
return perApi.rows[0].allowed_origins;
|
|
40
|
-
}
|
|
41
|
-
const dbDefault = await routingPool.query(CORS_SETTINGS_DB_DEFAULT_SQL, [databaseId]);
|
|
42
|
-
if (dbDefault.rows[0])
|
|
43
|
-
return dbDefault.rows[0].allowed_origins;
|
|
44
|
-
}
|
|
45
|
-
catch {
|
|
46
|
-
// Table may not exist yet
|
|
47
|
-
}
|
|
48
|
-
// Fall back to api_modules
|
|
29
|
+
const schema = routingSchemaOf(ctx);
|
|
49
30
|
if (apiId) {
|
|
50
|
-
const
|
|
51
|
-
|
|
31
|
+
const perApi = await routingPool.query(corsSettingsSql(schema), [databaseId, apiId]);
|
|
32
|
+
if (perApi.rows[0])
|
|
33
|
+
return perApi.rows[0].allowed_origins;
|
|
52
34
|
}
|
|
35
|
+
const dbDefault = await routingPool.query(corsSettingsDbDefaultSql(schema), [databaseId]);
|
|
36
|
+
if (dbDefault.rows[0])
|
|
37
|
+
return dbDefault.rows[0].allowed_origins;
|
|
53
38
|
return undefined;
|
|
54
39
|
}
|
|
55
40
|
});
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* Merges database-level defaults with optional per-API overrides.
|
|
7
7
|
*/
|
|
8
8
|
import { createModuleLoader } from './create-loader';
|
|
9
|
+
import { routingSchemaOf } from './types';
|
|
9
10
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
10
|
-
const
|
|
11
|
+
const databaseSettingsSql = (schema) => `
|
|
11
12
|
SELECT
|
|
12
13
|
COALESCE(aps.enable_aggregates, ds.enable_aggregates) AS resolved_enable_aggregates,
|
|
13
14
|
COALESCE(aps.enable_postgis, ds.enable_postgis) AS resolved_enable_postgis,
|
|
@@ -21,8 +22,8 @@ const DATABASE_SETTINGS_SQL = `
|
|
|
21
22
|
COALESCE(aps.enable_realtime, ds.enable_realtime) AS resolved_enable_realtime,
|
|
22
23
|
COALESCE(aps.enable_bulk, ds.enable_bulk) AS resolved_enable_bulk,
|
|
23
24
|
COALESCE(aps.enable_i18n, ds.enable_i18n) AS resolved_enable_i18n
|
|
24
|
-
FROM
|
|
25
|
-
LEFT JOIN
|
|
25
|
+
FROM "${schema}".database_settings ds
|
|
26
|
+
LEFT JOIN "${schema}".api_settings aps ON ds.database_id = aps.database_id AND aps.api_id = $2
|
|
26
27
|
WHERE ds.database_id = $1
|
|
27
28
|
LIMIT 1
|
|
28
29
|
`;
|
|
@@ -32,7 +33,7 @@ export const databaseSettingsLoader = createModuleLoader({
|
|
|
32
33
|
ttlMs: 5 * 60_000,
|
|
33
34
|
async resolve(ctx) {
|
|
34
35
|
const { routingPool, databaseId, apiId } = ctx;
|
|
35
|
-
const result = await routingPool.query(
|
|
36
|
+
const result = await routingPool.query(databaseSettingsSql(routingSchemaOf(ctx)), [databaseId, apiId ?? null]);
|
|
36
37
|
const row = result.rows[0];
|
|
37
38
|
if (!row)
|
|
38
39
|
return undefined;
|
package/esm/loaders/index.js
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* a LoaderRegistry and pass it to createContextMiddleware().
|
|
7
7
|
*
|
|
8
8
|
* Built-in loaders cover the standard Constructive modules:
|
|
9
|
-
* - rlsModule (
|
|
10
|
-
* - corsOrigins (
|
|
11
|
-
* - databaseSettings(
|
|
12
|
-
* - pubkeyChallengeSettings (
|
|
13
|
-
* - webauthnSettings(
|
|
9
|
+
* - rlsModule (routing-plane rls_settings)
|
|
10
|
+
* - corsOrigins (routing-plane cors_settings)
|
|
11
|
+
* - databaseSettings(routing-plane database_settings)
|
|
12
|
+
* - pubkeyChallengeSettings (routing-plane pubkey_settings)
|
|
13
|
+
* - webauthnSettings(routing-plane webauthn_settings)
|
|
14
14
|
* - authSettings (metaschema_modules_public.sessions_module → tenant DB)
|
|
15
15
|
*
|
|
16
16
|
* To add a new per-db lookup, implement a ModuleLoader and register it:
|
package/esm/loaders/pubkey.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* Pubkey Challenge Settings Loader
|
|
3
3
|
*
|
|
4
4
|
* Resolves public-key challenge auth config (crypto network, sign-in/sign-up
|
|
5
|
-
* function names) from the scoped routing plane
|
|
6
|
-
* table
|
|
5
|
+
* function names) from the scoped routing plane via the typed pubkey_settings
|
|
6
|
+
* table.
|
|
7
7
|
*/
|
|
8
8
|
import { createModuleLoader } from './create-loader';
|
|
9
|
+
import { routingSchemaOf } from './types';
|
|
9
10
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
10
|
-
const
|
|
11
|
+
const pubkeySettingsSql = (schema) => `
|
|
11
12
|
SELECT
|
|
12
13
|
s.schema_name AS schema,
|
|
13
14
|
ps.crypto_network,
|
|
@@ -15,7 +16,7 @@ const PUBKEY_SETTINGS_SQL = `
|
|
|
15
16
|
sign_in_req_fn.name AS sign_in_request_challenge,
|
|
16
17
|
sign_in_fail_fn.name AS sign_in_record_failure,
|
|
17
18
|
sign_in_fn.name AS sign_in_with_challenge
|
|
18
|
-
FROM
|
|
19
|
+
FROM "${schema}".pubkey_settings ps
|
|
19
20
|
LEFT JOIN metaschema_public.schema s ON ps.schema_id = s.id
|
|
20
21
|
LEFT JOIN metaschema_public.function sign_up_fn ON ps.sign_up_with_key_function_id = sign_up_fn.id
|
|
21
22
|
LEFT JOIN metaschema_public.function sign_in_req_fn ON ps.sign_in_request_challenge_function_id = sign_in_req_fn.id
|
|
@@ -24,12 +25,6 @@ const PUBKEY_SETTINGS_SQL = `
|
|
|
24
25
|
WHERE ps.database_id = $1
|
|
25
26
|
LIMIT 1
|
|
26
27
|
`;
|
|
27
|
-
const PUBKEY_MODULE_SQL = `
|
|
28
|
-
SELECT data
|
|
29
|
-
FROM constructive_routing_public.api_modules
|
|
30
|
-
WHERE api_id = $1 AND name = 'pubkey_challenge'
|
|
31
|
-
LIMIT 1
|
|
32
|
-
`;
|
|
33
28
|
// ─── Transforms ─────────────────────────────────────────────────────────────
|
|
34
29
|
function fromRow(row) {
|
|
35
30
|
if (!row?.schema || !row?.sign_up_with_key)
|
|
@@ -48,22 +43,8 @@ export const pubkeyLoader = createModuleLoader({
|
|
|
48
43
|
name: 'pubkeyChallengeSettings',
|
|
49
44
|
ttlMs: 5 * 60_000,
|
|
50
45
|
async resolve(ctx) {
|
|
51
|
-
const { routingPool, databaseId
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const result = await routingPool.query(PUBKEY_SETTINGS_SQL, [databaseId]);
|
|
55
|
-
const resolved = fromRow(result.rows[0] ?? null);
|
|
56
|
-
if (resolved)
|
|
57
|
-
return resolved;
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
// Table may not exist yet
|
|
61
|
-
}
|
|
62
|
-
// Fall back to api_modules
|
|
63
|
-
if (apiId) {
|
|
64
|
-
const result = await routingPool.query(PUBKEY_MODULE_SQL, [apiId]);
|
|
65
|
-
return fromRow(result.rows[0]?.data ?? null);
|
|
66
|
-
}
|
|
67
|
-
return undefined;
|
|
46
|
+
const { routingPool, databaseId } = ctx;
|
|
47
|
+
const result = await routingPool.query(pubkeySettingsSql(routingSchemaOf(ctx)), [databaseId]);
|
|
48
|
+
return fromRow(result.rows[0] ?? null);
|
|
68
49
|
}
|
|
69
50
|
});
|
package/esm/loaders/rls.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* RLS Module Loader
|
|
3
3
|
*
|
|
4
4
|
* Resolves RLS authentication function names and schema references for
|
|
5
|
-
* a given database from the scoped routing plane
|
|
6
|
-
* table
|
|
5
|
+
* a given database from the scoped routing plane via the typed rls_settings
|
|
6
|
+
* table.
|
|
7
7
|
*/
|
|
8
8
|
import { createModuleLoader } from './create-loader';
|
|
9
|
+
import { routingSchemaOf } from './types';
|
|
9
10
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
10
|
-
const
|
|
11
|
+
const rlsSettingsSql = (schema) => `
|
|
11
12
|
SELECT
|
|
12
13
|
auth_schema.schema_name AS authenticate_schema,
|
|
13
14
|
role_schema.schema_name AS role_schema,
|
|
@@ -17,7 +18,7 @@ const RLS_SETTINGS_SQL = `
|
|
|
17
18
|
role_id_fn.name AS current_role_id,
|
|
18
19
|
ua_fn.name AS current_user_agent,
|
|
19
20
|
ip_fn.name AS current_ip_address
|
|
20
|
-
FROM
|
|
21
|
+
FROM "${schema}".rls_settings rs
|
|
21
22
|
LEFT JOIN metaschema_public.schema auth_schema ON rs.authenticate_schema_id = auth_schema.id
|
|
22
23
|
LEFT JOIN metaschema_public.schema role_schema ON rs.role_schema_id = role_schema.id
|
|
23
24
|
LEFT JOIN metaschema_public.function auth_fn ON rs.authenticate_function_id = auth_fn.id
|
|
@@ -29,12 +30,6 @@ const RLS_SETTINGS_SQL = `
|
|
|
29
30
|
WHERE rs.database_id = $1
|
|
30
31
|
LIMIT 1
|
|
31
32
|
`;
|
|
32
|
-
const RLS_MODULE_SQL = `
|
|
33
|
-
SELECT data
|
|
34
|
-
FROM constructive_routing_public.api_modules
|
|
35
|
-
WHERE api_id = $1 AND name = 'rls_module'
|
|
36
|
-
LIMIT 1
|
|
37
|
-
`;
|
|
38
33
|
// ─── Transforms ─────────────────────────────────────────────────────────────
|
|
39
34
|
function fromSettings(row) {
|
|
40
35
|
if (!row)
|
|
@@ -52,42 +47,13 @@ function fromSettings(row) {
|
|
|
52
47
|
currentUserAgent: row.current_user_agent
|
|
53
48
|
};
|
|
54
49
|
}
|
|
55
|
-
function fromModule(row) {
|
|
56
|
-
if (!row?.data)
|
|
57
|
-
return undefined;
|
|
58
|
-
const d = row.data;
|
|
59
|
-
return {
|
|
60
|
-
authenticate: d.authenticate,
|
|
61
|
-
authenticateStrict: d.authenticate_strict,
|
|
62
|
-
privateSchema: { schemaName: d.authenticate_schema },
|
|
63
|
-
publicSchema: { schemaName: d.role_schema },
|
|
64
|
-
currentRole: d.current_role,
|
|
65
|
-
currentRoleId: d.current_role_id,
|
|
66
|
-
currentIpAddress: d.current_ip_address,
|
|
67
|
-
currentUserAgent: d.current_user_agent
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
50
|
// ─── Loader ─────────────────────────────────────────────────────────────────
|
|
71
51
|
export const rlsLoader = createModuleLoader({
|
|
72
52
|
name: 'rlsModule',
|
|
73
53
|
ttlMs: 5 * 60_000,
|
|
74
54
|
async resolve(ctx) {
|
|
75
|
-
const { routingPool, databaseId
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const result = await routingPool.query(RLS_SETTINGS_SQL, [databaseId]);
|
|
79
|
-
const resolved = fromSettings(result.rows[0] ?? null);
|
|
80
|
-
if (resolved)
|
|
81
|
-
return resolved;
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
84
|
-
// Table may not exist yet
|
|
85
|
-
}
|
|
86
|
-
// Fall back to api_modules
|
|
87
|
-
if (apiId) {
|
|
88
|
-
const result = await routingPool.query(RLS_MODULE_SQL, [apiId]);
|
|
89
|
-
return fromModule(result.rows[0] ?? null);
|
|
90
|
-
}
|
|
91
|
-
return undefined;
|
|
55
|
+
const { routingPool, databaseId } = ctx;
|
|
56
|
+
const result = await routingPool.query(rlsSettingsSql(routingSchemaOf(ctx)), [databaseId]);
|
|
57
|
+
return fromSettings(result.rows[0] ?? null);
|
|
92
58
|
}
|
|
93
59
|
});
|
package/esm/loaders/types.js
CHANGED
|
@@ -9,4 +9,17 @@
|
|
|
9
9
|
* during context building. The result is a typed modules map on
|
|
10
10
|
* `req.constructive.modules`.
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
/** Published logical name of the scoped routing plane. */
|
|
13
|
+
export const DEFAULT_ROUTING_SCHEMA = 'routing_public';
|
|
14
|
+
/**
|
|
15
|
+
* The routing-plane schema a loader should query: the context override or
|
|
16
|
+
* the published default. Throws on names unsafe to interpolate as an
|
|
17
|
+
* identifier.
|
|
18
|
+
*/
|
|
19
|
+
export const routingSchemaOf = (ctx) => {
|
|
20
|
+
const schema = ctx.routingSchema ?? DEFAULT_ROUTING_SCHEMA;
|
|
21
|
+
if (!/^[a-z_][a-z0-9_]*$/.test(schema)) {
|
|
22
|
+
throw new Error(`invalid routing schema name: ${schema}`);
|
|
23
|
+
}
|
|
24
|
+
return schema;
|
|
25
|
+
};
|
package/esm/loaders/webauthn.js
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
* schema references, attestation policy, and challenge expiry.
|
|
6
6
|
*/
|
|
7
7
|
import { createModuleLoader } from './create-loader';
|
|
8
|
+
import { routingSchemaOf } from './types';
|
|
8
9
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
9
|
-
const
|
|
10
|
+
const webauthnSettingsSql = (schema) => `
|
|
10
11
|
SELECT
|
|
11
12
|
s.schema_name AS schema,
|
|
12
13
|
cred_s.schema_name AS credentials_schema,
|
|
@@ -19,7 +20,7 @@ const WEBAUTHN_SETTINGS_SQL = `
|
|
|
19
20
|
ws.require_user_verification,
|
|
20
21
|
ws.resident_key,
|
|
21
22
|
ws.challenge_expiry_seconds
|
|
22
|
-
FROM
|
|
23
|
+
FROM "${schema}".webauthn_settings ws
|
|
23
24
|
LEFT JOIN metaschema_public.schema s ON ws.schema_id = s.id
|
|
24
25
|
LEFT JOIN metaschema_public.schema cred_s ON ws.credentials_schema_id = cred_s.id
|
|
25
26
|
LEFT JOIN metaschema_public.schema sess_s ON ws.sessions_schema_id = sess_s.id
|
|
@@ -33,7 +34,7 @@ export const webauthnLoader = createModuleLoader({
|
|
|
33
34
|
ttlMs: 5 * 60_000,
|
|
34
35
|
async resolve(ctx) {
|
|
35
36
|
const { routingPool, databaseId } = ctx;
|
|
36
|
-
const result = await routingPool.query(
|
|
37
|
+
const result = await routingPool.query(webauthnSettingsSql(routingSchemaOf(ctx)), [databaseId]);
|
|
37
38
|
const row = result.rows[0];
|
|
38
39
|
if (!row?.schema)
|
|
39
40
|
return undefined;
|
package/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* });
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
|
-
export type { AgentChatConfig, ApiConfigResult, ApiError,
|
|
37
|
+
export type { AgentChatConfig, ApiConfigResult, ApiError, ApiStructure, AuthSettings, BillingConfig, BuiltinModuleMap, ComputeConfig, ComputeModuleConfig, ConstructiveAPIToken, ConstructiveContext, DatabaseSettings, InferenceLogConfig, LlmConfig, PubkeyChallengeSettings, RlsModule, WebauthnSettings, WithPgClient, } from './types';
|
|
38
38
|
export type { BillingClient, InferenceLogEntry } from './billing-client';
|
|
39
39
|
export { createBillingClient } from './billing-client';
|
|
40
40
|
export type { PgSettingsInput } from './pg-settings';
|
package/loaders/cors.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* CORS Origins Loader
|
|
3
3
|
*
|
|
4
4
|
* Resolves allowed CORS origins for a database+API combination from the
|
|
5
|
-
* scoped routing plane. Checks per-API settings first, falls back to
|
|
6
|
-
* database-level default
|
|
5
|
+
* scoped routing plane. Checks per-API settings first, falls back to the
|
|
6
|
+
* database-level default.
|
|
7
7
|
*/
|
|
8
8
|
import type { ModuleLoader } from './types';
|
|
9
9
|
export declare const corsLoader: ModuleLoader<string[]>;
|
package/loaders/cors.js
CHANGED
|
@@ -3,56 +3,41 @@
|
|
|
3
3
|
* CORS Origins Loader
|
|
4
4
|
*
|
|
5
5
|
* Resolves allowed CORS origins for a database+API combination from the
|
|
6
|
-
* scoped routing plane. Checks per-API settings first, falls back to
|
|
7
|
-
* database-level default
|
|
6
|
+
* scoped routing plane. Checks per-API settings first, falls back to the
|
|
7
|
+
* database-level default.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.corsLoader = void 0;
|
|
11
11
|
const create_loader_1 = require("./create-loader");
|
|
12
|
+
const types_1 = require("./types");
|
|
12
13
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
13
|
-
const
|
|
14
|
+
const corsSettingsSql = (schema) => `
|
|
14
15
|
SELECT allowed_origins
|
|
15
|
-
FROM
|
|
16
|
+
FROM "${schema}".cors_settings
|
|
16
17
|
WHERE database_id = $1 AND api_id = $2
|
|
17
18
|
LIMIT 1
|
|
18
19
|
`;
|
|
19
|
-
const
|
|
20
|
+
const corsSettingsDbDefaultSql = (schema) => `
|
|
20
21
|
SELECT allowed_origins
|
|
21
|
-
FROM
|
|
22
|
+
FROM "${schema}".cors_settings
|
|
22
23
|
WHERE database_id = $1 AND api_id IS NULL
|
|
23
24
|
LIMIT 1
|
|
24
25
|
`;
|
|
25
|
-
const CORS_MODULE_SQL = `
|
|
26
|
-
SELECT data
|
|
27
|
-
FROM constructive_routing_public.api_modules
|
|
28
|
-
WHERE api_id = $1 AND name = 'cors'
|
|
29
|
-
LIMIT 1
|
|
30
|
-
`;
|
|
31
26
|
// ─── Loader ─────────────────────────────────────────────────────────────────
|
|
32
27
|
exports.corsLoader = (0, create_loader_1.createModuleLoader)({
|
|
33
28
|
name: 'corsOrigins',
|
|
34
29
|
ttlMs: 5 * 60_000,
|
|
35
30
|
async resolve(ctx) {
|
|
36
31
|
const { routingPool, databaseId, apiId } = ctx;
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
if (apiId) {
|
|
40
|
-
const perApi = await routingPool.query(CORS_SETTINGS_SQL, [databaseId, apiId]);
|
|
41
|
-
if (perApi.rows[0])
|
|
42
|
-
return perApi.rows[0].allowed_origins;
|
|
43
|
-
}
|
|
44
|
-
const dbDefault = await routingPool.query(CORS_SETTINGS_DB_DEFAULT_SQL, [databaseId]);
|
|
45
|
-
if (dbDefault.rows[0])
|
|
46
|
-
return dbDefault.rows[0].allowed_origins;
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
// Table may not exist yet
|
|
50
|
-
}
|
|
51
|
-
// Fall back to api_modules
|
|
32
|
+
const schema = (0, types_1.routingSchemaOf)(ctx);
|
|
52
33
|
if (apiId) {
|
|
53
|
-
const
|
|
54
|
-
|
|
34
|
+
const perApi = await routingPool.query(corsSettingsSql(schema), [databaseId, apiId]);
|
|
35
|
+
if (perApi.rows[0])
|
|
36
|
+
return perApi.rows[0].allowed_origins;
|
|
55
37
|
}
|
|
38
|
+
const dbDefault = await routingPool.query(corsSettingsDbDefaultSql(schema), [databaseId]);
|
|
39
|
+
if (dbDefault.rows[0])
|
|
40
|
+
return dbDefault.rows[0].allowed_origins;
|
|
56
41
|
return undefined;
|
|
57
42
|
}
|
|
58
43
|
});
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.databaseSettingsLoader = void 0;
|
|
11
11
|
const create_loader_1 = require("./create-loader");
|
|
12
|
+
const types_1 = require("./types");
|
|
12
13
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
13
|
-
const
|
|
14
|
+
const databaseSettingsSql = (schema) => `
|
|
14
15
|
SELECT
|
|
15
16
|
COALESCE(aps.enable_aggregates, ds.enable_aggregates) AS resolved_enable_aggregates,
|
|
16
17
|
COALESCE(aps.enable_postgis, ds.enable_postgis) AS resolved_enable_postgis,
|
|
@@ -24,8 +25,8 @@ const DATABASE_SETTINGS_SQL = `
|
|
|
24
25
|
COALESCE(aps.enable_realtime, ds.enable_realtime) AS resolved_enable_realtime,
|
|
25
26
|
COALESCE(aps.enable_bulk, ds.enable_bulk) AS resolved_enable_bulk,
|
|
26
27
|
COALESCE(aps.enable_i18n, ds.enable_i18n) AS resolved_enable_i18n
|
|
27
|
-
FROM
|
|
28
|
-
LEFT JOIN
|
|
28
|
+
FROM "${schema}".database_settings ds
|
|
29
|
+
LEFT JOIN "${schema}".api_settings aps ON ds.database_id = aps.database_id AND aps.api_id = $2
|
|
29
30
|
WHERE ds.database_id = $1
|
|
30
31
|
LIMIT 1
|
|
31
32
|
`;
|
|
@@ -35,7 +36,7 @@ exports.databaseSettingsLoader = (0, create_loader_1.createModuleLoader)({
|
|
|
35
36
|
ttlMs: 5 * 60_000,
|
|
36
37
|
async resolve(ctx) {
|
|
37
38
|
const { routingPool, databaseId, apiId } = ctx;
|
|
38
|
-
const result = await routingPool.query(
|
|
39
|
+
const result = await routingPool.query(databaseSettingsSql((0, types_1.routingSchemaOf)(ctx)), [databaseId, apiId ?? null]);
|
|
39
40
|
const row = result.rows[0];
|
|
40
41
|
if (!row)
|
|
41
42
|
return undefined;
|
package/loaders/index.d.ts
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
* a LoaderRegistry and pass it to createContextMiddleware().
|
|
7
7
|
*
|
|
8
8
|
* Built-in loaders cover the standard Constructive modules:
|
|
9
|
-
* - rlsModule (
|
|
10
|
-
* - corsOrigins (
|
|
11
|
-
* - databaseSettings(
|
|
12
|
-
* - pubkeyChallengeSettings (
|
|
13
|
-
* - webauthnSettings(
|
|
9
|
+
* - rlsModule (routing-plane rls_settings)
|
|
10
|
+
* - corsOrigins (routing-plane cors_settings)
|
|
11
|
+
* - databaseSettings(routing-plane database_settings)
|
|
12
|
+
* - pubkeyChallengeSettings (routing-plane pubkey_settings)
|
|
13
|
+
* - webauthnSettings(routing-plane webauthn_settings)
|
|
14
14
|
* - authSettings (metaschema_modules_public.sessions_module → tenant DB)
|
|
15
15
|
*
|
|
16
16
|
* To add a new per-db lookup, implement a ModuleLoader and register it:
|
package/loaders/index.js
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
* a LoaderRegistry and pass it to createContextMiddleware().
|
|
8
8
|
*
|
|
9
9
|
* Built-in loaders cover the standard Constructive modules:
|
|
10
|
-
* - rlsModule (
|
|
11
|
-
* - corsOrigins (
|
|
12
|
-
* - databaseSettings(
|
|
13
|
-
* - pubkeyChallengeSettings (
|
|
14
|
-
* - webauthnSettings(
|
|
10
|
+
* - rlsModule (routing-plane rls_settings)
|
|
11
|
+
* - corsOrigins (routing-plane cors_settings)
|
|
12
|
+
* - databaseSettings(routing-plane database_settings)
|
|
13
|
+
* - pubkeyChallengeSettings (routing-plane pubkey_settings)
|
|
14
|
+
* - webauthnSettings(routing-plane webauthn_settings)
|
|
15
15
|
* - authSettings (metaschema_modules_public.sessions_module → tenant DB)
|
|
16
16
|
*
|
|
17
17
|
* To add a new per-db lookup, implement a ModuleLoader and register it:
|
package/loaders/pubkey.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Pubkey Challenge Settings Loader
|
|
3
3
|
*
|
|
4
4
|
* Resolves public-key challenge auth config (crypto network, sign-in/sign-up
|
|
5
|
-
* function names) from the scoped routing plane
|
|
6
|
-
* table
|
|
5
|
+
* function names) from the scoped routing plane via the typed pubkey_settings
|
|
6
|
+
* table.
|
|
7
7
|
*/
|
|
8
8
|
import type { PubkeyChallengeSettings } from '../types';
|
|
9
9
|
import type { ModuleLoader } from './types';
|
package/loaders/pubkey.js
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
* Pubkey Challenge Settings Loader
|
|
4
4
|
*
|
|
5
5
|
* Resolves public-key challenge auth config (crypto network, sign-in/sign-up
|
|
6
|
-
* function names) from the scoped routing plane
|
|
7
|
-
* table
|
|
6
|
+
* function names) from the scoped routing plane via the typed pubkey_settings
|
|
7
|
+
* table.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.pubkeyLoader = void 0;
|
|
11
11
|
const create_loader_1 = require("./create-loader");
|
|
12
|
+
const types_1 = require("./types");
|
|
12
13
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
13
|
-
const
|
|
14
|
+
const pubkeySettingsSql = (schema) => `
|
|
14
15
|
SELECT
|
|
15
16
|
s.schema_name AS schema,
|
|
16
17
|
ps.crypto_network,
|
|
@@ -18,7 +19,7 @@ const PUBKEY_SETTINGS_SQL = `
|
|
|
18
19
|
sign_in_req_fn.name AS sign_in_request_challenge,
|
|
19
20
|
sign_in_fail_fn.name AS sign_in_record_failure,
|
|
20
21
|
sign_in_fn.name AS sign_in_with_challenge
|
|
21
|
-
FROM
|
|
22
|
+
FROM "${schema}".pubkey_settings ps
|
|
22
23
|
LEFT JOIN metaschema_public.schema s ON ps.schema_id = s.id
|
|
23
24
|
LEFT JOIN metaschema_public.function sign_up_fn ON ps.sign_up_with_key_function_id = sign_up_fn.id
|
|
24
25
|
LEFT JOIN metaschema_public.function sign_in_req_fn ON ps.sign_in_request_challenge_function_id = sign_in_req_fn.id
|
|
@@ -27,12 +28,6 @@ const PUBKEY_SETTINGS_SQL = `
|
|
|
27
28
|
WHERE ps.database_id = $1
|
|
28
29
|
LIMIT 1
|
|
29
30
|
`;
|
|
30
|
-
const PUBKEY_MODULE_SQL = `
|
|
31
|
-
SELECT data
|
|
32
|
-
FROM constructive_routing_public.api_modules
|
|
33
|
-
WHERE api_id = $1 AND name = 'pubkey_challenge'
|
|
34
|
-
LIMIT 1
|
|
35
|
-
`;
|
|
36
31
|
// ─── Transforms ─────────────────────────────────────────────────────────────
|
|
37
32
|
function fromRow(row) {
|
|
38
33
|
if (!row?.schema || !row?.sign_up_with_key)
|
|
@@ -51,22 +46,8 @@ exports.pubkeyLoader = (0, create_loader_1.createModuleLoader)({
|
|
|
51
46
|
name: 'pubkeyChallengeSettings',
|
|
52
47
|
ttlMs: 5 * 60_000,
|
|
53
48
|
async resolve(ctx) {
|
|
54
|
-
const { routingPool, databaseId
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const result = await routingPool.query(PUBKEY_SETTINGS_SQL, [databaseId]);
|
|
58
|
-
const resolved = fromRow(result.rows[0] ?? null);
|
|
59
|
-
if (resolved)
|
|
60
|
-
return resolved;
|
|
61
|
-
}
|
|
62
|
-
catch {
|
|
63
|
-
// Table may not exist yet
|
|
64
|
-
}
|
|
65
|
-
// Fall back to api_modules
|
|
66
|
-
if (apiId) {
|
|
67
|
-
const result = await routingPool.query(PUBKEY_MODULE_SQL, [apiId]);
|
|
68
|
-
return fromRow(result.rows[0]?.data ?? null);
|
|
69
|
-
}
|
|
70
|
-
return undefined;
|
|
49
|
+
const { routingPool, databaseId } = ctx;
|
|
50
|
+
const result = await routingPool.query(pubkeySettingsSql((0, types_1.routingSchemaOf)(ctx)), [databaseId]);
|
|
51
|
+
return fromRow(result.rows[0] ?? null);
|
|
71
52
|
}
|
|
72
53
|
});
|
package/loaders/rls.d.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* RLS Module Loader
|
|
3
3
|
*
|
|
4
4
|
* Resolves RLS authentication function names and schema references for
|
|
5
|
-
* a given database from the scoped routing plane
|
|
6
|
-
* table
|
|
5
|
+
* a given database from the scoped routing plane via the typed rls_settings
|
|
6
|
+
* table.
|
|
7
7
|
*/
|
|
8
8
|
import type { RlsModule } from '../types';
|
|
9
9
|
import type { ModuleLoader } from './types';
|
package/loaders/rls.js
CHANGED
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
* RLS Module Loader
|
|
4
4
|
*
|
|
5
5
|
* Resolves RLS authentication function names and schema references for
|
|
6
|
-
* a given database from the scoped routing plane
|
|
7
|
-
* table
|
|
6
|
+
* a given database from the scoped routing plane via the typed rls_settings
|
|
7
|
+
* table.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.rlsLoader = void 0;
|
|
11
11
|
const create_loader_1 = require("./create-loader");
|
|
12
|
+
const types_1 = require("./types");
|
|
12
13
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
13
|
-
const
|
|
14
|
+
const rlsSettingsSql = (schema) => `
|
|
14
15
|
SELECT
|
|
15
16
|
auth_schema.schema_name AS authenticate_schema,
|
|
16
17
|
role_schema.schema_name AS role_schema,
|
|
@@ -20,7 +21,7 @@ const RLS_SETTINGS_SQL = `
|
|
|
20
21
|
role_id_fn.name AS current_role_id,
|
|
21
22
|
ua_fn.name AS current_user_agent,
|
|
22
23
|
ip_fn.name AS current_ip_address
|
|
23
|
-
FROM
|
|
24
|
+
FROM "${schema}".rls_settings rs
|
|
24
25
|
LEFT JOIN metaschema_public.schema auth_schema ON rs.authenticate_schema_id = auth_schema.id
|
|
25
26
|
LEFT JOIN metaschema_public.schema role_schema ON rs.role_schema_id = role_schema.id
|
|
26
27
|
LEFT JOIN metaschema_public.function auth_fn ON rs.authenticate_function_id = auth_fn.id
|
|
@@ -32,12 +33,6 @@ const RLS_SETTINGS_SQL = `
|
|
|
32
33
|
WHERE rs.database_id = $1
|
|
33
34
|
LIMIT 1
|
|
34
35
|
`;
|
|
35
|
-
const RLS_MODULE_SQL = `
|
|
36
|
-
SELECT data
|
|
37
|
-
FROM constructive_routing_public.api_modules
|
|
38
|
-
WHERE api_id = $1 AND name = 'rls_module'
|
|
39
|
-
LIMIT 1
|
|
40
|
-
`;
|
|
41
36
|
// ─── Transforms ─────────────────────────────────────────────────────────────
|
|
42
37
|
function fromSettings(row) {
|
|
43
38
|
if (!row)
|
|
@@ -55,42 +50,13 @@ function fromSettings(row) {
|
|
|
55
50
|
currentUserAgent: row.current_user_agent
|
|
56
51
|
};
|
|
57
52
|
}
|
|
58
|
-
function fromModule(row) {
|
|
59
|
-
if (!row?.data)
|
|
60
|
-
return undefined;
|
|
61
|
-
const d = row.data;
|
|
62
|
-
return {
|
|
63
|
-
authenticate: d.authenticate,
|
|
64
|
-
authenticateStrict: d.authenticate_strict,
|
|
65
|
-
privateSchema: { schemaName: d.authenticate_schema },
|
|
66
|
-
publicSchema: { schemaName: d.role_schema },
|
|
67
|
-
currentRole: d.current_role,
|
|
68
|
-
currentRoleId: d.current_role_id,
|
|
69
|
-
currentIpAddress: d.current_ip_address,
|
|
70
|
-
currentUserAgent: d.current_user_agent
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
53
|
// ─── Loader ─────────────────────────────────────────────────────────────────
|
|
74
54
|
exports.rlsLoader = (0, create_loader_1.createModuleLoader)({
|
|
75
55
|
name: 'rlsModule',
|
|
76
56
|
ttlMs: 5 * 60_000,
|
|
77
57
|
async resolve(ctx) {
|
|
78
|
-
const { routingPool, databaseId
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const result = await routingPool.query(RLS_SETTINGS_SQL, [databaseId]);
|
|
82
|
-
const resolved = fromSettings(result.rows[0] ?? null);
|
|
83
|
-
if (resolved)
|
|
84
|
-
return resolved;
|
|
85
|
-
}
|
|
86
|
-
catch {
|
|
87
|
-
// Table may not exist yet
|
|
88
|
-
}
|
|
89
|
-
// Fall back to api_modules
|
|
90
|
-
if (apiId) {
|
|
91
|
-
const result = await routingPool.query(RLS_MODULE_SQL, [apiId]);
|
|
92
|
-
return fromModule(result.rows[0] ?? null);
|
|
93
|
-
}
|
|
94
|
-
return undefined;
|
|
58
|
+
const { routingPool, databaseId } = ctx;
|
|
59
|
+
const result = await routingPool.query(rlsSettingsSql((0, types_1.routingSchemaOf)(ctx)), [databaseId]);
|
|
60
|
+
return fromSettings(result.rows[0] ?? null);
|
|
95
61
|
}
|
|
96
62
|
});
|
package/loaders/types.d.ts
CHANGED
|
@@ -10,14 +10,24 @@
|
|
|
10
10
|
* `req.constructive.modules`.
|
|
11
11
|
*/
|
|
12
12
|
import type { Pool } from 'pg';
|
|
13
|
+
/** Published logical name of the scoped routing plane. */
|
|
14
|
+
export declare const DEFAULT_ROUTING_SCHEMA = "routing_public";
|
|
15
|
+
/**
|
|
16
|
+
* The routing-plane schema a loader should query: the context override or
|
|
17
|
+
* the published default. Throws on names unsafe to interpolate as an
|
|
18
|
+
* identifier.
|
|
19
|
+
*/
|
|
20
|
+
export declare const routingSchemaOf: (ctx: Pick<LoaderContext, "routingSchema">) => string;
|
|
13
21
|
/**
|
|
14
22
|
* Context passed to every loader's resolve function.
|
|
15
23
|
* Provides both pool references so the loader can query whichever
|
|
16
24
|
* database tier it needs.
|
|
17
25
|
*/
|
|
18
26
|
export interface LoaderContext {
|
|
19
|
-
/** Routing/configuration database pool (for
|
|
27
|
+
/** Routing/configuration database pool (for routing-plane lookups) */
|
|
20
28
|
routingPool: Pool;
|
|
29
|
+
/** Routing-plane schema to query (defaults to the published routing_public) */
|
|
30
|
+
routingSchema?: string;
|
|
21
31
|
/** Tenant database pool (for metaschema_modules_public.* lookups) */
|
|
22
32
|
tenantPool: Pool;
|
|
23
33
|
/** UUID of the database being resolved */
|
package/loaders/types.js
CHANGED
|
@@ -11,3 +11,19 @@
|
|
|
11
11
|
* `req.constructive.modules`.
|
|
12
12
|
*/
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.routingSchemaOf = exports.DEFAULT_ROUTING_SCHEMA = void 0;
|
|
15
|
+
/** Published logical name of the scoped routing plane. */
|
|
16
|
+
exports.DEFAULT_ROUTING_SCHEMA = 'routing_public';
|
|
17
|
+
/**
|
|
18
|
+
* The routing-plane schema a loader should query: the context override or
|
|
19
|
+
* the published default. Throws on names unsafe to interpolate as an
|
|
20
|
+
* identifier.
|
|
21
|
+
*/
|
|
22
|
+
const routingSchemaOf = (ctx) => {
|
|
23
|
+
const schema = ctx.routingSchema ?? exports.DEFAULT_ROUTING_SCHEMA;
|
|
24
|
+
if (!/^[a-z_][a-z0-9_]*$/.test(schema)) {
|
|
25
|
+
throw new Error(`invalid routing schema name: ${schema}`);
|
|
26
|
+
}
|
|
27
|
+
return schema;
|
|
28
|
+
};
|
|
29
|
+
exports.routingSchemaOf = routingSchemaOf;
|
package/loaders/webauthn.js
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.webauthnLoader = void 0;
|
|
10
10
|
const create_loader_1 = require("./create-loader");
|
|
11
|
+
const types_1 = require("./types");
|
|
11
12
|
// ─── SQL ────────────────────────────────────────────────────────────────────
|
|
12
|
-
const
|
|
13
|
+
const webauthnSettingsSql = (schema) => `
|
|
13
14
|
SELECT
|
|
14
15
|
s.schema_name AS schema,
|
|
15
16
|
cred_s.schema_name AS credentials_schema,
|
|
@@ -22,7 +23,7 @@ const WEBAUTHN_SETTINGS_SQL = `
|
|
|
22
23
|
ws.require_user_verification,
|
|
23
24
|
ws.resident_key,
|
|
24
25
|
ws.challenge_expiry_seconds
|
|
25
|
-
FROM
|
|
26
|
+
FROM "${schema}".webauthn_settings ws
|
|
26
27
|
LEFT JOIN metaschema_public.schema s ON ws.schema_id = s.id
|
|
27
28
|
LEFT JOIN metaschema_public.schema cred_s ON ws.credentials_schema_id = cred_s.id
|
|
28
29
|
LEFT JOIN metaschema_public.schema sess_s ON ws.sessions_schema_id = sess_s.id
|
|
@@ -36,7 +37,7 @@ exports.webauthnLoader = (0, create_loader_1.createModuleLoader)({
|
|
|
36
37
|
ttlMs: 5 * 60_000,
|
|
37
38
|
async resolve(ctx) {
|
|
38
39
|
const { routingPool, databaseId } = ctx;
|
|
39
|
-
const result = await routingPool.query(
|
|
40
|
+
const result = await routingPool.query(webauthnSettingsSql((0, types_1.routingSchemaOf)(ctx)), [databaseId]);
|
|
40
41
|
const row = result.rows[0];
|
|
41
42
|
if (!row?.schema)
|
|
42
43
|
return undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/express-context",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Extractable Express middleware for Constructive tenant context — domain resolution, JWT auth, pgSettings, and withPgClient",
|
|
5
5
|
"author": "Constructive <developers@constructive.io>",
|
|
6
6
|
"homepage": "https://github.com/constructive-io/constructive",
|
|
@@ -59,5 +59,5 @@
|
|
|
59
59
|
"jwt",
|
|
60
60
|
"pgSettings"
|
|
61
61
|
],
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "518e7ab2270661c64875258436d90fdf76b4b336"
|
|
63
63
|
}
|
package/types.d.ts
CHANGED
|
@@ -8,20 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type { Pool, PoolClient } from 'pg';
|
|
10
10
|
import type { BillingClient } from './billing-client';
|
|
11
|
-
export interface CorsModuleData {
|
|
12
|
-
urls: string[];
|
|
13
|
-
}
|
|
14
|
-
export interface PublicKeyChallengeData {
|
|
15
|
-
schema: string;
|
|
16
|
-
crypto_network: string;
|
|
17
|
-
sign_up_with_key: string;
|
|
18
|
-
sign_in_request_challenge: string;
|
|
19
|
-
sign_in_record_failure: string;
|
|
20
|
-
sign_in_with_challenge: string;
|
|
21
|
-
}
|
|
22
|
-
export interface GenericModuleData {
|
|
23
|
-
[key: string]: unknown;
|
|
24
|
-
}
|
|
25
11
|
export interface DatabaseSettings {
|
|
26
12
|
enableAggregates: boolean;
|
|
27
13
|
enablePostgis: boolean;
|
|
@@ -57,16 +43,6 @@ export interface WebauthnSettings {
|
|
|
57
43
|
residentKey: string;
|
|
58
44
|
challengeExpirySeconds: number;
|
|
59
45
|
}
|
|
60
|
-
export type ApiModule = {
|
|
61
|
-
name: 'cors';
|
|
62
|
-
data: CorsModuleData;
|
|
63
|
-
} | {
|
|
64
|
-
name: 'pubkey_challenge';
|
|
65
|
-
data: PublicKeyChallengeData;
|
|
66
|
-
} | {
|
|
67
|
-
name: string;
|
|
68
|
-
data?: GenericModuleData;
|
|
69
|
-
};
|
|
70
46
|
export interface RlsModule {
|
|
71
47
|
authenticate: string;
|
|
72
48
|
authenticateStrict: string;
|
|
@@ -98,7 +74,6 @@ export interface ApiStructure {
|
|
|
98
74
|
anonRole: string;
|
|
99
75
|
roleName: string;
|
|
100
76
|
schema: string[];
|
|
101
|
-
apiModules: ApiModule[];
|
|
102
77
|
rlsModule?: RlsModule;
|
|
103
78
|
domains?: string[];
|
|
104
79
|
databaseId?: string;
|