@feltdb/core 0.4.14 → 0.4.16
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/dist/cli/index.js +1 -1
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +11 -5
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/crates/feltdb/Cargo.toml +1 -1
- package/dist/create/server-source/crates/feltdb/src/application.rs +93 -0
- package/dist/create/server-source/crates/feltdb/src/authorization_security_tests.rs +787 -0
- package/dist/create/server-source/crates/feltdb/src/lib.rs +139 -0
- package/dist/create/server-source/crates/feltdb/src/policy_evaluation.rs +1669 -0
- package/dist/create/server-source/crates/feltdb/src/state_contract.rs +1269 -15
- package/dist/create/server-source/crates/feltdb/tests/pr7_self_authorization_proof.rs +406 -0
- package/dist/create/server-source/crates/feltdb/tests/pr8_vocabulary_assessment.rs +908 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase2_boundary_tests.rs +1028 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3a_path_a_tests.rs +332 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_authorized_mutations.rs +342 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_role_based_authorization.rs +313 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_simple_auth_delete.rs +90 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_phase3c_team_delete_role_authorization.rs +571 -0
- package/dist/create/server-source/crates/feltdb/tests/pr9_teams_role_based_access.rs +506 -0
- package/dist/create/server-source/crates/feltdb/tests/saas_authorization_integration.rs +81 -0
- package/dist/create/server-source/crates/feltdb/tests/saas_invitation_lifecycle.rs +434 -0
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +130 -23
- package/dist/create/server-source/crates/feltdb-wasm/src/lib.rs +2 -2
- package/dist/db.d.ts +10 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +3 -1
- package/dist/feltdb.d.ts +1 -1
- package/dist/feltdb.d.ts.map +1 -1
- package/dist/file-db.d.ts +69 -0
- package/dist/file-db.d.ts.map +1 -0
- package/dist/file-db.js +355 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/indexeddb-db.d.ts +20 -1
- package/dist/indexeddb-db.d.ts.map +1 -1
- package/dist/indexeddb-db.js +167 -26
- package/dist/studio-app/assets/{feltdb_wasm-Bb1Pg6qz.js → feltdb_wasm-CBGD0zRu.js} +1 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-C6ATF9mJ.wasm +0 -0
- package/dist/studio-app/assets/{index-DVdvmf69.js → index-D74dfBgZ.js} +9 -9
- package/dist/studio-app/index.html +1 -1
- package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
- package/package.json +7 -2
- package/dist/studio-app/assets/feltdb_wasm_bg-2_wVudcZ.wasm +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import * as path from 'path';
|
|
|
23
23
|
import * as readline from 'readline';
|
|
24
24
|
import { getClient } from './api-client.js';
|
|
25
25
|
import { loadFeltDBConfig, createDefaultConfig, validateModel, } from './config.js';
|
|
26
|
-
const VERSION = '0.4.
|
|
26
|
+
const VERSION = '0.4.16';
|
|
27
27
|
function prompt(question) {
|
|
28
28
|
const rl = readline.createInterface({
|
|
29
29
|
input: process.stdin,
|
package/dist/collection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAIxC,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,kBAAkB,CAAC;AAEhE,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC;AAChD,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC;AAEjD;;;;;GAKG;AACH,qBAAa,UAAU,CAAC,CAAC;IACvB,OAAO,CAAC,EAAE,CAAO;IACjB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,oBAAoB,CAA8B;IAC1D,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,YAAY,CAAoC;IACxD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,aAAa,CAAS;gBAElB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;IAmBpF;;OAEG;YACW,oBAAoB;IAalC;;;OAGG;IACG,GAAG,IAAI,OAAO,CAAC,CAAC,EAAE,CAAC;IAKzB,0DAA0D;IACpD,IAAI,CAAC,KAAK,GAAE,OAAO,CAAC,CAAC,CAAM,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAQhD;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAWtC;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE;IAI5B;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAYrC;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAazC;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAajD;;;OAGG;IACH,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC;IAO7C;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4BrE;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BrE;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BhD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAK9B;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKnD;;;OAGG;IACH,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI;
|
|
1
|
+
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"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"}
|
package/dist/collection.js
CHANGED
|
@@ -258,10 +258,16 @@ export class Collection {
|
|
|
258
258
|
}
|
|
259
259
|
// Subscribe to changes via reactive dependency graph
|
|
260
260
|
if (!this.graphUnsubscribe) {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
261
|
+
let refreshInFlight = null;
|
|
262
|
+
const notify = () => {
|
|
263
|
+
if (refreshInFlight)
|
|
264
|
+
return refreshInFlight;
|
|
265
|
+
refreshInFlight = (async () => {
|
|
266
|
+
await this.refresh();
|
|
267
|
+
for (const sub of this.subscribers)
|
|
268
|
+
sub([...this.cache]);
|
|
269
|
+
})().finally(() => { refreshInFlight = null; });
|
|
270
|
+
return refreshInFlight;
|
|
265
271
|
};
|
|
266
272
|
const graph = getReactiveDependencyGraph();
|
|
267
273
|
this.graphUnsubscribe = graph.subscribe(this.name, notify);
|
|
@@ -269,7 +275,7 @@ export class Collection {
|
|
|
269
275
|
this.runtimeUnsubscribe = this.db.subscribe_changes(collection => {
|
|
270
276
|
if (collection === this.name)
|
|
271
277
|
void notify();
|
|
272
|
-
});
|
|
278
|
+
}, this.name);
|
|
273
279
|
}
|
|
274
280
|
}
|
|
275
281
|
// Return unsubscribe function
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// One release train keeps generated applications installable. The repository
|
|
2
2
|
// validation script checks these values against every workspace manifest.
|
|
3
|
-
export const FELTDB_PACKAGE_VERSION = '0.4.
|
|
3
|
+
export const FELTDB_PACKAGE_VERSION = '0.4.16';
|
|
4
4
|
export const feltdbPackageRange = `^${FELTDB_PACKAGE_VERSION}`;
|
|
@@ -15,7 +15,7 @@ rand = "0.8"
|
|
|
15
15
|
bincode = "1"
|
|
16
16
|
|
|
17
17
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
|
18
|
-
tokio = { version = "1", features = ["net", "io-util"] }
|
|
18
|
+
tokio = { version = "1", features = ["net", "io-util", "rt-multi-thread"] }
|
|
19
19
|
|
|
20
20
|
[dev-dependencies]
|
|
21
21
|
criterion = { version = "0.5", features = ["html_reports"] }
|
|
@@ -152,6 +152,10 @@ pub struct PolicyDefinition {
|
|
|
152
152
|
pub name: String,
|
|
153
153
|
pub resource: String,
|
|
154
154
|
#[serde(default)]
|
|
155
|
+
pub read: Option<String>,
|
|
156
|
+
#[serde(default)]
|
|
157
|
+
pub write: Option<String>,
|
|
158
|
+
#[serde(default)]
|
|
155
159
|
pub capabilities: Vec<String>,
|
|
156
160
|
}
|
|
157
161
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
|
@@ -363,6 +367,10 @@ pub struct ValidationReport {
|
|
|
363
367
|
pub issues: Vec<ValidationIssue>,
|
|
364
368
|
}
|
|
365
369
|
|
|
370
|
+
fn is_valid_policy_subject(subject: &str) -> bool {
|
|
371
|
+
matches!(subject, "authenticated" | "owner" | "member")
|
|
372
|
+
}
|
|
373
|
+
|
|
366
374
|
fn unique(
|
|
367
375
|
issues: &mut Vec<ValidationIssue>,
|
|
368
376
|
category: &str,
|
|
@@ -734,6 +742,24 @@ pub fn validate_manifest(
|
|
|
734
742
|
));
|
|
735
743
|
}
|
|
736
744
|
}
|
|
745
|
+
if let Some(ref read_subject) = policy.read {
|
|
746
|
+
if !is_valid_policy_subject(read_subject) {
|
|
747
|
+
issues.push(issue(
|
|
748
|
+
"semantic",
|
|
749
|
+
format!("policies.{}.read", policy.name),
|
|
750
|
+
&format!("invalid policy subject '{}'", read_subject),
|
|
751
|
+
));
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
if let Some(ref write_subject) = policy.write {
|
|
755
|
+
if !is_valid_policy_subject(write_subject) {
|
|
756
|
+
issues.push(issue(
|
|
757
|
+
"semantic",
|
|
758
|
+
format!("policies.{}.write", policy.name),
|
|
759
|
+
&format!("invalid policy subject '{}'", write_subject),
|
|
760
|
+
));
|
|
761
|
+
}
|
|
762
|
+
}
|
|
737
763
|
}
|
|
738
764
|
let state_schema = crate::state_contract::schema_from_manifest(manifest, "validation");
|
|
739
765
|
let schema_validation = crate::state_contract::validate_schema(&state_schema);
|
|
@@ -2241,4 +2267,71 @@ mod tests {
|
|
|
2241
2267
|
Some(promotion.diff_hash.as_str())
|
|
2242
2268
|
);
|
|
2243
2269
|
}
|
|
2270
|
+
|
|
2271
|
+
#[test]
|
|
2272
|
+
fn policy_with_valid_authenticated_subject() {
|
|
2273
|
+
let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
|
|
2274
|
+
manifest.policies.push(PolicyDefinition {
|
|
2275
|
+
name: "TodoPolicy".into(),
|
|
2276
|
+
resource: "Todo".into(),
|
|
2277
|
+
read: Some("authenticated".into()),
|
|
2278
|
+
write: Some("authenticated".into()),
|
|
2279
|
+
capabilities: vec![],
|
|
2280
|
+
});
|
|
2281
|
+
|
|
2282
|
+
let report = validate_manifest(&manifest, "tenant", "app", None);
|
|
2283
|
+
assert!(report.valid, "Policy with authenticated subject should be valid: {:?}", report.issues);
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
#[test]
|
|
2287
|
+
fn policy_with_valid_owner_subject() {
|
|
2288
|
+
let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
|
|
2289
|
+
manifest.policies.push(PolicyDefinition {
|
|
2290
|
+
name: "ProjectPolicy".into(),
|
|
2291
|
+
resource: "Project".into(),
|
|
2292
|
+
read: Some("authenticated".into()),
|
|
2293
|
+
write: Some("owner".into()),
|
|
2294
|
+
capabilities: vec![],
|
|
2295
|
+
});
|
|
2296
|
+
|
|
2297
|
+
let report = validate_manifest(&manifest, "tenant", "app", None);
|
|
2298
|
+
assert!(report.valid, "Policy with owner subject should be valid: {:?}", report.issues);
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
#[test]
|
|
2302
|
+
fn policy_with_invalid_subject_rejected() {
|
|
2303
|
+
let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
|
|
2304
|
+
manifest.policies.push(PolicyDefinition {
|
|
2305
|
+
name: "BadPolicy".into(),
|
|
2306
|
+
resource: "BadCollection".into(),
|
|
2307
|
+
read: Some("unknown_subject".into()),
|
|
2308
|
+
write: None,
|
|
2309
|
+
capabilities: vec![],
|
|
2310
|
+
});
|
|
2311
|
+
|
|
2312
|
+
let report = validate_manifest(&manifest, "tenant", "app", None);
|
|
2313
|
+
assert!(!report.valid, "Policy with unknown subject should be invalid");
|
|
2314
|
+
assert!(
|
|
2315
|
+
report.issues.iter().any(|i|
|
|
2316
|
+
i.path.contains("BadPolicy") && i.path.contains("read") &&
|
|
2317
|
+
i.message.contains("invalid policy subject")
|
|
2318
|
+
),
|
|
2319
|
+
"Should have error about invalid policy subject"
|
|
2320
|
+
);
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
#[test]
|
|
2324
|
+
fn policy_without_subjects_is_valid() {
|
|
2325
|
+
let mut manifest = ApplicationManifest::empty("tenant", "app", "test");
|
|
2326
|
+
manifest.policies.push(PolicyDefinition {
|
|
2327
|
+
name: "LegacyPolicy".into(),
|
|
2328
|
+
resource: "SomeCollection".into(),
|
|
2329
|
+
read: None,
|
|
2330
|
+
write: None,
|
|
2331
|
+
capabilities: vec!["some:capability".into()],
|
|
2332
|
+
});
|
|
2333
|
+
|
|
2334
|
+
let report = validate_manifest(&manifest, "tenant", "app", None);
|
|
2335
|
+
assert!(report.valid, "Policy without subjects should be valid (backward compatible)");
|
|
2336
|
+
}
|
|
2244
2337
|
}
|