@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.
- package/LICENSE +21 -0
- package/dist/decorators/policy.decorator.d.ts +18 -0
- package/dist/decorators/policy.decorator.js +257 -0
- package/dist/decorators/policy.decorator.js.map +1 -0
- package/dist/decorators/policy.decorator.spec.d.ts +1 -0
- package/dist/decorators/policy.decorator.spec.js +498 -0
- package/dist/decorators/policy.decorator.spec.js.map +1 -0
- package/dist/enums/policy-command.enum.d.ts +13 -0
- package/dist/enums/policy-command.enum.js +18 -0
- package/dist/enums/policy-command.enum.js.map +1 -0
- package/dist/enums/policy-mode.enum.d.ts +7 -0
- package/dist/enums/policy-mode.enum.js +12 -0
- package/dist/enums/policy-mode.enum.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/index.spec.d.ts +1 -0
- package/dist/index.spec.js +70 -0
- package/dist/index.spec.js.map +1 -0
- package/dist/interfaces/index.d.ts +5 -0
- package/dist/interfaces/index.js +21 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/policy-metadata.interface.d.ts +62 -0
- package/dist/interfaces/policy-metadata.interface.js +3 -0
- package/dist/interfaces/policy-metadata.interface.js.map +1 -0
- package/dist/interfaces/policy-options.interface.d.ts +21 -0
- package/dist/interfaces/policy-options.interface.js +3 -0
- package/dist/interfaces/policy-options.interface.js.map +1 -0
- package/dist/interfaces/policy-sql-options.interface.d.ts +21 -0
- package/dist/interfaces/policy-sql-options.interface.js +3 -0
- package/dist/interfaces/policy-sql-options.interface.js.map +1 -0
- package/dist/interfaces/row-level-security-migration-generator.interface.d.ts +65 -0
- package/dist/interfaces/row-level-security-migration-generator.interface.js +3 -0
- package/dist/interfaces/row-level-security-migration-generator.interface.js.map +1 -0
- package/dist/interfaces/row-level-security-options.interface.d.ts +18 -0
- package/dist/interfaces/row-level-security-options.interface.js +3 -0
- package/dist/interfaces/row-level-security-options.interface.js.map +1 -0
- package/dist/row-level-security-context.d.ts +14 -0
- package/dist/row-level-security-context.js +38 -0
- package/dist/row-level-security-context.js.map +1 -0
- package/dist/row-level-security-context.spec.d.ts +1 -0
- package/dist/row-level-security-context.spec.js +29 -0
- package/dist/row-level-security-context.spec.js.map +1 -0
- package/dist/row-level-security-entity-manager.d.ts +22 -0
- package/dist/row-level-security-entity-manager.js +135 -0
- package/dist/row-level-security-entity-manager.js.map +1 -0
- package/dist/row-level-security-entity-manager.spec.d.ts +1 -0
- package/dist/row-level-security-entity-manager.spec.js +200 -0
- package/dist/row-level-security-entity-manager.spec.js.map +1 -0
- package/dist/row-level-security-migration-generator.d.ts +14 -0
- package/dist/row-level-security-migration-generator.js +294 -0
- package/dist/row-level-security-migration-generator.js.map +1 -0
- package/dist/row-level-security-migration-generator.spec.d.ts +1 -0
- package/dist/row-level-security-migration-generator.spec.js +468 -0
- package/dist/row-level-security-migration-generator.spec.js.map +1 -0
- package/dist/row-level-security-migration.d.ts +11 -0
- package/dist/row-level-security-migration.js +28 -0
- package/dist/row-level-security-migration.js.map +1 -0
- package/dist/row-level-security-migration.spec.d.ts +1 -0
- package/dist/row-level-security-migration.spec.js +40 -0
- package/dist/row-level-security-migration.spec.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/utils/assert-identifier.d.ts +2 -0
- package/dist/utils/assert-identifier.js +11 -0
- package/dist/utils/assert-identifier.js.map +1 -0
- package/dist/utils/assert-snake-case.d.ts +2 -0
- package/dist/utils/assert-snake-case.js +10 -0
- package/dist/utils/assert-snake-case.js.map +1 -0
- package/dist/utils/create-policy-bootstrap-sql-statements.d.ts +2 -0
- package/dist/utils/create-policy-bootstrap-sql-statements.js +17 -0
- package/dist/utils/create-policy-bootstrap-sql-statements.js.map +1 -0
- package/dist/utils/create-policy-down-sql.d.ts +3 -0
- package/dist/utils/create-policy-down-sql.js +30 -0
- package/dist/utils/create-policy-down-sql.js.map +1 -0
- package/dist/utils/create-policy-up-sql-statements.d.ts +3 -0
- package/dist/utils/create-policy-up-sql-statements.js +114 -0
- package/dist/utils/create-policy-up-sql-statements.js.map +1 -0
- package/dist/utils/default-row-level-security-options.d.ts +3 -0
- package/dist/utils/default-row-level-security-options.js +9 -0
- package/dist/utils/default-row-level-security-options.js.map +1 -0
- package/dist/utils/escape-sql-literal.d.ts +2 -0
- package/dist/utils/escape-sql-literal.js +8 -0
- package/dist/utils/escape-sql-literal.js.map +1 -0
- package/dist/utils/get-row-level-security-options.d.ts +8 -0
- package/dist/utils/get-row-level-security-options.js +9 -0
- package/dist/utils/get-row-level-security-options.js.map +1 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.js +29 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/policy-migration-sql.spec.d.ts +1 -0
- package/dist/utils/policy-migration-sql.spec.js +168 -0
- package/dist/utils/policy-migration-sql.spec.js.map +1 -0
- package/dist/utils/policy-sql-options.d.ts +12 -0
- package/dist/utils/policy-sql-options.js +3 -0
- package/dist/utils/policy-sql-options.js.map +1 -0
- package/dist/utils/quote-identifier.d.ts +2 -0
- package/dist/utils/quote-identifier.js +10 -0
- package/dist/utils/quote-identifier.js.map +1 -0
- package/dist/utils/quote-qualified-identifier.d.ts +2 -0
- package/dist/utils/quote-qualified-identifier.js +9 -0
- package/dist/utils/quote-qualified-identifier.js.map +1 -0
- package/dist/utils/row-level-security-context-builder.d.ts +12 -0
- package/dist/utils/row-level-security-context-builder.js +40 -0
- package/dist/utils/row-level-security-context-builder.js.map +1 -0
- package/dist/utils/row-level-security-context-builder.spec.d.ts +1 -0
- package/dist/utils/row-level-security-context-builder.spec.js +40 -0
- package/dist/utils/row-level-security-context-builder.spec.js.map +1 -0
- package/dist/utils/row-level-security-context-builder.types.d.ts +10 -0
- package/dist/utils/row-level-security-context-builder.types.js +3 -0
- package/dist/utils/row-level-security-context-builder.types.js.map +1 -0
- package/dist/utils/row-level-security-options-state.d.ts +4 -0
- package/dist/utils/row-level-security-options-state.js +8 -0
- package/dist/utils/row-level-security-options-state.js.map +1 -0
- package/dist/utils/set-row-level-security-options.d.ts +3 -0
- package/dist/utils/set-row-level-security-options.js +13 -0
- package/dist/utils/set-row-level-security-options.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const migrations_1 = require("@mikro-orm/migrations");
|
|
10
|
+
const policy_decorator_1 = require("./decorators/policy.decorator");
|
|
11
|
+
const policy_command_enum_1 = require("./enums/policy-command.enum");
|
|
12
|
+
const row_level_security_migration_generator_1 = require("./row-level-security-migration-generator");
|
|
13
|
+
let WorkspaceMember = class WorkspaceMember {
|
|
14
|
+
};
|
|
15
|
+
WorkspaceMember = __decorate([
|
|
16
|
+
(0, policy_decorator_1.Policy)({
|
|
17
|
+
name: "workspace_member_user_select_policy",
|
|
18
|
+
command: policy_command_enum_1.PolicyCommand.SELECT,
|
|
19
|
+
using: `((select app.get_context('user_id', null::bigint)) = "user_id")`,
|
|
20
|
+
})
|
|
21
|
+
], WorkspaceMember);
|
|
22
|
+
let WorkspaceMemberWithMultiplePolicies = class WorkspaceMemberWithMultiplePolicies {
|
|
23
|
+
};
|
|
24
|
+
WorkspaceMemberWithMultiplePolicies = __decorate([
|
|
25
|
+
(0, policy_decorator_1.Policy)({
|
|
26
|
+
name: "workspace_member_user_select_policy",
|
|
27
|
+
command: policy_command_enum_1.PolicyCommand.SELECT,
|
|
28
|
+
using: `((select app.get_context('user_id', null::bigint)) = "user_id")`,
|
|
29
|
+
}),
|
|
30
|
+
(0, policy_decorator_1.Policy)({
|
|
31
|
+
name: "workspace_member_write_policy",
|
|
32
|
+
using: `((select app.get_context('workspace_id', null::bigint)) = "workspace_id")`,
|
|
33
|
+
withCheck: `((select app.get_context('workspace_id', null::bigint)) = "workspace_id")`,
|
|
34
|
+
})
|
|
35
|
+
], WorkspaceMemberWithMultiplePolicies);
|
|
36
|
+
let WorkspaceMemberWithGeneratedPolicy = class WorkspaceMemberWithGeneratedPolicy {
|
|
37
|
+
};
|
|
38
|
+
WorkspaceMemberWithGeneratedPolicy = __decorate([
|
|
39
|
+
(0, policy_decorator_1.Policy)({
|
|
40
|
+
command: policy_command_enum_1.PolicyCommand.SELECT,
|
|
41
|
+
property: "user",
|
|
42
|
+
context: "user_id",
|
|
43
|
+
})
|
|
44
|
+
], WorkspaceMemberWithGeneratedPolicy);
|
|
45
|
+
let AuditLog = class AuditLog {
|
|
46
|
+
};
|
|
47
|
+
AuditLog = __decorate([
|
|
48
|
+
(0, policy_decorator_1.Policy)({
|
|
49
|
+
name: "audit_log_select_policy",
|
|
50
|
+
command: policy_command_enum_1.PolicyCommand.SELECT,
|
|
51
|
+
using: "true",
|
|
52
|
+
})
|
|
53
|
+
], AuditLog);
|
|
54
|
+
class UnmanagedEntity {
|
|
55
|
+
}
|
|
56
|
+
describe("RowLevelSecurityMigrationGenerator", () => {
|
|
57
|
+
afterEach(() => {
|
|
58
|
+
jest.restoreAllMocks();
|
|
59
|
+
});
|
|
60
|
+
it("loads existing policies from the database while generating migrations", async () => {
|
|
61
|
+
const execute = jest.fn((_sql) => Promise.resolve([
|
|
62
|
+
{
|
|
63
|
+
policy_name: "workspace_member_user_select_policy",
|
|
64
|
+
schema_name: "public",
|
|
65
|
+
table_name: "workspace_member",
|
|
66
|
+
permissive: true,
|
|
67
|
+
command: "r",
|
|
68
|
+
qual: "true",
|
|
69
|
+
with_check: null,
|
|
70
|
+
roles: ["authenticated"],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
policy_name: "workspace_member_insert_policy",
|
|
74
|
+
schema_name: "public",
|
|
75
|
+
table_name: "workspace_member",
|
|
76
|
+
permissive: false,
|
|
77
|
+
command: "a",
|
|
78
|
+
qual: null,
|
|
79
|
+
with_check: "true",
|
|
80
|
+
roles: ["authenticated"],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
policy_name: "workspace_member_update_policy",
|
|
84
|
+
schema_name: "public",
|
|
85
|
+
table_name: "workspace_member",
|
|
86
|
+
permissive: true,
|
|
87
|
+
command: "w",
|
|
88
|
+
qual: "true",
|
|
89
|
+
with_check: "true",
|
|
90
|
+
roles: ["authenticated"],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
policy_name: "workspace_member_delete_policy",
|
|
94
|
+
schema_name: "public",
|
|
95
|
+
table_name: "workspace_member",
|
|
96
|
+
permissive: true,
|
|
97
|
+
command: "d",
|
|
98
|
+
qual: "true",
|
|
99
|
+
with_check: null,
|
|
100
|
+
roles: ["authenticated"],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
policy_name: "workspace_member_all_policy",
|
|
104
|
+
schema_name: "public",
|
|
105
|
+
table_name: "workspace_member",
|
|
106
|
+
permissive: true,
|
|
107
|
+
command: "*",
|
|
108
|
+
qual: "true",
|
|
109
|
+
with_check: "true",
|
|
110
|
+
roles: ["authenticated"],
|
|
111
|
+
},
|
|
112
|
+
]));
|
|
113
|
+
const superGenerate = jest
|
|
114
|
+
.spyOn(migrations_1.TSMigrationGenerator.prototype, "generate")
|
|
115
|
+
.mockImplementation(function () {
|
|
116
|
+
expect(this.existingPolicyDefinitions).toEqual(expect.arrayContaining([
|
|
117
|
+
expect.objectContaining({
|
|
118
|
+
policyName: "workspace_member_insert_policy",
|
|
119
|
+
mode: "restrictive",
|
|
120
|
+
command: "insert",
|
|
121
|
+
withCheck: "true",
|
|
122
|
+
roles: ["authenticated"],
|
|
123
|
+
}),
|
|
124
|
+
expect.objectContaining({
|
|
125
|
+
policyName: "workspace_member_delete_policy",
|
|
126
|
+
command: "delete",
|
|
127
|
+
using: "true",
|
|
128
|
+
}),
|
|
129
|
+
expect.objectContaining({
|
|
130
|
+
policyName: "workspace_member_all_policy",
|
|
131
|
+
command: "all",
|
|
132
|
+
}),
|
|
133
|
+
]));
|
|
134
|
+
expect(this.currentPolicyDefinitions).toEqual([
|
|
135
|
+
expect.objectContaining({
|
|
136
|
+
policyName: "workspace_member_user_select_policy",
|
|
137
|
+
tableName: "workspace_member",
|
|
138
|
+
}),
|
|
139
|
+
]);
|
|
140
|
+
return Promise.resolve(["migration-file", "/tmp/Migration.ts"]);
|
|
141
|
+
});
|
|
142
|
+
const generator = createGenerator([
|
|
143
|
+
{
|
|
144
|
+
class: WorkspaceMember,
|
|
145
|
+
tableName: "workspace_member",
|
|
146
|
+
},
|
|
147
|
+
], {
|
|
148
|
+
getConnection: () => ({
|
|
149
|
+
execute,
|
|
150
|
+
}),
|
|
151
|
+
});
|
|
152
|
+
await expect(generator.generate({ up: [], down: [] }, "/tmp", "Migration")).resolves.toEqual(["migration-file", "/tmp/Migration.ts"]);
|
|
153
|
+
expect(superGenerate).toHaveBeenCalledWith({ up: [], down: [] }, "/tmp", "Migration");
|
|
154
|
+
expect(execute.mock.calls[0]?.[0]).toContain("('public', 'workspace_member')");
|
|
155
|
+
expect(execute.mock.calls[0]?.[0]).toContain("unnest(p.polroles)");
|
|
156
|
+
expect(generator.existingPolicyDefinitions).toBeUndefined();
|
|
157
|
+
expect(generator.currentPolicyDefinitions).toBeUndefined();
|
|
158
|
+
});
|
|
159
|
+
it("continues generation when the driver has no database connection", async () => {
|
|
160
|
+
const superGenerate = jest
|
|
161
|
+
.spyOn(migrations_1.TSMigrationGenerator.prototype, "generate")
|
|
162
|
+
.mockImplementation(function () {
|
|
163
|
+
expect(this.existingPolicyDefinitions).toBeUndefined();
|
|
164
|
+
return Promise.resolve(["migration-file", "/tmp/Migration.ts"]);
|
|
165
|
+
});
|
|
166
|
+
const generator = createGenerator([
|
|
167
|
+
{
|
|
168
|
+
class: WorkspaceMember,
|
|
169
|
+
tableName: "workspace_member",
|
|
170
|
+
},
|
|
171
|
+
]);
|
|
172
|
+
await expect(generator.generate({ up: [], down: [] })).resolves.toEqual([
|
|
173
|
+
"migration-file",
|
|
174
|
+
"/tmp/Migration.ts",
|
|
175
|
+
]);
|
|
176
|
+
expect(superGenerate).toHaveBeenCalledTimes(1);
|
|
177
|
+
});
|
|
178
|
+
it("does not recreate policies for unrelated schema changes without a database connection", async () => {
|
|
179
|
+
const diff = {
|
|
180
|
+
up: [
|
|
181
|
+
'alter table "workspace_member" add column "display_name" text null;',
|
|
182
|
+
],
|
|
183
|
+
down: ['alter table "workspace_member" drop column "display_name";'],
|
|
184
|
+
};
|
|
185
|
+
const superGenerate = jest
|
|
186
|
+
.spyOn(migrations_1.TSMigrationGenerator.prototype, "generate")
|
|
187
|
+
.mockImplementation(function () {
|
|
188
|
+
return Promise.resolve([
|
|
189
|
+
this.generateMigrationFile("MigrationTest", diff),
|
|
190
|
+
"/tmp/Migration.ts",
|
|
191
|
+
]);
|
|
192
|
+
});
|
|
193
|
+
const generator = createGenerator([
|
|
194
|
+
{
|
|
195
|
+
class: WorkspaceMember,
|
|
196
|
+
tableName: "workspace_member",
|
|
197
|
+
},
|
|
198
|
+
]);
|
|
199
|
+
const [file] = await generator.generate(diff);
|
|
200
|
+
expect(superGenerate).toHaveBeenCalledWith(diff, undefined, undefined);
|
|
201
|
+
expect(file).toContain("import { Migration } from '@mikro-orm/migrations';");
|
|
202
|
+
expect(file).toContain("extends Migration");
|
|
203
|
+
expect(file).not.toContain("workspace_member_user_select_policy");
|
|
204
|
+
});
|
|
205
|
+
it("skips database policy lookup when metadata has no entity classes", async () => {
|
|
206
|
+
const execute = jest.fn();
|
|
207
|
+
jest
|
|
208
|
+
.spyOn(migrations_1.TSMigrationGenerator.prototype, "generate")
|
|
209
|
+
.mockResolvedValue(["migration-file", "/tmp/Migration.ts"]);
|
|
210
|
+
const generator = createGenerator([
|
|
211
|
+
{
|
|
212
|
+
tableName: "workspace_member",
|
|
213
|
+
},
|
|
214
|
+
], {
|
|
215
|
+
getConnection: () => ({
|
|
216
|
+
execute,
|
|
217
|
+
}),
|
|
218
|
+
});
|
|
219
|
+
await generator.generate({ up: [], down: [] });
|
|
220
|
+
expect(execute).not.toHaveBeenCalled();
|
|
221
|
+
});
|
|
222
|
+
it("only loads existing database policies for tables managed by Policy metadata", async () => {
|
|
223
|
+
const execute = jest.fn((_sql) => Promise.resolve([]));
|
|
224
|
+
jest
|
|
225
|
+
.spyOn(migrations_1.TSMigrationGenerator.prototype, "generate")
|
|
226
|
+
.mockResolvedValue(["migration-file", "/tmp/Migration.ts"]);
|
|
227
|
+
const generator = createGenerator([
|
|
228
|
+
{
|
|
229
|
+
class: WorkspaceMember,
|
|
230
|
+
tableName: "workspace_member",
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
class: UnmanagedEntity,
|
|
234
|
+
tableName: "unmanaged_entity",
|
|
235
|
+
},
|
|
236
|
+
], {
|
|
237
|
+
getConnection: () => ({
|
|
238
|
+
execute,
|
|
239
|
+
}),
|
|
240
|
+
});
|
|
241
|
+
await generator.generate({ up: [], down: [] });
|
|
242
|
+
expect(execute.mock.calls[0]?.[0]).toContain("('public', 'workspace_member')");
|
|
243
|
+
expect(execute.mock.calls[0]?.[0]).not.toContain("unmanaged_entity");
|
|
244
|
+
});
|
|
245
|
+
it("throws when MikroORM metadata is unavailable", () => {
|
|
246
|
+
const generator = new row_level_security_migration_generator_1.RowLevelSecurityMigrationGenerator({}, {}, { emit: "ts" });
|
|
247
|
+
expect(() => generator.generateMigrationFile("MigrationTest", {
|
|
248
|
+
up: [],
|
|
249
|
+
down: [],
|
|
250
|
+
})).toThrow("MikroORM metadata storage is not available");
|
|
251
|
+
});
|
|
252
|
+
it("throws when a policy entity does not expose a table name", () => {
|
|
253
|
+
const generator = createGenerator([
|
|
254
|
+
{
|
|
255
|
+
class: WorkspaceMember,
|
|
256
|
+
},
|
|
257
|
+
]);
|
|
258
|
+
expect(() => generator.generateMigrationFile("MigrationTest", {
|
|
259
|
+
up: [],
|
|
260
|
+
down: [],
|
|
261
|
+
})).toThrow("Policy entity WorkspaceMember does not have a table name");
|
|
262
|
+
});
|
|
263
|
+
it("generates RowLevelSecurityMigration files with policy up and down SQL", () => {
|
|
264
|
+
const generator = createGenerator([
|
|
265
|
+
{
|
|
266
|
+
class: WorkspaceMember,
|
|
267
|
+
schema: "*",
|
|
268
|
+
tableName: "workspace_member",
|
|
269
|
+
},
|
|
270
|
+
]);
|
|
271
|
+
const file = generator.generateMigrationFile("MigrationTest", {
|
|
272
|
+
up: ['create table "workspace_member" ("user_id" bigint null);'],
|
|
273
|
+
down: ['drop table if exists "workspace_member" cascade;'],
|
|
274
|
+
});
|
|
275
|
+
expect(file).toContain("import { RowLevelSecurityMigration } from '@nest-boot/row-level-security';");
|
|
276
|
+
expect(file).toContain("extends RowLevelSecurityMigration");
|
|
277
|
+
expect(file.indexOf("create policy workspace_member_user_select_policy")).toBeGreaterThan(file.indexOf('create table "workspace_member"'));
|
|
278
|
+
expect(file.indexOf("drop policy if exists workspace_member_user_select_policy")).toBeLessThan(file.indexOf('drop table if exists "workspace_member" cascade;'));
|
|
279
|
+
});
|
|
280
|
+
it("throws when MikroORM migration output cannot be converted to the RLS base class", () => {
|
|
281
|
+
jest
|
|
282
|
+
.spyOn(migrations_1.TSMigrationGenerator.prototype, "generateMigrationFile")
|
|
283
|
+
.mockReturnValue("export class MigrationTest {}");
|
|
284
|
+
const generator = createGenerator([
|
|
285
|
+
{
|
|
286
|
+
class: WorkspaceMember,
|
|
287
|
+
tableName: "workspace_member",
|
|
288
|
+
},
|
|
289
|
+
]);
|
|
290
|
+
expect(() => generator.generateMigrationFile("MigrationTest", {
|
|
291
|
+
up: [],
|
|
292
|
+
down: [],
|
|
293
|
+
})).toThrow("MikroORM migration output format is not supported");
|
|
294
|
+
});
|
|
295
|
+
it("generates policy SQL for all policy entities in a blank migration", () => {
|
|
296
|
+
const generator = createGenerator([
|
|
297
|
+
{
|
|
298
|
+
class: WorkspaceMember,
|
|
299
|
+
tableName: "workspace_member",
|
|
300
|
+
},
|
|
301
|
+
]);
|
|
302
|
+
const file = generator.generateMigrationFile("MigrationTest", {
|
|
303
|
+
up: [],
|
|
304
|
+
down: [],
|
|
305
|
+
});
|
|
306
|
+
expect(file).toContain("extends RowLevelSecurityMigration");
|
|
307
|
+
expect(file).toContain("this.addSql(`do \\$\\$ begin if not exists (select 1 from pg_roles where rolname = 'authenticated') then create role authenticated nologin; end if; end \\$\\$;`);");
|
|
308
|
+
expect(file).toContain("this.addSql(`create schema if not exists app;`);");
|
|
309
|
+
expect(file).toContain("this.addSql(`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;`);");
|
|
310
|
+
expect(file).not.toContain("get_tenant_id()");
|
|
311
|
+
expect(file).not.toContain("get_policy_context");
|
|
312
|
+
expect(file).not.toContain("create schema if not exists extensions");
|
|
313
|
+
expect(file).not.toContain("grant usage on schema extensions");
|
|
314
|
+
expect(file).toContain('this.addSql(`alter table "public"."workspace_member" enable row level security;`);');
|
|
315
|
+
expect(file).toContain('this.addSql(`drop policy if exists workspace_member_user_select_policy on "public"."workspace_member";`);');
|
|
316
|
+
expect(file).toContain('this.addSql(`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");`);');
|
|
317
|
+
});
|
|
318
|
+
it("handles removed policies when an existing database policy is no longer declared", () => {
|
|
319
|
+
const generator = createGenerator([
|
|
320
|
+
{
|
|
321
|
+
class: WorkspaceMember,
|
|
322
|
+
tableName: "workspace_member",
|
|
323
|
+
},
|
|
324
|
+
]);
|
|
325
|
+
generator.existingPolicyDefinitions = [
|
|
326
|
+
{
|
|
327
|
+
entityName: "WorkspaceMember",
|
|
328
|
+
schemaName: "public",
|
|
329
|
+
tableName: "workspace_member",
|
|
330
|
+
policyName: "removed_workspace_member_policy",
|
|
331
|
+
command: policy_command_enum_1.PolicyCommand.SELECT,
|
|
332
|
+
using: "true",
|
|
333
|
+
roles: ["authenticated"],
|
|
334
|
+
},
|
|
335
|
+
];
|
|
336
|
+
const file = generator.generateMigrationFile("MigrationTest", {
|
|
337
|
+
up: ['alter table "workspace_member" add column "display_name" text;'],
|
|
338
|
+
down: ['alter table "workspace_member" drop column "display_name";'],
|
|
339
|
+
});
|
|
340
|
+
expect(file).toContain("drop policy if exists removed_workspace_member_policy");
|
|
341
|
+
expect(file).toContain("create policy workspace_member_user_select_policy");
|
|
342
|
+
expect(file).toContain("create policy removed_workspace_member_policy");
|
|
343
|
+
expect(file).toContain("create policy removed_workspace_member_policy on");
|
|
344
|
+
expect(file).toContain("for select to authenticated using true");
|
|
345
|
+
});
|
|
346
|
+
it("recreates policies when an existing policy changes content", () => {
|
|
347
|
+
const generator = createGenerator([
|
|
348
|
+
{
|
|
349
|
+
class: WorkspaceMember,
|
|
350
|
+
tableName: "workspace_member",
|
|
351
|
+
},
|
|
352
|
+
]);
|
|
353
|
+
generator.existingPolicyDefinitions = [
|
|
354
|
+
{
|
|
355
|
+
entityName: "WorkspaceMember",
|
|
356
|
+
schemaName: "public",
|
|
357
|
+
tableName: "workspace_member",
|
|
358
|
+
policyName: "workspace_member_user_select_policy",
|
|
359
|
+
command: policy_command_enum_1.PolicyCommand.SELECT,
|
|
360
|
+
using: "false",
|
|
361
|
+
roles: ["authenticated"],
|
|
362
|
+
},
|
|
363
|
+
];
|
|
364
|
+
const file = generator.generateMigrationFile("MigrationTest", {
|
|
365
|
+
up: ['alter table "workspace_member" add column "display_name" text;'],
|
|
366
|
+
down: ['alter table "workspace_member" drop column "display_name";'],
|
|
367
|
+
});
|
|
368
|
+
expect(file).toContain("drop policy if exists workspace_member_user_select_policy");
|
|
369
|
+
expect(file).toContain("create policy workspace_member_user_select_policy on");
|
|
370
|
+
expect(file).toContain("using ((select app.get_context('user_id', null::bigint)) = \"user_id\")");
|
|
371
|
+
expect(file).toContain("for select to authenticated using false");
|
|
372
|
+
});
|
|
373
|
+
it("matches create table statements for non-public schemas and collection names", () => {
|
|
374
|
+
const generator = createGenerator([
|
|
375
|
+
{
|
|
376
|
+
class: AuditLog,
|
|
377
|
+
schema: "app",
|
|
378
|
+
collection: "audit_log",
|
|
379
|
+
},
|
|
380
|
+
]);
|
|
381
|
+
const file = generator.generateMigrationFile("MigrationTest", {
|
|
382
|
+
up: ['create table if not exists "app"."audit_log" ("id" bigint);'],
|
|
383
|
+
down: ['drop table if exists "app"."audit_log";'],
|
|
384
|
+
});
|
|
385
|
+
expect(file).toContain('this.addSql(`create policy audit_log_select_policy on "app"."audit_log" as permissive for select using true;`);');
|
|
386
|
+
});
|
|
387
|
+
it("generates all policies declared on an entity", () => {
|
|
388
|
+
const generator = createGenerator([
|
|
389
|
+
{
|
|
390
|
+
class: WorkspaceMemberWithMultiplePolicies,
|
|
391
|
+
tableName: "workspace_member",
|
|
392
|
+
},
|
|
393
|
+
]);
|
|
394
|
+
const file = generator.generateMigrationFile("MigrationTest", {
|
|
395
|
+
up: [],
|
|
396
|
+
down: [],
|
|
397
|
+
});
|
|
398
|
+
expect(file).toContain('this.addSql(`create policy workspace_member_write_policy on "public"."workspace_member" as permissive for all using ((select app.get_context(\'workspace_id\', null::bigint)) = "workspace_id") with check ((select app.get_context(\'workspace_id\', null::bigint)) = "workspace_id");`);');
|
|
399
|
+
expect(file).toContain('this.addSql(`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");`);');
|
|
400
|
+
});
|
|
401
|
+
it("generates property context policy SQL from entity metadata", () => {
|
|
402
|
+
const generator = createGenerator([
|
|
403
|
+
{
|
|
404
|
+
class: WorkspaceMemberWithGeneratedPolicy,
|
|
405
|
+
tableName: "workspace_member",
|
|
406
|
+
properties: {
|
|
407
|
+
user: {
|
|
408
|
+
fieldNames: ["user_id"],
|
|
409
|
+
columnTypes: ["integer"],
|
|
410
|
+
targetMeta: {
|
|
411
|
+
primaryKeys: ["id"],
|
|
412
|
+
properties: {
|
|
413
|
+
id: {
|
|
414
|
+
columnTypes: ["bigint"],
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
]);
|
|
422
|
+
const file = generator.generateMigrationFile("MigrationTest", {
|
|
423
|
+
up: [],
|
|
424
|
+
down: [],
|
|
425
|
+
});
|
|
426
|
+
expect(file).toContain('this.addSql(`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");`);');
|
|
427
|
+
});
|
|
428
|
+
it("keeps default MikroORM output for unrelated schema changes", () => {
|
|
429
|
+
const generator = createGenerator([
|
|
430
|
+
{
|
|
431
|
+
class: WorkspaceMember,
|
|
432
|
+
tableName: "workspace_member",
|
|
433
|
+
},
|
|
434
|
+
]);
|
|
435
|
+
const file = generator.generateMigrationFile("MigrationTest", {
|
|
436
|
+
up: [
|
|
437
|
+
'alter table "workspace_member" add column "display_name" text null;',
|
|
438
|
+
],
|
|
439
|
+
down: ['alter table "workspace_member" drop column "display_name";'],
|
|
440
|
+
});
|
|
441
|
+
expect(file).toContain("import { Migration } from '@mikro-orm/migrations';");
|
|
442
|
+
expect(file).toContain("extends Migration");
|
|
443
|
+
expect(file).not.toContain("workspace_member_user_select_policy");
|
|
444
|
+
});
|
|
445
|
+
it("keeps default MikroORM output when no entities use Policy", () => {
|
|
446
|
+
const generator = createGenerator([]);
|
|
447
|
+
const file = generator.generateMigrationFile("MigrationTest", {
|
|
448
|
+
up: ["select 1;"],
|
|
449
|
+
down: [],
|
|
450
|
+
});
|
|
451
|
+
expect(file).toContain("import { Migration } from '@mikro-orm/migrations';");
|
|
452
|
+
expect(file).toContain("extends Migration");
|
|
453
|
+
});
|
|
454
|
+
it("is a MikroORM TypeScript migration generator", () => {
|
|
455
|
+
expect(row_level_security_migration_generator_1.RowLevelSecurityMigrationGenerator.prototype).toBeInstanceOf(migrations_1.TSMigrationGenerator);
|
|
456
|
+
});
|
|
457
|
+
});
|
|
458
|
+
function createGenerator(metadata, driverOptions = {}) {
|
|
459
|
+
return new row_level_security_migration_generator_1.RowLevelSecurityMigrationGenerator({
|
|
460
|
+
config: {
|
|
461
|
+
getMetadata: () => ({
|
|
462
|
+
getAll: () => metadata,
|
|
463
|
+
}),
|
|
464
|
+
},
|
|
465
|
+
...driverOptions,
|
|
466
|
+
}, {}, { emit: "ts" });
|
|
467
|
+
}
|
|
468
|
+
//# sourceMappingURL=row-level-security-migration-generator.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-level-security-migration-generator.spec.js","sourceRoot":"","sources":["../src/row-level-security-migration-generator.spec.ts"],"names":[],"mappings":";;;;;;;;AAAA,sDAA6D;AAE7D,oEAAuD;AACvD,qEAA4D;AAC5D,qGAA8F;AAO9F,IAAM,eAAe,GAArB,MAAM,eAAe;CAAG,CAAA;AAAlB,eAAe;IALpB,IAAA,yBAAM,EAAC;QACN,IAAI,EAAE,qCAAqC;QAC3C,OAAO,EAAE,mCAAa,CAAC,MAAM;QAC7B,KAAK,EAAE,iEAAiE;KACzE,CAAC;GACI,eAAe,CAAG;AAYxB,IAAM,mCAAmC,GAAzC,MAAM,mCAAmC;CAAG,CAAA;AAAtC,mCAAmC;IAVxC,IAAA,yBAAM,EAAC;QACN,IAAI,EAAE,qCAAqC;QAC3C,OAAO,EAAE,mCAAa,CAAC,MAAM;QAC7B,KAAK,EAAE,iEAAiE;KACzE,CAAC;IACD,IAAA,yBAAM,EAAC;QACN,IAAI,EAAE,+BAA+B;QACrC,KAAK,EAAE,2EAA2E;QAClF,SAAS,EAAE,2EAA2E;KACvF,CAAC;GACI,mCAAmC,CAAG;AAO5C,IAAM,kCAAkC,GAAxC,MAAM,kCAAkC;CAAG,CAAA;AAArC,kCAAkC;IALvC,IAAA,yBAAM,EAAC;QACN,OAAO,EAAE,mCAAa,CAAC,MAAM;QAC7B,QAAQ,EAAE,MAAM;QAChB,OAAO,EAAE,SAAS;KACnB,CAAC;GACI,kCAAkC,CAAG;AAO3C,IAAM,QAAQ,GAAd,MAAM,QAAQ;CAAG,CAAA;AAAX,QAAQ;IALb,IAAA,yBAAM,EAAC;QACN,IAAI,EAAE,yBAAyB;QAC/B,OAAO,EAAE,mCAAa,CAAC,MAAM;QAC7B,KAAK,EAAE,MAAM;KACd,CAAC;GACI,QAAQ,CAAG;AAEjB,MAAM,eAAe;CAAG;AAExB,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CACvC,OAAO,CAAC,OAAO,CAAC;YACd;gBACE,WAAW,EAAE,qCAAqC;gBAClD,WAAW,EAAE,QAAQ;gBACrB,UAAU,EAAE,kBAAkB;gBAC9B,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,GAAG;gBACZ,IAAI,EAAE,MAAM;gBACZ,UAAU,EAAE,IAAI;gBAChB,KAAK,EAAE,CAAC,eAAe,CAAC;aACzB;YACD;gBACE,WAAW,EAAE,gCAAgC;gBAC7C,WAAW,EAAE,QAAQ;gBACrB,UAAU,EAAE,kBAAkB;gBAC9B,UAAU,EAAE,KAAK;gBACjB,OAAO,EAAE,GAAG;gBACZ,IAAI,EAAE,IAAI;gBACV,UAAU,EAAE,MAAM;gBAClB,KAAK,EAAE,CAAC,eAAe,CAAC;aACzB;YACD;gBACE,WAAW,EAAE,gCAAgC;gBAC7C,WAAW,EAAE,QAAQ;gBACrB,UAAU,EAAE,kBAAkB;gBAC9B,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,GAAG;gBACZ,IAAI,EAAE,MAAM;gBACZ,UAAU,EAAE,MAAM;gBAClB,KAAK,EAAE,CAAC,eAAe,CAAC;aACzB;YACD;gBACE,WAAW,EAAE,gCAAgC;gBAC7C,WAAW,EAAE,QAAQ;gBACrB,UAAU,EAAE,kBAAkB;gBAC9B,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,GAAG;gBACZ,IAAI,EAAE,MAAM;gBACZ,UAAU,EAAE,IAAI;gBAChB,KAAK,EAAE,CAAC,eAAe,CAAC;aACzB;YACD;gBACE,WAAW,EAAE,6BAA6B;gBAC1C,WAAW,EAAE,QAAQ;gBACrB,UAAU,EAAE,kBAAkB;gBAC9B,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,GAAG;gBACZ,IAAI,EAAE,MAAM;gBACZ,UAAU,EAAE,MAAM;gBAClB,KAAK,EAAE,CAAC,eAAe,CAAC;aACzB;SACF,CAAC,CACH,CAAC;QACF,MAAM,aAAa,GAAG,IAAI;aACvB,KAAK,CAAC,iCAAoB,CAAC,SAAS,EAAE,UAAU,CAAC;aACjD,kBAAkB,CAAC;YAClB,MAAM,CAAE,IAAY,CAAC,yBAAyB,CAAC,CAAC,OAAO,CACrD,MAAM,CAAC,eAAe,CAAC;gBACrB,MAAM,CAAC,gBAAgB,CAAC;oBACtB,UAAU,EAAE,gCAAgC;oBAC5C,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,QAAQ;oBACjB,SAAS,EAAE,MAAM;oBACjB,KAAK,EAAE,CAAC,eAAe,CAAC;iBACzB,CAAC;gBACF,MAAM,CAAC,gBAAgB,CAAC;oBACtB,UAAU,EAAE,gCAAgC;oBAC5C,OAAO,EAAE,QAAQ;oBACjB,KAAK,EAAE,MAAM;iBACd,CAAC;gBACF,MAAM,CAAC,gBAAgB,CAAC;oBACtB,UAAU,EAAE,6BAA6B;oBACzC,OAAO,EAAE,KAAK;iBACf,CAAC;aACH,CAAC,CACH,CAAC;YACF,MAAM,CAAE,IAAY,CAAC,wBAAwB,CAAC,CAAC,OAAO,CAAC;gBACrD,MAAM,CAAC,gBAAgB,CAAC;oBACtB,UAAU,EAAE,qCAAqC;oBACjD,SAAS,EAAE,kBAAkB;iBAC9B,CAAC;aACH,CAAC,CAAC;YAEH,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACL,MAAM,SAAS,GAAG,eAAe,CAC/B;YACE;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;SACF,EACD;YACE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;gBACpB,OAAO;aACR,CAAC;SACH,CACF,CAAC;QAEF,MAAM,MAAM,CACV,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,CAC9D,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAE5D,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CACxC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EACpB,MAAM,EACN,WAAW,CACZ,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAC1C,gCAAgC,CACjC,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACnE,MAAM,CAAE,SAAiB,CAAC,yBAAyB,CAAC,CAAC,aAAa,EAAE,CAAC;QACrE,MAAM,CAAE,SAAiB,CAAC,wBAAwB,CAAC,CAAC,aAAa,EAAE,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,aAAa,GAAG,IAAI;aACvB,KAAK,CAAC,iCAAoB,CAAC,SAAS,EAAE,UAAU,CAAC;aACjD,kBAAkB,CAAC;YAClB,MAAM,CAAE,IAAY,CAAC,yBAAyB,CAAC,CAAC,aAAa,EAAE,CAAC;YAEhE,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACL,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;SACF,CAAC,CAAC;QAEH,MAAM,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;YACtE,gBAAgB;YAChB,mBAAmB;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uFAAuF,EAAE,KAAK,IAAI,EAAE;QACrG,MAAM,IAAI,GAAG;YACX,EAAE,EAAE;gBACF,qEAAqE;aACtE;YACD,IAAI,EAAE,CAAC,4DAA4D,CAAC;SACrE,CAAC;QACF,MAAM,aAAa,GAAG,IAAI;aACvB,KAAK,CAAC,iCAAoB,CAAC,SAAS,EAAE,UAAU,CAAC;aACjD,kBAAkB,CAAC;YAClB,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,IAAI,CAAC,qBAAqB,CAAC,eAAe,EAAE,IAAI,CAAC;gBACjD,mBAAmB;aACpB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACL,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAE9C,MAAM,CAAC,aAAa,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACvE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,oDAAoD,CACrD,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;QAC1B,IAAI;aACD,KAAK,CAAC,iCAAoB,CAAC,SAAS,EAAE,UAAU,CAAC;aACjD,iBAAiB,CAAC,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAC9D,MAAM,SAAS,GAAG,eAAe,CAC/B;YACE;gBACE,SAAS,EAAE,kBAAkB;aAC9B;SACF,EACD;YACE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;gBACpB,OAAO;aACR,CAAC;SACH,CACF,CAAC;QAEF,MAAM,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAE/C,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,KAAK,IAAI,EAAE;QAC3F,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/D,IAAI;aACD,KAAK,CAAC,iCAAoB,CAAC,SAAS,EAAE,UAAU,CAAC;aACjD,iBAAiB,CAAC,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAC9D,MAAM,SAAS,GAAG,eAAe,CAC/B;YACE;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;YACD;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;SACF,EACD;YACE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAC;gBACpB,OAAO;aACR,CAAC;SACH,CACF,CAAC;QAEF,MAAM,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAE/C,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAC1C,gCAAgC,CACjC,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,SAAS,GAAG,IAAI,2EAAkC,CACtD,EAAW,EACX,EAAW,EACX,EAAE,IAAI,EAAE,IAAI,EAAW,CACxB,CAAC;QAEF,MAAM,CAAC,GAAG,EAAE,CACV,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC/C,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,EAAE;SACT,CAAC,CACH,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,eAAe;aACvB;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,EAAE,CACV,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC/C,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,EAAE;SACT,CAAC,CACH,CAAC,OAAO,CAAC,0DAA0D,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,eAAe;gBACtB,MAAM,EAAE,GAAG;gBACX,SAAS,EAAE,kBAAkB;aAC9B;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC5D,EAAE,EAAE,CAAC,0DAA0D,CAAC;YAChE,IAAI,EAAE,CAAC,kDAAkD,CAAC;SAC3D,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,4EAA4E,CAC7E,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mCAAmC,CAAC,CAAC;QAC5D,MAAM,CACJ,IAAI,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAClE,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,CAAC;QACnE,MAAM,CACJ,IAAI,CAAC,OAAO,CAAC,2DAA2D,CAAC,CAC1E,CAAC,YAAY,CACZ,IAAI,CAAC,OAAO,CAAC,kDAAkD,CAAC,CACjE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,IAAI;aACD,KAAK,CAAC,iCAAoB,CAAC,SAAS,EAAE,uBAAuB,CAAC;aAC9D,eAAe,CAAC,+BAA+B,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,EAAE,CACV,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC/C,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,EAAE;SACT,CAAC,CACH,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC5D,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mCAAmC,CAAC,CAAC;QAC5D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,oKAAoK,CACrK,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kDAAkD,CAAC,CAAC;QAC3E,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,gdAAgd,CACjd,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;QACrE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAC;QAC/D,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,oFAAoF,CACrF,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,2GAA2G,CAC5G,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,oMAAoM,CACrM,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,GAAG,EAAE;QACzF,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;SACF,CAAC,CAAC;QACF,SAAiB,CAAC,yBAAyB,GAAG;YAC7C;gBACE,UAAU,EAAE,iBAAiB;gBAC7B,UAAU,EAAE,QAAQ;gBACpB,SAAS,EAAE,kBAAkB;gBAC7B,UAAU,EAAE,iCAAiC;gBAC7C,OAAO,EAAE,mCAAa,CAAC,MAAM;gBAC7B,KAAK,EAAE,MAAM;gBACb,KAAK,EAAE,CAAC,eAAe,CAAC;aACzB;SACF,CAAC;QAEF,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC5D,EAAE,EAAE,CAAC,gEAAgE,CAAC;YACtE,IAAI,EAAE,CAAC,4DAA4D,CAAC;SACrE,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,uDAAuD,CACxD,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mDAAmD,CAAC,CAAC;QAC5E,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,+CAA+C,CAAC,CAAC;QACxE,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,kDAAkD,CAAC,CAAC;QAC3E,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;SACF,CAAC,CAAC;QACF,SAAiB,CAAC,yBAAyB,GAAG;YAC7C;gBACE,UAAU,EAAE,iBAAiB;gBAC7B,UAAU,EAAE,QAAQ;gBACpB,SAAS,EAAE,kBAAkB;gBAC7B,UAAU,EAAE,qCAAqC;gBACjD,OAAO,EAAE,mCAAa,CAAC,MAAM;gBAC7B,KAAK,EAAE,OAAO;gBACd,KAAK,EAAE,CAAC,eAAe,CAAC;aACzB;SACF,CAAC;QAEF,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC5D,EAAE,EAAE,CAAC,gEAAgE,CAAC;YACtE,IAAI,EAAE,CAAC,4DAA4D,CAAC;SACrE,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,2DAA2D,CAC5D,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,sDAAsD,CACvD,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,yEAAyE,CAC1E,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,yCAAyC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,QAAQ;gBACf,MAAM,EAAE,KAAK;gBACb,UAAU,EAAE,WAAW;aACxB;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC5D,EAAE,EAAE,CAAC,6DAA6D,CAAC;YACnE,IAAI,EAAE,CAAC,yCAAyC,CAAC;SAClD,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,iHAAiH,CAClH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,mCAAmC;gBAC1C,SAAS,EAAE,kBAAkB;aAC9B;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC5D,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,4RAA4R,CAC7R,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,oMAAoM,CACrM,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,kCAAkC;gBACzC,SAAS,EAAE,kBAAkB;gBAC7B,UAAU,EAAE;oBACV,IAAI,EAAE;wBACJ,UAAU,EAAE,CAAC,SAAS,CAAC;wBACvB,WAAW,EAAE,CAAC,SAAS,CAAC;wBACxB,UAAU,EAAE;4BACV,WAAW,EAAE,CAAC,IAAI,CAAC;4BACnB,UAAU,EAAE;gCACV,EAAE,EAAE;oCACF,WAAW,EAAE,CAAC,QAAQ,CAAC;iCACxB;6BACF;yBACF;qBACF;iBACF;aACF;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC5D,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,oMAAoM,CACrM,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,SAAS,GAAG,eAAe,CAAC;YAChC;gBACE,KAAK,EAAE,eAAe;gBACtB,SAAS,EAAE,kBAAkB;aAC9B;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC5D,EAAE,EAAE;gBACF,qEAAqE;aACtE;YACD,IAAI,EAAE,CAAC,4DAA4D,CAAC;SACrE,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,oDAAoD,CACrD,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,SAAS,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QAEtC,MAAM,IAAI,GAAG,SAAS,CAAC,qBAAqB,CAAC,eAAe,EAAE;YAC5D,EAAE,EAAE,CAAC,WAAW,CAAC;YACjB,IAAI,EAAE,EAAE;SACT,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CACpB,oDAAoD,CACrD,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,2EAAkC,CAAC,SAAS,CAAC,CAAC,cAAc,CACjE,iCAAoB,CACrB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,SAAS,eAAe,CACtB,QAAkB,EAClB,gBAAyC,EAAE;IAE3C,OAAO,IAAI,2EAAkC,CAC3C;QACE,MAAM,EAAE;YACN,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;gBAClB,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ;aACvB,CAAC;SACH;QACD,GAAG,aAAa;KACR,EACV,EAAW,EACX,EAAE,IAAI,EAAE,IAAI,EAAW,CACxB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Migration } from "@mikro-orm/migrations";
|
|
2
|
+
import type { PolicySqlOptions } from "./interfaces/policy-sql-options.interface";
|
|
3
|
+
/** Base MikroORM migration with convenience helpers for row-level security SQL. */
|
|
4
|
+
export declare abstract class RowLevelSecurityMigration extends Migration {
|
|
5
|
+
/** Adds the shared RLS roles, grants, schema, and `app.get_context` helper SQL. */
|
|
6
|
+
protected addRowLevelSecurityBootstrapSql(): void;
|
|
7
|
+
/** Adds SQL that enables RLS and creates the configured policy. */
|
|
8
|
+
protected addPolicySql(options: PolicySqlOptions): void;
|
|
9
|
+
/** Adds SQL that drops the configured policy and disables RLS when no policies remain. */
|
|
10
|
+
protected addDropPolicySql(options: PolicySqlOptions): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RowLevelSecurityMigration = void 0;
|
|
4
|
+
const migrations_1 = require("@mikro-orm/migrations");
|
|
5
|
+
const create_policy_bootstrap_sql_statements_1 = require("./utils/create-policy-bootstrap-sql-statements");
|
|
6
|
+
const create_policy_down_sql_1 = require("./utils/create-policy-down-sql");
|
|
7
|
+
const create_policy_up_sql_statements_1 = require("./utils/create-policy-up-sql-statements");
|
|
8
|
+
/** Base MikroORM migration with convenience helpers for row-level security SQL. */
|
|
9
|
+
class RowLevelSecurityMigration extends migrations_1.Migration {
|
|
10
|
+
/** Adds the shared RLS roles, grants, schema, and `app.get_context` helper SQL. */
|
|
11
|
+
addRowLevelSecurityBootstrapSql() {
|
|
12
|
+
for (const sql of (0, create_policy_bootstrap_sql_statements_1.createPolicyBootstrapSqlStatements)()) {
|
|
13
|
+
this.addSql(sql);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Adds SQL that enables RLS and creates the configured policy. */
|
|
17
|
+
addPolicySql(options) {
|
|
18
|
+
for (const sql of (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)(options)) {
|
|
19
|
+
this.addSql(sql);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Adds SQL that drops the configured policy and disables RLS when no policies remain. */
|
|
23
|
+
addDropPolicySql(options) {
|
|
24
|
+
this.addSql((0, create_policy_down_sql_1.createPolicyDownSql)(options));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.RowLevelSecurityMigration = RowLevelSecurityMigration;
|
|
28
|
+
//# sourceMappingURL=row-level-security-migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-level-security-migration.js","sourceRoot":"","sources":["../src/row-level-security-migration.ts"],"names":[],"mappings":";;;AAAA,sDAAkD;AAGlD,2GAAoG;AACpG,2EAAqE;AACrE,6FAAsF;AAEtF,mFAAmF;AACnF,MAAsB,yBAA0B,SAAQ,sBAAS;IAC/D,mFAAmF;IACzE,+BAA+B;QACvC,KAAK,MAAM,GAAG,IAAI,IAAA,2EAAkC,GAAE,EAAE,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,mEAAmE;IACzD,YAAY,CAAC,OAAyB;QAC9C,KAAK,MAAM,GAAG,IAAI,IAAA,6DAA2B,EAAC,OAAO,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAED,0FAA0F;IAChF,gBAAgB,CAAC,OAAyB;QAClD,IAAI,CAAC,MAAM,CAAC,IAAA,4CAAmB,EAAC,OAAO,CAAC,CAAC,CAAC;IAC5C,CAAC;CACF;AAnBD,8DAmBC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const policy_command_enum_1 = require("./enums/policy-command.enum");
|
|
4
|
+
const row_level_security_migration_1 = require("./row-level-security-migration");
|
|
5
|
+
class TestRowLevelSecurityMigration extends row_level_security_migration_1.RowLevelSecurityMigration {
|
|
6
|
+
up() {
|
|
7
|
+
this.addRowLevelSecurityBootstrapSql();
|
|
8
|
+
this.addPolicySql({
|
|
9
|
+
schemaName: "public",
|
|
10
|
+
tableName: "workspace_member",
|
|
11
|
+
policyName: "workspace_member_user_select_policy",
|
|
12
|
+
command: policy_command_enum_1.PolicyCommand.SELECT,
|
|
13
|
+
using: `((select app.get_context('user_id', null::bigint)) = "user_id")`,
|
|
14
|
+
});
|
|
15
|
+
this.addDropPolicySql({
|
|
16
|
+
schemaName: "public",
|
|
17
|
+
tableName: "workspace_member",
|
|
18
|
+
policyName: "workspace_member_user_select_policy",
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
describe("RowLevelSecurityMigration", () => {
|
|
23
|
+
it("adds policy SQL through protected helpers", () => {
|
|
24
|
+
const migration = new TestRowLevelSecurityMigration({}, {});
|
|
25
|
+
migration.up();
|
|
26
|
+
const queries = migration.getQueries();
|
|
27
|
+
expect(migration.getQueries()).toHaveLength(12);
|
|
28
|
+
expect(queries[0]).toContain("create role authenticated nologin");
|
|
29
|
+
expect(queries[1]).toContain("create role anonymous nologin");
|
|
30
|
+
expect(queries[2]).toContain("grant authenticated to current_user");
|
|
31
|
+
expect(queries[3]).toContain("grant anonymous to current_user");
|
|
32
|
+
expect(queries[4]).toContain("create schema if not exists app");
|
|
33
|
+
expect(queries[7]).toContain("create or replace function app.get_context");
|
|
34
|
+
expect(queries[8]).toContain('alter table "public"."workspace_member" enable row level security;');
|
|
35
|
+
expect(queries[9]).toContain('drop policy if exists workspace_member_user_select_policy on "public"."workspace_member";');
|
|
36
|
+
expect(queries[10]).toContain("create policy workspace_member_user_select_policy");
|
|
37
|
+
expect(queries[11]).toContain("drop policy if exists workspace_member_user_select_policy");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=row-level-security-migration.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"row-level-security-migration.spec.js","sourceRoot":"","sources":["../src/row-level-security-migration.spec.ts"],"names":[],"mappings":";;AAAA,qEAA4D;AAC5D,iFAA2E;AAE3E,MAAM,6BAA8B,SAAQ,wDAAyB;IAC1D,EAAE;QACT,IAAI,CAAC,+BAA+B,EAAE,CAAC;QACvC,IAAI,CAAC,YAAY,CAAC;YAChB,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,kBAAkB;YAC7B,UAAU,EAAE,qCAAqC;YACjD,OAAO,EAAE,mCAAa,CAAC,MAAM;YAC7B,KAAK,EAAE,iEAAiE;SACzE,CAAC,CAAC;QACH,IAAI,CAAC,gBAAgB,CAAC;YACpB,UAAU,EAAE,QAAQ;YACpB,SAAS,EAAE,kBAAkB;YAC7B,UAAU,EAAE,qCAAqC;SAClD,CAAC,CAAC;IACL,CAAC;CACF;AAED,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,SAAS,GAAG,IAAI,6BAA6B,CACjD,EAAW,EACX,EAAW,CACZ,CAAC;QAEF,SAAS,CAAC,EAAE,EAAE,CAAC;QAEf,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,EAAc,CAAC;QAEnD,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAChD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,mCAAmC,CAAC,CAAC;QAClE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,+BAA+B,CAAC,CAAC;QAC9D,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,qCAAqC,CAAC,CAAC;QACpE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;QAChE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;QAChE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,4CAA4C,CAAC,CAAC;QAC3E,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAC1B,oEAAoE,CACrE,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAC1B,2FAA2F,CAC5F,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAC3B,mDAAmD,CACpD,CAAC;QACF,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAC3B,2DAA2D,CAC5D,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|