@nest-boot/row-level-security 7.0.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.
Files changed (118) hide show
  1. package/LICENSE +21 -0
  2. package/dist/decorators/policy.decorator.d.ts +18 -0
  3. package/dist/decorators/policy.decorator.js +257 -0
  4. package/dist/decorators/policy.decorator.js.map +1 -0
  5. package/dist/decorators/policy.decorator.spec.d.ts +1 -0
  6. package/dist/decorators/policy.decorator.spec.js +498 -0
  7. package/dist/decorators/policy.decorator.spec.js.map +1 -0
  8. package/dist/enums/policy-command.enum.d.ts +13 -0
  9. package/dist/enums/policy-command.enum.js +18 -0
  10. package/dist/enums/policy-command.enum.js.map +1 -0
  11. package/dist/enums/policy-mode.enum.d.ts +7 -0
  12. package/dist/enums/policy-mode.enum.js +12 -0
  13. package/dist/enums/policy-mode.enum.js.map +1 -0
  14. package/dist/index.d.ts +9 -0
  15. package/dist/index.js +26 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/index.spec.d.ts +1 -0
  18. package/dist/index.spec.js +70 -0
  19. package/dist/index.spec.js.map +1 -0
  20. package/dist/interfaces/index.d.ts +5 -0
  21. package/dist/interfaces/index.js +21 -0
  22. package/dist/interfaces/index.js.map +1 -0
  23. package/dist/interfaces/policy-metadata.interface.d.ts +62 -0
  24. package/dist/interfaces/policy-metadata.interface.js +3 -0
  25. package/dist/interfaces/policy-metadata.interface.js.map +1 -0
  26. package/dist/interfaces/policy-options.interface.d.ts +21 -0
  27. package/dist/interfaces/policy-options.interface.js +3 -0
  28. package/dist/interfaces/policy-options.interface.js.map +1 -0
  29. package/dist/interfaces/policy-sql-options.interface.d.ts +21 -0
  30. package/dist/interfaces/policy-sql-options.interface.js +3 -0
  31. package/dist/interfaces/policy-sql-options.interface.js.map +1 -0
  32. package/dist/interfaces/row-level-security-migration-generator.interface.d.ts +65 -0
  33. package/dist/interfaces/row-level-security-migration-generator.interface.js +3 -0
  34. package/dist/interfaces/row-level-security-migration-generator.interface.js.map +1 -0
  35. package/dist/interfaces/row-level-security-options.interface.d.ts +18 -0
  36. package/dist/interfaces/row-level-security-options.interface.js +3 -0
  37. package/dist/interfaces/row-level-security-options.interface.js.map +1 -0
  38. package/dist/row-level-security-context.d.ts +14 -0
  39. package/dist/row-level-security-context.js +38 -0
  40. package/dist/row-level-security-context.js.map +1 -0
  41. package/dist/row-level-security-context.spec.d.ts +1 -0
  42. package/dist/row-level-security-context.spec.js +29 -0
  43. package/dist/row-level-security-context.spec.js.map +1 -0
  44. package/dist/row-level-security-entity-manager.d.ts +22 -0
  45. package/dist/row-level-security-entity-manager.js +135 -0
  46. package/dist/row-level-security-entity-manager.js.map +1 -0
  47. package/dist/row-level-security-entity-manager.spec.d.ts +1 -0
  48. package/dist/row-level-security-entity-manager.spec.js +200 -0
  49. package/dist/row-level-security-entity-manager.spec.js.map +1 -0
  50. package/dist/row-level-security-migration-generator.d.ts +14 -0
  51. package/dist/row-level-security-migration-generator.js +294 -0
  52. package/dist/row-level-security-migration-generator.js.map +1 -0
  53. package/dist/row-level-security-migration-generator.spec.d.ts +1 -0
  54. package/dist/row-level-security-migration-generator.spec.js +468 -0
  55. package/dist/row-level-security-migration-generator.spec.js.map +1 -0
  56. package/dist/row-level-security-migration.d.ts +11 -0
  57. package/dist/row-level-security-migration.js +28 -0
  58. package/dist/row-level-security-migration.js.map +1 -0
  59. package/dist/row-level-security-migration.spec.d.ts +1 -0
  60. package/dist/row-level-security-migration.spec.js +40 -0
  61. package/dist/row-level-security-migration.spec.js.map +1 -0
  62. package/dist/tsconfig.build.tsbuildinfo +1 -0
  63. package/dist/tsconfig.tsbuildinfo +1 -0
  64. package/dist/utils/assert-identifier.d.ts +2 -0
  65. package/dist/utils/assert-identifier.js +11 -0
  66. package/dist/utils/assert-identifier.js.map +1 -0
  67. package/dist/utils/assert-snake-case.d.ts +2 -0
  68. package/dist/utils/assert-snake-case.js +10 -0
  69. package/dist/utils/assert-snake-case.js.map +1 -0
  70. package/dist/utils/create-policy-bootstrap-sql-statements.d.ts +2 -0
  71. package/dist/utils/create-policy-bootstrap-sql-statements.js +17 -0
  72. package/dist/utils/create-policy-bootstrap-sql-statements.js.map +1 -0
  73. package/dist/utils/create-policy-down-sql.d.ts +3 -0
  74. package/dist/utils/create-policy-down-sql.js +30 -0
  75. package/dist/utils/create-policy-down-sql.js.map +1 -0
  76. package/dist/utils/create-policy-up-sql-statements.d.ts +3 -0
  77. package/dist/utils/create-policy-up-sql-statements.js +114 -0
  78. package/dist/utils/create-policy-up-sql-statements.js.map +1 -0
  79. package/dist/utils/default-row-level-security-options.d.ts +3 -0
  80. package/dist/utils/default-row-level-security-options.js +9 -0
  81. package/dist/utils/default-row-level-security-options.js.map +1 -0
  82. package/dist/utils/escape-sql-literal.d.ts +2 -0
  83. package/dist/utils/escape-sql-literal.js +8 -0
  84. package/dist/utils/escape-sql-literal.js.map +1 -0
  85. package/dist/utils/get-row-level-security-options.d.ts +8 -0
  86. package/dist/utils/get-row-level-security-options.js +9 -0
  87. package/dist/utils/get-row-level-security-options.js.map +1 -0
  88. package/dist/utils/index.d.ts +13 -0
  89. package/dist/utils/index.js +29 -0
  90. package/dist/utils/index.js.map +1 -0
  91. package/dist/utils/policy-migration-sql.spec.d.ts +1 -0
  92. package/dist/utils/policy-migration-sql.spec.js +168 -0
  93. package/dist/utils/policy-migration-sql.spec.js.map +1 -0
  94. package/dist/utils/policy-sql-options.d.ts +12 -0
  95. package/dist/utils/policy-sql-options.js +3 -0
  96. package/dist/utils/policy-sql-options.js.map +1 -0
  97. package/dist/utils/quote-identifier.d.ts +2 -0
  98. package/dist/utils/quote-identifier.js +10 -0
  99. package/dist/utils/quote-identifier.js.map +1 -0
  100. package/dist/utils/quote-qualified-identifier.d.ts +2 -0
  101. package/dist/utils/quote-qualified-identifier.js +9 -0
  102. package/dist/utils/quote-qualified-identifier.js.map +1 -0
  103. package/dist/utils/row-level-security-context-builder.d.ts +12 -0
  104. package/dist/utils/row-level-security-context-builder.js +40 -0
  105. package/dist/utils/row-level-security-context-builder.js.map +1 -0
  106. package/dist/utils/row-level-security-context-builder.spec.d.ts +1 -0
  107. package/dist/utils/row-level-security-context-builder.spec.js +40 -0
  108. package/dist/utils/row-level-security-context-builder.spec.js.map +1 -0
  109. package/dist/utils/row-level-security-context-builder.types.d.ts +10 -0
  110. package/dist/utils/row-level-security-context-builder.types.js +3 -0
  111. package/dist/utils/row-level-security-context-builder.types.js.map +1 -0
  112. package/dist/utils/row-level-security-options-state.d.ts +4 -0
  113. package/dist/utils/row-level-security-options-state.js +8 -0
  114. package/dist/utils/row-level-security-options-state.js.map +1 -0
  115. package/dist/utils/set-row-level-security-options.d.ts +3 -0
  116. package/dist/utils/set-row-level-security-options.js +13 -0
  117. package/dist/utils/set-row-level-security-options.js.map +1 -0
  118. package/package.json +77 -0
@@ -0,0 +1,2 @@
1
+ /** Asserts that a value is a safe unquoted PostgreSQL identifier. */
2
+ export declare function assertIdentifier(identifier: string): string;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertIdentifier = assertIdentifier;
4
+ /** Asserts that a value is a safe unquoted PostgreSQL identifier. */
5
+ function assertIdentifier(identifier) {
6
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier)) {
7
+ throw new Error(`Invalid SQL identifier: ${identifier}`);
8
+ }
9
+ return identifier;
10
+ }
11
+ //# sourceMappingURL=assert-identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-identifier.js","sourceRoot":"","sources":["../../src/utils/assert-identifier.ts"],"names":[],"mappings":";;AACA,4CAMC;AAPD,qEAAqE;AACrE,SAAgB,gBAAgB,CAAC,UAAkB;IACjD,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Asserts that a value is snake_case for use in roles or context keys. */
2
+ export declare function assertSnakeCase(value: string, label: string): void;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertSnakeCase = assertSnakeCase;
4
+ /** Asserts that a value is snake_case for use in roles or context keys. */
5
+ function assertSnakeCase(value, label) {
6
+ if (!/^[a-z]+(_[a-z]+)*$/.test(value)) {
7
+ throw new Error(`${label} must be snake_case: ${value}`);
8
+ }
9
+ }
10
+ //# sourceMappingURL=assert-snake-case.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-snake-case.js","sourceRoot":"","sources":["../../src/utils/assert-snake-case.ts"],"names":[],"mappings":";;AACA,0CAIC;AALD,2EAA2E;AAC3E,SAAgB,eAAe,CAAC,KAAa,EAAE,KAAa;IAC1D,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,wBAAwB,KAAK,EAAE,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Creates SQL statements for shared RLS roles, grants, schema, and `app.get_context`. */
2
+ export declare function createPolicyBootstrapSqlStatements(): string[];
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPolicyBootstrapSqlStatements = createPolicyBootstrapSqlStatements;
4
+ /** Creates SQL statements for shared RLS roles, grants, schema, and `app.get_context`. */
5
+ function createPolicyBootstrapSqlStatements() {
6
+ return [
7
+ "do $$ begin if not exists (select 1 from pg_roles where rolname = 'authenticated') then create role authenticated nologin; end if; end $$;",
8
+ "do $$ begin if not exists (select 1 from pg_roles where rolname = 'anonymous') then create role anonymous nologin; end if; end $$;",
9
+ "grant authenticated to current_user;",
10
+ "grant anonymous to current_user;",
11
+ "create schema if not exists app;",
12
+ "grant usage on schema app to authenticated;",
13
+ "grant usage on schema app to anonymous;",
14
+ "create or replace function app.get_context(context_key text, context_type anyelement) returns anyelement as $$ declare context_value text; begin context_value := current_setting('app.' || context_key, true); if context_value is null or context_value = '' then return null; end if; execute format('select $1::%s', pg_typeof(context_type)::text) using context_value into context_type; return context_type; end; $$ language plpgsql stable;",
15
+ ];
16
+ }
17
+ //# sourceMappingURL=create-policy-bootstrap-sql-statements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-policy-bootstrap-sql-statements.js","sourceRoot":"","sources":["../../src/utils/create-policy-bootstrap-sql-statements.ts"],"names":[],"mappings":";;AACA,gFAWC;AAZD,0FAA0F;AAC1F,SAAgB,kCAAkC;IAChD,OAAO;QACL,4IAA4I;QAC5I,oIAAoI;QACpI,sCAAsC;QACtC,kCAAkC;QAClC,kCAAkC;QAClC,6CAA6C;QAC7C,yCAAyC;QACzC,sbAAsb;KACvb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PolicySqlOptions } from "../interfaces/policy-sql-options.interface";
2
+ /** Creates guarded SQL for dropping a policy and disabling RLS when no policies remain. */
3
+ export declare function createPolicyDownSql(options: PolicySqlOptions): string;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPolicyDownSql = createPolicyDownSql;
4
+ const assert_identifier_1 = require("./assert-identifier");
5
+ const quote_qualified_identifier_1 = require("./quote-qualified-identifier");
6
+ /** Creates guarded SQL for dropping a policy and disabling RLS when no policies remain. */
7
+ function createPolicyDownSql(options) {
8
+ const tableIdentifier = (0, quote_qualified_identifier_1.quoteQualifiedIdentifier)(options.schemaName, options.tableName);
9
+ const policyName = (0, assert_identifier_1.assertIdentifier)(options.policyName);
10
+ return /* SQL */ `
11
+ do $$
12
+ declare
13
+ policy_count integer;
14
+ begin
15
+ if to_regclass('${tableIdentifier}') is not null then
16
+ execute 'drop policy if exists ${policyName} on ${tableIdentifier}';
17
+
18
+ select count(*) into policy_count
19
+ from pg_policies
20
+ where schemaname = '${options.schemaName}' and tablename = '${options.tableName}';
21
+
22
+ if policy_count = 0 then
23
+ execute 'alter table ${tableIdentifier} disable row level security';
24
+ end if;
25
+ end if;
26
+ end
27
+ $$;
28
+ `.trim();
29
+ }
30
+ //# sourceMappingURL=create-policy-down-sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-policy-down-sql.js","sourceRoot":"","sources":["../../src/utils/create-policy-down-sql.ts"],"names":[],"mappings":";;AAKA,kDA0BC;AA9BD,2DAAuD;AACvD,6EAAwE;AAExE,2FAA2F;AAC3F,SAAgB,mBAAmB,CAAC,OAAyB;IAC3D,MAAM,eAAe,GAAG,IAAA,qDAAwB,EAC9C,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,SAAS,CAClB,CAAC;IACF,MAAM,UAAU,GAAG,IAAA,oCAAgB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAExD,OAAO,SAAS,CAAC;;;;;oBAKC,eAAe;qCACE,UAAU,OAAO,eAAe;;;;0BAI3C,OAAO,CAAC,UAAU,sBAAsB,OAAO,CAAC,SAAS;;;6BAGtD,eAAe;;;;;CAK3C,CAAC,IAAI,EAAE,CAAC;AACT,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PolicySqlOptions } from "../interfaces/policy-sql-options.interface";
2
+ /** Creates SQL statements that enable RLS and recreate a PostgreSQL policy. */
3
+ export declare function createPolicyUpSqlStatements(options: PolicySqlOptions): string[];
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPolicyUpSqlStatements = createPolicyUpSqlStatements;
4
+ const policy_command_enum_1 = require("../enums/policy-command.enum");
5
+ const policy_mode_enum_1 = require("../enums/policy-mode.enum");
6
+ const assert_identifier_1 = require("./assert-identifier");
7
+ const escape_sql_literal_1 = require("./escape-sql-literal");
8
+ const quote_qualified_identifier_1 = require("./quote-qualified-identifier");
9
+ /** Creates SQL statements that enable RLS and recreate a PostgreSQL policy. */
10
+ function createPolicyUpSqlStatements(options) {
11
+ const tableIdentifier = (0, quote_qualified_identifier_1.quoteQualifiedIdentifier)(options.schemaName, options.tableName);
12
+ const policyName = (0, assert_identifier_1.assertIdentifier)(options.policyName);
13
+ const mode = options.mode ?? policy_mode_enum_1.PolicyMode.PERMISSIVE;
14
+ const command = options.command ?? policy_command_enum_1.PolicyCommand.ALL;
15
+ const roles = options.roles ?? [];
16
+ const roleSql = roles.map((role) => (0, assert_identifier_1.assertIdentifier)(role)).join(", ");
17
+ const predicates = getPolicyPredicates(options);
18
+ return [
19
+ `alter table ${tableIdentifier} enable row level security;`,
20
+ ...createPrivilegeGrantSqlStatements(options, tableIdentifier, roleSql),
21
+ `drop policy if exists ${policyName} on ${tableIdentifier};`,
22
+ `create policy ${policyName} on ${tableIdentifier} as ${mode} for ${command}${roleSql ? ` to ${roleSql}` : ""} ${getPolicyPredicateSql(command, predicates)};`,
23
+ ];
24
+ }
25
+ function createPrivilegeGrantSqlStatements(options, tableIdentifier, roleSql) {
26
+ if (!roleSql) {
27
+ return [];
28
+ }
29
+ const command = options.command ?? policy_command_enum_1.PolicyCommand.ALL;
30
+ const privileges = getTablePrivileges(command).join(", ");
31
+ const statements = [
32
+ `grant ${privileges} on table ${tableIdentifier} to ${roleSql};`,
33
+ ];
34
+ if (requiresSequencePrivileges(command)) {
35
+ statements.push(createSequenceGrantSql(options, tableIdentifier, roleSql));
36
+ }
37
+ return statements;
38
+ }
39
+ function getTablePrivileges(command) {
40
+ if (command === policy_command_enum_1.PolicyCommand.SELECT) {
41
+ return ["select"];
42
+ }
43
+ if (command === policy_command_enum_1.PolicyCommand.INSERT) {
44
+ return ["insert"];
45
+ }
46
+ if (command === policy_command_enum_1.PolicyCommand.UPDATE) {
47
+ return ["select", "update"];
48
+ }
49
+ if (command === policy_command_enum_1.PolicyCommand.DELETE) {
50
+ return ["select", "delete"];
51
+ }
52
+ return ["select", "insert", "update", "delete"];
53
+ }
54
+ function requiresSequencePrivileges(command) {
55
+ return command === policy_command_enum_1.PolicyCommand.INSERT || command === policy_command_enum_1.PolicyCommand.ALL;
56
+ }
57
+ function createSequenceGrantSql(options, tableIdentifier, roleSql) {
58
+ const tableLiteral = (0, escape_sql_literal_1.escapeSqlLiteral)(tableIdentifier);
59
+ const schemaName = (0, escape_sql_literal_1.escapeSqlLiteral)(options.schemaName);
60
+ const tableName = (0, escape_sql_literal_1.escapeSqlLiteral)(options.tableName);
61
+ return /* SQL */ `do $$ declare sequence_identifier text; begin for sequence_identifier in select pg_get_serial_sequence('${tableLiteral}', columns.column_name) from information_schema.columns where columns.table_schema = '${schemaName}' and columns.table_name = '${tableName}' and pg_get_serial_sequence('${tableLiteral}', columns.column_name) is not null loop execute format('grant usage, select on sequence %s to ${roleSql}', sequence_identifier); end loop; end $$;`;
62
+ }
63
+ function getPolicyPredicates(options) {
64
+ const command = options.command ?? policy_command_enum_1.PolicyCommand.ALL;
65
+ const predicates = {
66
+ using: normalizeExpression(options.using),
67
+ withCheck: normalizeExpression(options.withCheck),
68
+ };
69
+ assertPolicyPredicates(command, predicates);
70
+ return predicates;
71
+ }
72
+ function normalizeExpression(expression) {
73
+ const normalized = expression?.trim();
74
+ if (!normalized) {
75
+ return undefined;
76
+ }
77
+ return normalized;
78
+ }
79
+ function assertPolicyPredicates(command, predicates) {
80
+ if (command === policy_command_enum_1.PolicyCommand.SELECT || command === policy_command_enum_1.PolicyCommand.DELETE) {
81
+ if (!predicates.using) {
82
+ throw new Error("Policy using expression is required");
83
+ }
84
+ if (predicates.withCheck) {
85
+ throw new Error(`Policy withCheck is not allowed for ${command}`);
86
+ }
87
+ return;
88
+ }
89
+ if (command === policy_command_enum_1.PolicyCommand.INSERT) {
90
+ if (predicates.using) {
91
+ throw new Error("Policy using is not allowed for insert");
92
+ }
93
+ if (!predicates.withCheck) {
94
+ throw new Error("Policy withCheck expression is required");
95
+ }
96
+ return;
97
+ }
98
+ if (!predicates.using && !predicates.withCheck) {
99
+ throw new Error("Policy using or withCheck expression is required");
100
+ }
101
+ }
102
+ function getPolicyPredicateSql(command, predicates) {
103
+ const fragments = [];
104
+ if (command !== policy_command_enum_1.PolicyCommand.INSERT && predicates.using) {
105
+ fragments.push(`using ${predicates.using}`);
106
+ }
107
+ if (command !== policy_command_enum_1.PolicyCommand.SELECT &&
108
+ command !== policy_command_enum_1.PolicyCommand.DELETE &&
109
+ predicates.withCheck) {
110
+ fragments.push(`with check ${predicates.withCheck}`);
111
+ }
112
+ return fragments.join(" ");
113
+ }
114
+ //# sourceMappingURL=create-policy-up-sql-statements.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-policy-up-sql-statements.js","sourceRoot":"","sources":["../../src/utils/create-policy-up-sql-statements.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { RowLevelSecurityOptions } from "../interfaces/row-level-security-options.interface";
2
+ /** Default RLS database roles. */
3
+ export declare const DEFAULT_ROW_LEVEL_SECURITY_OPTIONS: Required<Pick<RowLevelSecurityOptions, "authenticatedRole" | "anonymousRole">>;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_ROW_LEVEL_SECURITY_OPTIONS = void 0;
4
+ /** Default RLS database roles. */
5
+ exports.DEFAULT_ROW_LEVEL_SECURITY_OPTIONS = {
6
+ authenticatedRole: "authenticated",
7
+ anonymousRole: "anonymous",
8
+ };
9
+ //# sourceMappingURL=default-row-level-security-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-row-level-security-options.js","sourceRoot":"","sources":["../../src/utils/default-row-level-security-options.ts"],"names":[],"mappings":";;;AAEA,kCAAkC;AACrB,QAAA,kCAAkC,GAE3C;IACF,iBAAiB,EAAE,eAAe;IAClC,aAAa,EAAE,WAAW;CAC3B,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Escapes a string for use inside a single-quoted SQL literal. */
2
+ export declare function escapeSqlLiteral(value: string): string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.escapeSqlLiteral = escapeSqlLiteral;
4
+ /** Escapes a string for use inside a single-quoted SQL literal. */
5
+ function escapeSqlLiteral(value) {
6
+ return value.replace(/'/g, "''");
7
+ }
8
+ //# sourceMappingURL=escape-sql-literal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escape-sql-literal.js","sourceRoot":"","sources":["../../src/utils/escape-sql-literal.ts"],"names":[],"mappings":";;AACA,4CAEC;AAHD,mEAAmE;AACnE,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /** Reads the process-level RLS options used by the entity manager. */
2
+ export declare function getRowLevelSecurityOptions(): {
3
+ authenticatedRole?: string;
4
+ anonymousRole?: string;
5
+ shouldApply?: () => import("..").MaybePromise<boolean>;
6
+ isAuthenticated?: () => import("..").MaybePromise<boolean>;
7
+ getContext?: () => import("..").MaybePromise<import("..").RowLevelSecurityContextEntries | undefined>;
8
+ };
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRowLevelSecurityOptions = getRowLevelSecurityOptions;
4
+ const row_level_security_options_state_1 = require("./row-level-security-options-state");
5
+ /** Reads the process-level RLS options used by the entity manager. */
6
+ function getRowLevelSecurityOptions() {
7
+ return { ...row_level_security_options_state_1.rowLevelSecurityOptionsState.value };
8
+ }
9
+ //# sourceMappingURL=get-row-level-security-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-row-level-security-options.js","sourceRoot":"","sources":["../../src/utils/get-row-level-security-options.ts"],"names":[],"mappings":";;AAGA,gEAEC;AALD,yFAAkF;AAElF,sEAAsE;AACtE,SAAgB,0BAA0B;IACxC,OAAO,EAAE,GAAG,+DAA4B,CAAC,KAAK,EAAE,CAAC;AACnD,CAAC"}
@@ -0,0 +1,13 @@
1
+ export * from "./assert-identifier";
2
+ export * from "./assert-snake-case";
3
+ export * from "./create-policy-bootstrap-sql-statements";
4
+ export * from "./create-policy-down-sql";
5
+ export * from "./create-policy-up-sql-statements";
6
+ export * from "./default-row-level-security-options";
7
+ export * from "./escape-sql-literal";
8
+ export * from "./get-row-level-security-options";
9
+ export * from "./quote-identifier";
10
+ export * from "./quote-qualified-identifier";
11
+ export * from "./row-level-security-context-builder";
12
+ export type * from "./row-level-security-context-builder.types";
13
+ export * from "./set-row-level-security-options";
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./assert-identifier"), exports);
18
+ __exportStar(require("./assert-snake-case"), exports);
19
+ __exportStar(require("./create-policy-bootstrap-sql-statements"), exports);
20
+ __exportStar(require("./create-policy-down-sql"), exports);
21
+ __exportStar(require("./create-policy-up-sql-statements"), exports);
22
+ __exportStar(require("./default-row-level-security-options"), exports);
23
+ __exportStar(require("./escape-sql-literal"), exports);
24
+ __exportStar(require("./get-row-level-security-options"), exports);
25
+ __exportStar(require("./quote-identifier"), exports);
26
+ __exportStar(require("./quote-qualified-identifier"), exports);
27
+ __exportStar(require("./row-level-security-context-builder"), exports);
28
+ __exportStar(require("./set-row-level-security-options"), exports);
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,sDAAoC;AACpC,2EAAyD;AACzD,2DAAyC;AACzC,oEAAkD;AAClD,uEAAqD;AACrD,uDAAqC;AACrC,mEAAiD;AACjD,qDAAmC;AACnC,+DAA6C;AAC7C,uEAAqD;AAErD,mEAAiD"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const policy_command_enum_1 = require("../enums/policy-command.enum");
4
+ const policy_mode_enum_1 = require("../enums/policy-mode.enum");
5
+ const create_policy_bootstrap_sql_statements_1 = require("./create-policy-bootstrap-sql-statements");
6
+ const create_policy_down_sql_1 = require("./create-policy-down-sql");
7
+ const create_policy_up_sql_statements_1 = require("./create-policy-up-sql-statements");
8
+ describe("policy migration SQL", () => {
9
+ it("generates row level security bootstrap SQL", () => {
10
+ const statements = (0, create_policy_bootstrap_sql_statements_1.createPolicyBootstrapSqlStatements)();
11
+ expect(statements).toEqual([
12
+ "do $$ begin if not exists (select 1 from pg_roles where rolname = 'authenticated') then create role authenticated nologin; end if; end $$;",
13
+ "do $$ begin if not exists (select 1 from pg_roles where rolname = 'anonymous') then create role anonymous nologin; end if; end $$;",
14
+ "grant authenticated to current_user;",
15
+ "grant anonymous to current_user;",
16
+ "create schema if not exists app;",
17
+ "grant usage on schema app to authenticated;",
18
+ "grant usage on schema app to anonymous;",
19
+ "create or replace function app.get_context(context_key text, context_type anyelement) returns anyelement as $$ declare context_value text; begin context_value := current_setting('app.' || context_key, true); if context_value is null or context_value = '' then return null; end if; execute format('select $1::%s', pg_typeof(context_type)::text) using context_value into context_type; return context_type; end; $$ language plpgsql stable;",
20
+ ]);
21
+ expect(statements.join("\n")).not.toContain("grant all on all tables");
22
+ expect(statements.join("\n")).not.toContain("get_policy_context");
23
+ });
24
+ it("generates policy up SQL", () => {
25
+ const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
26
+ schemaName: "public",
27
+ tableName: "workspace_member",
28
+ policyName: "workspace_member_user_select_policy",
29
+ command: policy_command_enum_1.PolicyCommand.SELECT,
30
+ using: `((select app.get_context('user_id', null::bigint)) = "user_id")`,
31
+ });
32
+ expect(statements).toEqual([
33
+ 'alter table "public"."workspace_member" enable row level security;',
34
+ 'drop policy if exists workspace_member_user_select_policy on "public"."workspace_member";',
35
+ 'create policy workspace_member_user_select_policy on "public"."workspace_member" as permissive for select using ((select app.get_context(\'user_id\', null::bigint)) = "user_id");',
36
+ ]);
37
+ });
38
+ it("generates policy SQL for explicit roles", () => {
39
+ const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
40
+ schemaName: "public",
41
+ tableName: "workspace_member",
42
+ policyName: "workspace_member_user_select_policy",
43
+ command: policy_command_enum_1.PolicyCommand.SELECT,
44
+ using: `((select app.get_context('user_id', null::bigint)) = "user_id")`,
45
+ roles: ["authenticated", "anonymous"],
46
+ });
47
+ expect(statements[2]).toBe('drop policy if exists workspace_member_user_select_policy on "public"."workspace_member";');
48
+ });
49
+ it("generates table grants for explicit policy roles", () => {
50
+ const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
51
+ schemaName: "public",
52
+ tableName: "workspace_member",
53
+ policyName: "workspace_member_user_select_policy",
54
+ command: policy_command_enum_1.PolicyCommand.SELECT,
55
+ using: `((select app.get_context('user_id', null::bigint)) = "user_id")`,
56
+ roles: ["authenticated", "anonymous"],
57
+ });
58
+ expect(statements).toEqual([
59
+ 'alter table "public"."workspace_member" enable row level security;',
60
+ 'grant select on table "public"."workspace_member" to authenticated, anonymous;',
61
+ 'drop policy if exists workspace_member_user_select_policy on "public"."workspace_member";',
62
+ 'create policy workspace_member_user_select_policy on "public"."workspace_member" as permissive for select to authenticated, anonymous using ((select app.get_context(\'user_id\', null::bigint)) = "user_id");',
63
+ ]);
64
+ });
65
+ it("generates sequence grants for explicit insert policy roles", () => {
66
+ const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
67
+ schemaName: "public",
68
+ tableName: "workspace_member",
69
+ policyName: "workspace_member_insert_policy",
70
+ command: policy_command_enum_1.PolicyCommand.INSERT,
71
+ withCheck: "true",
72
+ roles: ["authenticated"],
73
+ });
74
+ expect(statements).toContain('grant insert on table "public"."workspace_member" to authenticated;');
75
+ expect(statements).toEqual(expect.arrayContaining([
76
+ expect.stringContaining("pg_get_serial_sequence"),
77
+ expect.stringContaining("grant usage, select on sequence %s to authenticated"),
78
+ ]));
79
+ });
80
+ it("generates restrictive policy SQL", () => {
81
+ const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
82
+ schemaName: "public",
83
+ tableName: "workspace_member",
84
+ policyName: "tenant_required_policy",
85
+ mode: policy_mode_enum_1.PolicyMode.RESTRICTIVE,
86
+ using: `((select app.get_context('tenant_id', null::bigint)) is not null)`,
87
+ });
88
+ expect(statements[2]).toBe('create policy tenant_required_policy on "public"."workspace_member" as restrictive for all using ((select app.get_context(\'tenant_id\', null::bigint)) is not null);');
89
+ });
90
+ it("generates insert policy SQL with only a with check predicate", () => {
91
+ const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
92
+ schemaName: "public",
93
+ tableName: "workspace_member",
94
+ policyName: "workspace_member_insert_policy",
95
+ command: policy_command_enum_1.PolicyCommand.INSERT,
96
+ withCheck: ` true `,
97
+ });
98
+ expect(statements[2]).toBe('create policy workspace_member_insert_policy on "public"."workspace_member" as permissive for insert with check true;');
99
+ });
100
+ it.each([
101
+ [
102
+ "select without using",
103
+ {
104
+ schemaName: "public",
105
+ tableName: "workspace_member",
106
+ policyName: "workspace_member_select_policy",
107
+ command: policy_command_enum_1.PolicyCommand.SELECT,
108
+ },
109
+ "Policy using expression is required",
110
+ ],
111
+ [
112
+ "delete with withCheck",
113
+ {
114
+ schemaName: "public",
115
+ tableName: "workspace_member",
116
+ policyName: "workspace_member_delete_policy",
117
+ command: policy_command_enum_1.PolicyCommand.DELETE,
118
+ using: "true",
119
+ withCheck: "true",
120
+ },
121
+ "Policy withCheck is not allowed for delete",
122
+ ],
123
+ [
124
+ "insert with using",
125
+ {
126
+ schemaName: "public",
127
+ tableName: "workspace_member",
128
+ policyName: "workspace_member_insert_policy",
129
+ command: policy_command_enum_1.PolicyCommand.INSERT,
130
+ using: "true",
131
+ withCheck: "true",
132
+ },
133
+ "Policy using is not allowed for insert",
134
+ ],
135
+ [
136
+ "insert without withCheck",
137
+ {
138
+ schemaName: "public",
139
+ tableName: "workspace_member",
140
+ policyName: "workspace_member_insert_policy",
141
+ command: policy_command_enum_1.PolicyCommand.INSERT,
142
+ },
143
+ "Policy withCheck expression is required",
144
+ ],
145
+ [
146
+ "all without predicates",
147
+ {
148
+ schemaName: "public",
149
+ tableName: "workspace_member",
150
+ policyName: "workspace_member_all_policy",
151
+ },
152
+ "Policy using or withCheck expression is required",
153
+ ],
154
+ ])("rejects %s", (_name, options, message) => {
155
+ expect(() => (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)(options)).toThrow(message);
156
+ });
157
+ it("generates guarded policy down SQL", () => {
158
+ const sql = (0, create_policy_down_sql_1.createPolicyDownSql)({
159
+ schemaName: "public",
160
+ tableName: "workspace_member",
161
+ policyName: "workspace_member_user_select_policy",
162
+ });
163
+ expect(sql).toContain('to_regclass(\'"public"."workspace_member"\')');
164
+ expect(sql).toContain('drop policy if exists workspace_member_user_select_policy on "public"."workspace_member"');
165
+ expect(sql).toContain("disable row level security");
166
+ });
167
+ });
168
+ //# sourceMappingURL=policy-migration-sql.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-migration-sql.spec.js","sourceRoot":"","sources":["../../src/utils/policy-migration-sql.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { PolicyCommand } from "../enums/policy-command.enum";
2
+ import { PolicyMode } from "../enums/policy-mode.enum";
3
+ export interface PolicySqlOptions {
4
+ schemaName: string;
5
+ tableName: string;
6
+ policyName: string;
7
+ mode?: PolicyMode;
8
+ command?: PolicyCommand;
9
+ using?: string;
10
+ withCheck?: string;
11
+ roles?: string[];
12
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=policy-sql-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-sql-options.js","sourceRoot":"","sources":["../../src/utils/policy-sql-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ /** Quotes a validated PostgreSQL identifier. */
2
+ export declare function quoteIdentifier(identifier: string): string;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.quoteIdentifier = quoteIdentifier;
4
+ const assert_identifier_1 = require("./assert-identifier");
5
+ /** Quotes a validated PostgreSQL identifier. */
6
+ function quoteIdentifier(identifier) {
7
+ (0, assert_identifier_1.assertIdentifier)(identifier);
8
+ return `"${identifier}"`;
9
+ }
10
+ //# sourceMappingURL=quote-identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote-identifier.js","sourceRoot":"","sources":["../../src/utils/quote-identifier.ts"],"names":[],"mappings":";;AAGA,0CAIC;AAPD,2DAAuD;AAEvD,gDAAgD;AAChD,SAAgB,eAAe,CAAC,UAAkB;IAChD,IAAA,oCAAgB,EAAC,UAAU,CAAC,CAAC;IAE7B,OAAO,IAAI,UAAU,GAAG,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** Quotes a schema-qualified PostgreSQL table identifier. */
2
+ export declare function quoteQualifiedIdentifier(schemaName: string, tableName: string): string;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.quoteQualifiedIdentifier = quoteQualifiedIdentifier;
4
+ const quote_identifier_1 = require("./quote-identifier");
5
+ /** Quotes a schema-qualified PostgreSQL table identifier. */
6
+ function quoteQualifiedIdentifier(schemaName, tableName) {
7
+ return `${(0, quote_identifier_1.quoteIdentifier)(schemaName)}.${(0, quote_identifier_1.quoteIdentifier)(tableName)}`;
8
+ }
9
+ //# sourceMappingURL=quote-qualified-identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote-qualified-identifier.js","sourceRoot":"","sources":["../../src/utils/quote-qualified-identifier.ts"],"names":[],"mappings":";;AAGA,4DAKC;AARD,yDAAqD;AAErD,6DAA6D;AAC7D,SAAgB,wBAAwB,CACtC,UAAkB,EAClB,SAAiB;IAEjB,OAAO,GAAG,IAAA,kCAAe,EAAC,UAAU,CAAC,IAAI,IAAA,kCAAe,EAAC,SAAS,CAAC,EAAE,CAAC;AACxE,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { RowLevelSecurityContextValue, SnakeCase } from "./row-level-security-context-builder.types";
2
+ /** Builds SQL that writes RLS context values into PostgreSQL transaction settings. */
3
+ export declare class RowLevelSecurityContextBuilder {
4
+ private readonly ctx;
5
+ private readonly namespace;
6
+ /** Adds a context key and value, ignoring nullish values. */
7
+ set<S extends string>(key: SnakeCase<S>, value: RowLevelSecurityContextValue): this;
8
+ /** Returns the context entries that will be emitted to SQL. */
9
+ entries(): [string, string][];
10
+ /** Renders a `SELECT set_config(...)` statement for the collected entries. */
11
+ toSQL(): string;
12
+ }