@stratum-hq/lib 1.7.0 → 1.8.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 +29 -2
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +50 -10
- package/dist/crypto.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/migrate-schemas.d.ts +4 -0
- package/dist/migrate-schemas.d.ts.map +1 -1
- package/dist/migrate-schemas.js +16 -6
- package/dist/migrate-schemas.js.map +1 -1
- package/dist/migrate.d.ts +24 -0
- package/dist/migrate.d.ts.map +1 -1
- package/dist/migrate.js +44 -6
- package/dist/migrate.js.map +1 -1
- package/dist/migration-sql.d.ts +25 -0
- package/dist/migration-sql.d.ts.map +1 -0
- package/dist/migration-sql.js +64 -0
- package/dist/migration-sql.js.map +1 -0
- package/dist/migrations/029_tenant_parent_cycle_guard.sql +2 -2
- package/dist/migrations/031_subtree_read_scope.sql +6 -6
- package/dist/migrations/032_control_role.sql +809 -0
- package/dist/migrations/033_api_keys_tenant_index.sql +14 -0
- package/dist/pinned-query.d.ts +29 -0
- package/dist/pinned-query.d.ts.map +1 -0
- package/dist/pinned-query.js +60 -0
- package/dist/pinned-query.js.map +1 -0
- package/dist/pool-helpers.d.ts +2 -0
- package/dist/pool-helpers.d.ts.map +1 -1
- package/dist/pool-helpers.js +17 -3
- package/dist/pool-helpers.js.map +1 -1
- package/dist/role-model.d.ts +178 -0
- package/dist/role-model.d.ts.map +1 -0
- package/dist/role-model.js +670 -0
- package/dist/role-model.js.map +1 -0
- package/dist/services/api-key-service.d.ts +12 -2
- package/dist/services/api-key-service.d.ts.map +1 -1
- package/dist/services/api-key-service.js +33 -9
- package/dist/services/api-key-service.js.map +1 -1
- package/dist/services/config-service.d.ts +15 -6
- package/dist/services/config-service.d.ts.map +1 -1
- package/dist/services/config-service.js +96 -50
- package/dist/services/config-service.js.map +1 -1
- package/dist/services/tenant-service.d.ts.map +1 -1
- package/dist/services/tenant-service.js +4 -4
- package/dist/services/tenant-service.js.map +1 -1
- package/dist/stratum-policies.d.ts +51 -0
- package/dist/stratum-policies.d.ts.map +1 -0
- package/dist/stratum-policies.js +217 -0
- package/dist/stratum-policies.js.map +1 -0
- package/dist/stratum-tables.d.ts.map +1 -1
- package/dist/stratum-tables.js +1 -0
- package/dist/stratum-tables.js.map +1 -1
- package/dist/stratum.d.ts +52 -7
- package/dist/stratum.d.ts.map +1 -1
- package/dist/stratum.js +75 -14
- package/dist/stratum.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ROLE_NAME = exports.STRATUM_CONTROL_ROLE = void 0;
|
|
4
|
+
exports.assertRoleName = assertRoleName;
|
|
5
|
+
exports.migrationSql = migrationSql;
|
|
6
|
+
exports.isSuperuser = isSuperuser;
|
|
7
|
+
exports.setControlRole = setControlRole;
|
|
8
|
+
exports.setApplyControlRole = setApplyControlRole;
|
|
9
|
+
/** The default name of the NOLOGIN control role (migration 032). */
|
|
10
|
+
exports.STRATUM_CONTROL_ROLE = "stratum_control";
|
|
11
|
+
/** A role name Stratum accepts: a plain lowercase identifier. */
|
|
12
|
+
exports.ROLE_NAME = /^[a-z_][a-z0-9_]{0,62}$/;
|
|
13
|
+
/** Throws when `role` is not a plain lowercase identifier. */
|
|
14
|
+
function assertRoleName(role, what) {
|
|
15
|
+
if (!exports.ROLE_NAME.test(role)) {
|
|
16
|
+
throw new Error(`[stratum] Invalid ${what} '${role}': use lowercase letters, digits and underscores`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// Migrations 029 and 031 created their helper functions with
|
|
20
|
+
// `SET app.bypass_rls = 'on'` (and `SET app.tenant_scope = ''`) clauses.
|
|
21
|
+
// PostgreSQL lets only a superuser, or a role granted SET on the parameter,
|
|
22
|
+
// put a custom setting in a function, so a fresh install by a role that is
|
|
23
|
+
// not a superuser stopped at 029. For such a role the runner drops the
|
|
24
|
+
// clauses from these two files. Migration 032 re-creates both functions
|
|
25
|
+
// without them (SECURITY DEFINER, owned by the control role) when it applies
|
|
26
|
+
// the control role, in the same run or later through
|
|
27
|
+
// stratum_apply_control_role(). Until then the functions see what their
|
|
28
|
+
// caller sees, which can only narrow what they return. A superuser runs the
|
|
29
|
+
// files as they are.
|
|
30
|
+
const SUPERSEDED_SET_CLAUSES = new Set(["029_tenant_parent_cycle_guard.sql", "031_subtree_read_scope.sql"]);
|
|
31
|
+
const APP_SET_CLAUSE = /^SET app\.[a-z_]+ = '[^']*'\n/gm;
|
|
32
|
+
/** The SQL to run for one migration file. */
|
|
33
|
+
function migrationSql(name, sql, superuser) {
|
|
34
|
+
if (superuser || !SUPERSEDED_SET_CLAUSES.has(name))
|
|
35
|
+
return sql;
|
|
36
|
+
return sql.replace(APP_SET_CLAUSE, "");
|
|
37
|
+
}
|
|
38
|
+
/** Whether the role of `client` is a superuser. */
|
|
39
|
+
async function isSuperuser(client) {
|
|
40
|
+
const res = await client.query("SELECT rolsuper FROM pg_catalog.pg_roles WHERE rolname = current_user");
|
|
41
|
+
return res.rows[0]?.rolsuper === true;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Sets stratum.control_role for the current transaction, which migration 032
|
|
45
|
+
* reads. Without a name the setting stays as the session has it.
|
|
46
|
+
*/
|
|
47
|
+
async function setControlRole(client, controlRole) {
|
|
48
|
+
if (controlRole === undefined)
|
|
49
|
+
return;
|
|
50
|
+
await client.query("SELECT pg_catalog.set_config('stratum.control_role', $1, true)", [controlRole]);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Sets stratum.apply_control_role = 'on' for the current transaction when
|
|
54
|
+
* `apply` is true. Migration 032 grants the control role to the migrating
|
|
55
|
+
* login only with this opt-in (or when the login is a superuser or already a
|
|
56
|
+
* member), because that login must be the library's admin login and never
|
|
57
|
+
* the application's.
|
|
58
|
+
*/
|
|
59
|
+
async function setApplyControlRole(client, apply) {
|
|
60
|
+
if (!apply)
|
|
61
|
+
return;
|
|
62
|
+
await client.query("SELECT pg_catalog.set_config('stratum.apply_control_role', 'on', true)");
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=migration-sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-sql.js","sourceRoot":"","sources":["../src/migration-sql.ts"],"names":[],"mappings":";;;AASA,wCAIC;AAiBD,oCAGC;AAGD,kCAKC;AAMD,wCAGC;AASD,kDAGC;AA5DD,oEAAoE;AACvD,QAAA,oBAAoB,GAAG,iBAAiB,CAAC;AAEtD,iEAAiE;AACpD,QAAA,SAAS,GAAG,yBAAyB,CAAC;AAEnD,8DAA8D;AAC9D,SAAgB,cAAc,CAAC,IAAY,EAAE,IAAY;IACvD,IAAI,CAAC,iBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,KAAK,IAAI,kDAAkD,CAAC,CAAC;IACxG,CAAC;AACH,CAAC;AAED,6DAA6D;AAC7D,yEAAyE;AACzE,4EAA4E;AAC5E,2EAA2E;AAC3E,uEAAuE;AACvE,wEAAwE;AACxE,6EAA6E;AAC7E,qDAAqD;AACrD,wEAAwE;AACxE,4EAA4E;AAC5E,qBAAqB;AACrB,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,mCAAmC,EAAE,4BAA4B,CAAC,CAAC,CAAC;AAC5G,MAAM,cAAc,GAAG,iCAAiC,CAAC;AAEzD,6CAA6C;AAC7C,SAAgB,YAAY,CAAC,IAAY,EAAE,GAAW,EAAE,SAAkB;IACxE,IAAI,SAAS,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC;IAC/D,OAAO,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,mDAAmD;AAC5C,KAAK,UAAU,WAAW,CAAC,MAA+B;IAC/D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAC5B,uEAAuE,CACxE,CAAC;IACF,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;AACxC,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,cAAc,CAAC,MAAqB,EAAE,WAA+B;IACzF,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO;IACtC,MAAM,MAAM,CAAC,KAAK,CAAC,gEAAgE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;AACtG,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,mBAAmB,CAAC,MAAqB,EAAE,KAA0B;IACzF,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,MAAM,MAAM,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;AAC/F,CAAC"}
|
|
@@ -48,9 +48,9 @@ END;
|
|
|
48
48
|
$$ language 'plpgsql';
|
|
49
49
|
|
|
50
50
|
DO $pin$ BEGIN
|
|
51
|
-
EXECUTE format(
|
|
51
|
+
EXECUTE pg_catalog.format(
|
|
52
52
|
'ALTER FUNCTION refuse_tenant_parent_cycle() SET search_path = pg_catalog, %I',
|
|
53
|
-
current_schema()
|
|
53
|
+
pg_catalog.current_schema()
|
|
54
54
|
);
|
|
55
55
|
END $pin$;
|
|
56
56
|
|
|
@@ -106,9 +106,9 @@ AS $$
|
|
|
106
106
|
$$;
|
|
107
107
|
|
|
108
108
|
DO $pin$ BEGIN
|
|
109
|
-
EXECUTE format(
|
|
109
|
+
EXECUTE pg_catalog.format(
|
|
110
110
|
'ALTER FUNCTION stratum_subtree_tenant_ids() SET search_path = pg_catalog, %I, pg_temp',
|
|
111
|
-
current_schema()
|
|
111
|
+
pg_catalog.current_schema()
|
|
112
112
|
);
|
|
113
113
|
END $pin$;
|
|
114
114
|
|
|
@@ -255,9 +255,9 @@ END;
|
|
|
255
255
|
$$ language 'plpgsql';
|
|
256
256
|
|
|
257
257
|
DO $pin$ BEGIN
|
|
258
|
-
EXECUTE format(
|
|
258
|
+
EXECUTE pg_catalog.format(
|
|
259
259
|
'ALTER FUNCTION refuse_tenant_tree_column_change() SET search_path = pg_catalog, %I, pg_temp',
|
|
260
|
-
current_schema()
|
|
260
|
+
pg_catalog.current_schema()
|
|
261
261
|
);
|
|
262
262
|
END $pin$;
|
|
263
263
|
|
|
@@ -300,8 +300,8 @@ END;
|
|
|
300
300
|
$$ language 'plpgsql';
|
|
301
301
|
|
|
302
302
|
DO $pin$ BEGIN
|
|
303
|
-
EXECUTE format(
|
|
303
|
+
EXECUTE pg_catalog.format(
|
|
304
304
|
'ALTER FUNCTION refuse_tenant_parent_cycle() SET search_path = pg_catalog, %I, pg_temp',
|
|
305
|
-
current_schema()
|
|
305
|
+
pg_catalog.current_schema()
|
|
306
306
|
);
|
|
307
307
|
END $pin$;
|