@rebasepro/common 0.9.1-canary.ff338b5 → 0.10.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rebasepro/common",
3
3
  "type": "module",
4
- "version": "0.9.1-canary.ff338b5",
4
+ "version": "0.10.0",
5
5
  "description": "Awesome Firebase/Firestore-based headless open-source CMS",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/rebaseco"
@@ -40,8 +40,8 @@
40
40
  "dependencies": {
41
41
  "fast-equals": "6.0.0",
42
42
  "json-logic-js": "^2.0.5",
43
- "@rebasepro/utils": "0.9.1-canary.ff338b5",
44
- "@rebasepro/types": "0.9.1-canary.ff338b5"
43
+ "@rebasepro/types": "0.10.0",
44
+ "@rebasepro/utils": "0.10.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@jest/globals": "^30.4.1",
@@ -87,12 +87,12 @@ function compile(expr: PolicyExpression, scope: CompileScope): string {
87
87
  return `string_to_array(auth.roles(), ',') @> ${rolesArraySql(expr.roles)}`;
88
88
  case "authenticated":
89
89
  // `IS NOT NULL` alone is a tautology on the user path: every
90
- // user-context request sets `app.user_id`, and an anonymous one sets
90
+ // user-context request sets `app.uid`, and an anonymous one sets
91
91
  // it to the sentinel. Excluding the sentinel is what makes this mean
92
92
  // "signed in" rather than "anyone at all".
93
93
  return `auth.uid() IS NOT NULL AND auth.uid() <> ${quoteLiteral(ANONYMOUS_USER_ID)}`;
94
94
  case "serverContext":
95
- // Only the built-in server flows leave `app.user_id` unset.
95
+ // Only the built-in server flows leave `app.uid` unset.
96
96
  return "auth.uid() IS NULL";
97
97
  case "existsIn":
98
98
  return compileExistsIn(expr, scope);
@@ -10,7 +10,7 @@ import { ANONYMOUS_USER_ID, LiteralPolicyOperand, PolicyExpression, policy } fro
10
10
  * It handles:
11
11
  * - `field = 'literal'`
12
12
  * - `field != 'literal'`
13
- * - `field = current_setting('app.user_id')`
13
+ * - `field = current_setting('app.uid')` (or the legacy `app.user_id`)
14
14
  * - `A AND B`, `A OR B` — only where the keyword is at the top level
15
15
  * - `true`
16
16
  * - `IN (...)` (as optimistic true)
@@ -245,8 +245,11 @@ export function findAnonymousGrants(expr: PolicyExpression): AnonymousGrantRisk[
245
245
  }
246
246
 
247
247
  function parseOperand(str: string) {
248
- // current_setting('app.user_id') or auth.uid()
249
- if (/current_setting\s*\(\s*'app\.user_id'\s*\)/i.test(str) || /auth\.uid\(\)/i.test(str)) {
248
+ // current_setting('app.uid') or auth.uid(). `app.user_id` is the
249
+ // pre-rename spelling and stays parseable: policies are data, so a
250
+ // database provisioned before the rename still holds rules written
251
+ // against it, and round-tripping one must not silently drop the operand.
252
+ if (/current_setting\s*\(\s*'app\.(uid|user_id)'\s*\)/i.test(str) || /auth\.uid\(\)/i.test(str)) {
250
253
  return policy.authUid();
251
254
  }
252
255