pyric-admin 0.1.0-alpha.10 → 0.1.0-alpha.11
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.
|
@@ -14,6 +14,24 @@
|
|
|
14
14
|
* default-app resolution and throw the captured `app/no-app` error when
|
|
15
15
|
* nothing is initialized. The original `getFirestore(ctx)` context form
|
|
16
16
|
* (the load-bearing shape the existing suite uses) is preserved verbatim.
|
|
17
|
+
*
|
|
18
|
+
* RULES-BYPASS PARITY (#394): the two APP-resolution forms — `getFirestore(app)`
|
|
19
|
+
* and no-arg `getFirestore()` — mirror `firebase-admin/firestore`'s
|
|
20
|
+
* `getFirestore(app?)`, and REAL firebase-admin bypasses security rules. So both
|
|
21
|
+
* app forms resolve to the rules-BYPASS admin lens (`getAdminFirestore` →
|
|
22
|
+
* `{ mode: 'admin' }`), exactly as `pyric-admin/database`'s `getDatabase(app)`
|
|
23
|
+
* and `pyric-admin/storage`'s `getStorage(app)` already do. Previously the app
|
|
24
|
+
* forms routed through the anon-lens `getFirestore(sandbox.withAuth(null))`,
|
|
25
|
+
* which evaluates `request.auth == null` and is DENIED by any real ruleset — a
|
|
26
|
+
* deny-direction divergence from production that blocked the RTDB-trigger →
|
|
27
|
+
* Firestore-stamp pattern (a Cloud Function's admin write).
|
|
28
|
+
*
|
|
29
|
+
* The `getFirestore(ctx)` CONTEXT form is UNCHANGED and stays rules-ENFORCED
|
|
30
|
+
* (its captured identity is load-bearing for the rules-simulation suite). No
|
|
31
|
+
* page ever reaches this module: a page's `firebase/firestore` resolves to
|
|
32
|
+
* `pyric/firestore` (the rules-enforced client), not `pyric-admin`; only the
|
|
33
|
+
* `firebase-admin/*` → `pyric-admin/*` swap in the trusted functions child
|
|
34
|
+
* imports this. See {@link getFirestore}.
|
|
17
35
|
*/
|
|
18
36
|
export * from 'pyric/sandbox/admin-firestore';
|
|
19
37
|
import { type SandboxFirestore } from 'pyric/sandbox/admin-firestore';
|
|
@@ -22,11 +40,19 @@ import { type PyricAdminApp } from '../app/index.js';
|
|
|
22
40
|
/**
|
|
23
41
|
* Return the admin Firestore handle.
|
|
24
42
|
*
|
|
25
|
-
* - `getFirestore(ctx)` — the original context form (rules-
|
|
43
|
+
* - `getFirestore(ctx)` — the original context form (rules-APPLIED for the
|
|
26
44
|
* ctx's captured identity). Unchanged; idempotent per `SandboxContext`.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
45
|
+
* This is the pyric-internal rules-simulation shape, not a firebase-admin
|
|
46
|
+
* shape, so it keeps rule evaluation.
|
|
47
|
+
* - `getFirestore(app)` — resolves a {@link PyricAdminApp}'s sandbox to the
|
|
48
|
+
* rules-BYPASS admin lens (firebase-admin parity, #394).
|
|
49
|
+
* - `getFirestore()` — resolves the default app to the rules-BYPASS admin
|
|
50
|
+
* lens; throws `app/no-app` when nothing is initialized.
|
|
51
|
+
*
|
|
52
|
+
* The app forms mirror `firebase-admin/firestore`'s `getFirestore(app?)`,
|
|
53
|
+
* which bypasses security rules — so a Cloud Function's admin write lands the
|
|
54
|
+
* same way it does in production, instead of being denied as `request.auth ==
|
|
55
|
+
* null` by the sandbox's anon lens (the #394 deny-direction divergence).
|
|
30
56
|
*/
|
|
31
57
|
export declare function getFirestore(target?: SandboxContext | PyricAdminApp): SandboxFirestore;
|
|
32
58
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/firestore/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/firestore/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,cAAc,+BAA+B,CAAC;AAE9C,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAC;AAsBzB;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAC1B,MAAM,CAAC,EAAE,cAAc,GAAG,aAAa,GACtC,gBAAgB,CAUlB"}
|
package/dist/firestore/index.js
CHANGED
|
@@ -14,18 +14,38 @@
|
|
|
14
14
|
* default-app resolution and throw the captured `app/no-app` error when
|
|
15
15
|
* nothing is initialized. The original `getFirestore(ctx)` context form
|
|
16
16
|
* (the load-bearing shape the existing suite uses) is preserved verbatim.
|
|
17
|
+
*
|
|
18
|
+
* RULES-BYPASS PARITY (#394): the two APP-resolution forms — `getFirestore(app)`
|
|
19
|
+
* and no-arg `getFirestore()` — mirror `firebase-admin/firestore`'s
|
|
20
|
+
* `getFirestore(app?)`, and REAL firebase-admin bypasses security rules. So both
|
|
21
|
+
* app forms resolve to the rules-BYPASS admin lens (`getAdminFirestore` →
|
|
22
|
+
* `{ mode: 'admin' }`), exactly as `pyric-admin/database`'s `getDatabase(app)`
|
|
23
|
+
* and `pyric-admin/storage`'s `getStorage(app)` already do. Previously the app
|
|
24
|
+
* forms routed through the anon-lens `getFirestore(sandbox.withAuth(null))`,
|
|
25
|
+
* which evaluates `request.auth == null` and is DENIED by any real ruleset — a
|
|
26
|
+
* deny-direction divergence from production that blocked the RTDB-trigger →
|
|
27
|
+
* Firestore-stamp pattern (a Cloud Function's admin write).
|
|
28
|
+
*
|
|
29
|
+
* The `getFirestore(ctx)` CONTEXT form is UNCHANGED and stays rules-ENFORCED
|
|
30
|
+
* (its captured identity is load-bearing for the rules-simulation suite). No
|
|
31
|
+
* page ever reaches this module: a page's `firebase/firestore` resolves to
|
|
32
|
+
* `pyric/firestore` (the rules-enforced client), not `pyric-admin`; only the
|
|
33
|
+
* `firebase-admin/*` → `pyric-admin/*` swap in the trusted functions child
|
|
34
|
+
* imports this. See {@link getFirestore}.
|
|
17
35
|
*/
|
|
18
36
|
export * from 'pyric/sandbox/admin-firestore';
|
|
19
|
-
import { getFirestore as baseGetFirestore, } from 'pyric/sandbox/admin-firestore';
|
|
37
|
+
import { getFirestore as baseGetFirestore, getAdminFirestore as baseGetAdminFirestore, } from 'pyric/sandbox/admin-firestore';
|
|
20
38
|
import { ADMIN_APP_TARGET, getApp, isSandboxAdminApp, } from '../app/index.js';
|
|
21
39
|
import { assertAdminAppActive } from '../app/lifecycle.js';
|
|
22
|
-
/** Narrow a `PyricAdminApp` to the
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
40
|
+
/** Narrow a `PyricAdminApp` to the {@link SandboxContext} the admin
|
|
41
|
+
* firestore backend runs against. Sandbox apps expose their `Sandbox` —
|
|
42
|
+
* LOCAL and REMOTE alike: the base resolvers are remote-aware (they
|
|
43
|
+
* dispatch a remote-branded sandbox to the channel-backed arm), so no
|
|
44
|
+
* guard is needed here. The context's captured auth is IRRELEVANT on the
|
|
45
|
+
* admin path (rules are bypassed, so no rule reads `request.auth`); it is
|
|
46
|
+
* normalised to `withAuth(null)` only to obtain a context. Prod apps
|
|
47
|
+
* require firebase-admin's real Firestore, which the in-process backend
|
|
48
|
+
* does not model. */
|
|
29
49
|
function adminAppToContext(app) {
|
|
30
50
|
if (isSandboxAdminApp(app)) {
|
|
31
51
|
return app.sandbox.withAuth(null);
|
|
@@ -36,20 +56,28 @@ function adminAppToContext(app) {
|
|
|
36
56
|
/**
|
|
37
57
|
* Return the admin Firestore handle.
|
|
38
58
|
*
|
|
39
|
-
* - `getFirestore(ctx)` — the original context form (rules-
|
|
59
|
+
* - `getFirestore(ctx)` — the original context form (rules-APPLIED for the
|
|
40
60
|
* ctx's captured identity). Unchanged; idempotent per `SandboxContext`.
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
61
|
+
* This is the pyric-internal rules-simulation shape, not a firebase-admin
|
|
62
|
+
* shape, so it keeps rule evaluation.
|
|
63
|
+
* - `getFirestore(app)` — resolves a {@link PyricAdminApp}'s sandbox to the
|
|
64
|
+
* rules-BYPASS admin lens (firebase-admin parity, #394).
|
|
65
|
+
* - `getFirestore()` — resolves the default app to the rules-BYPASS admin
|
|
66
|
+
* lens; throws `app/no-app` when nothing is initialized.
|
|
67
|
+
*
|
|
68
|
+
* The app forms mirror `firebase-admin/firestore`'s `getFirestore(app?)`,
|
|
69
|
+
* which bypasses security rules — so a Cloud Function's admin write lands the
|
|
70
|
+
* same way it does in production, instead of being denied as `request.auth ==
|
|
71
|
+
* null` by the sandbox's anon lens (the #394 deny-direction divergence).
|
|
44
72
|
*/
|
|
45
73
|
export function getFirestore(target) {
|
|
46
74
|
if (target === undefined) {
|
|
47
|
-
return
|
|
75
|
+
return baseGetAdminFirestore(adminAppToContext(getApp()));
|
|
48
76
|
}
|
|
49
77
|
if (typeof target === 'object' && target !== null && ADMIN_APP_TARGET in target) {
|
|
50
78
|
const app = target;
|
|
51
79
|
assertAdminAppActive(app);
|
|
52
|
-
return
|
|
80
|
+
return baseGetAdminFirestore(adminAppToContext(app));
|
|
53
81
|
}
|
|
54
82
|
return baseGetFirestore(target);
|
|
55
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/firestore/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/firestore/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,cAAc,+BAA+B,CAAC;AAE9C,OAAO,EACL,YAAY,IAAI,gBAAgB,EAChC,iBAAiB,IAAI,qBAAqB,GAE3C,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,gBAAgB,EAChB,MAAM,EACN,iBAAiB,GAElB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;;;;;;;sBAQsB;AACtB,SAAS,iBAAiB,CAAC,GAAkB;IAC3C,IAAI,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,MAAM,IAAI,KAAK,CACb,wEAAwE;QACtE,sEAAsE,CACzE,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAuC;IAEvC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,qBAAqB,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,gBAAgB,IAAI,MAAM,EAAE,CAAC;QAChF,MAAM,GAAG,GAAG,MAAuB,CAAC;QACpC,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAC1B,OAAO,qBAAqB,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,gBAAgB,CAAC,MAAwB,CAAC,CAAC;AACpD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pyric-admin",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.11",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"homepage": "https://pyric.dev",
|
|
6
6
|
"repository": {
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"typecheck": "bun x tsc -p tsconfig.json --noEmit"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"pyric": "^0.1.0-alpha.
|
|
49
|
+
"pyric": "^0.1.0-alpha.11"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/bun": "latest",
|