@feltdb/core 0.5.3 → 0.5.5
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/cell.d.ts.map +1 -1
- package/dist/cell.js +63 -59
- package/dist/create/managed-account.js +11 -4
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/crates/feltdb/src/lib.rs +31 -0
- package/dist/create/server-source/crates/feltdb/src/state_contract.rs +39 -3
- package/dist/create/server-source/crates/feltdb-server/src/auth.rs +12 -6
- package/dist/create/server-source/crates/feltdb-server/src/key_management.rs +7 -4
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +142 -30
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +4 -0
- package/dist/error-codes.d.ts +1 -1
- package/dist/error-codes.d.ts.map +1 -1
- package/dist/error-codes.js +5 -3
- package/dist/file-db.d.ts.map +1 -1
- package/dist/file-db.js +8 -40
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/studio-app/assets/index-DwII1ThH.js +28 -0
- package/dist/studio-app/index.html +1 -1
- package/dist/telemetry.d.ts +82 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +256 -0
- package/package.json +1 -1
- package/dist/studio-app/assets/index-Z92yFC4z.js +0 -28
package/dist/cell.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell.d.ts","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cell.d.ts","sourceRoot":"","sources":["../src/cell.ts"],"names":[],"mappings":"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"}
|
package/dist/cell.js
CHANGED
|
@@ -35,66 +35,65 @@ export class CellImpl {
|
|
|
35
35
|
}
|
|
36
36
|
async applyReplication(snapshot) {
|
|
37
37
|
return this.acquireLock(async () => {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
version
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
38
|
+
const key = this.encodeKey();
|
|
39
|
+
while (true) {
|
|
40
|
+
const currentRecord = await this.cellCollection.get(key);
|
|
41
|
+
const current = currentRecord ? this.snapshotFromState(currentRecord) : null;
|
|
42
|
+
// Replication can only move forward.
|
|
43
|
+
if (current && current.version > snapshot.version) {
|
|
44
|
+
throw new Error(`REPLICATION_CONFLICT: cannot apply version ${snapshot.version}, current is ${current.version}`);
|
|
45
|
+
}
|
|
46
|
+
// Same version must have identical state.
|
|
47
|
+
if (current && current.version === snapshot.version) {
|
|
48
|
+
if (JSON.stringify(current.value) !== JSON.stringify(snapshot.value)) {
|
|
49
|
+
const conflictReason = `version ${snapshot.version} has divergent state`;
|
|
50
|
+
await this.replicaCollection.insert({
|
|
51
|
+
cellId: this.id,
|
|
52
|
+
version: current.version,
|
|
53
|
+
value: current.value,
|
|
54
|
+
updatedAt: current.updatedAt,
|
|
55
|
+
authority: current.authority,
|
|
56
|
+
placement: current.placement,
|
|
57
|
+
lease: current.lease,
|
|
58
|
+
divergent: true,
|
|
59
|
+
conflictReason,
|
|
60
|
+
}, key);
|
|
61
|
+
throw new Error(`REPLICATION_CONFLICT: ${conflictReason}`);
|
|
62
|
+
}
|
|
63
|
+
await this.clearDivergenceMarker();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const replicaState = {
|
|
67
|
+
id: snapshot.cellId,
|
|
68
|
+
version: snapshot.version,
|
|
69
|
+
value: snapshot.value,
|
|
70
|
+
updatedAt: snapshot.updatedAt,
|
|
71
|
+
authority: {
|
|
72
|
+
owner: snapshot.authority.owner,
|
|
73
|
+
epoch: snapshot.authority.epoch,
|
|
74
|
+
lifecycle: snapshot.authority.lifecycle,
|
|
75
|
+
},
|
|
76
|
+
placement: { nodeId: snapshot.placement.nodeId },
|
|
77
|
+
lease: snapshot.lease,
|
|
78
|
+
};
|
|
79
|
+
if (!current) {
|
|
80
|
+
await this.cellCollection.insert(replicaState, key);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// Canonical and durable versions are distinct for a replica seeded at
|
|
84
|
+
// an arbitrary version. The durable revision is the CAS predicate.
|
|
85
|
+
const expectedStorageVersion = currentRecord?.__version ?? current.version;
|
|
86
|
+
const result = await this.cellCollection.updateIfVersion(key, expectedStorageVersion, replicaState, current.authority.epoch);
|
|
87
|
+
if (!result.updated) {
|
|
88
|
+
// An independent handle advanced the durable record. Re-read and
|
|
89
|
+
// re-evaluate this snapshot so a higher canonical version is not
|
|
90
|
+
// silently lost behind an earlier delivery.
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
59
93
|
}
|
|
60
|
-
// Identical state at same version is idempotent, no-op
|
|
61
94
|
await this.clearDivergenceMarker();
|
|
62
95
|
return;
|
|
63
96
|
}
|
|
64
|
-
// Apply replication: update the replicated state
|
|
65
|
-
// For PR 6A, we store replica state as regular cell state but marked as replica
|
|
66
|
-
const replicaState = {
|
|
67
|
-
id: snapshot.cellId,
|
|
68
|
-
version: snapshot.version,
|
|
69
|
-
value: snapshot.value,
|
|
70
|
-
updatedAt: snapshot.updatedAt,
|
|
71
|
-
authority: {
|
|
72
|
-
owner: snapshot.authority.owner,
|
|
73
|
-
epoch: snapshot.authority.epoch,
|
|
74
|
-
lifecycle: snapshot.authority.lifecycle,
|
|
75
|
-
},
|
|
76
|
-
placement: {
|
|
77
|
-
nodeId: snapshot.placement.nodeId,
|
|
78
|
-
},
|
|
79
|
-
lease: snapshot.lease,
|
|
80
|
-
};
|
|
81
|
-
const key = this.encodeKey();
|
|
82
|
-
if (!current) {
|
|
83
|
-
// New replica: insert the first version
|
|
84
|
-
await this.cellCollection.insert(replicaState, key);
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
// Update existing replica to new version
|
|
88
|
-
// Use version comparison for CAS (pass current version and epoch)
|
|
89
|
-
const result = await this.cellCollection.updateIfVersion(key, current.version, replicaState, current.authority.epoch);
|
|
90
|
-
if (!result.updated) {
|
|
91
|
-
// Concurrent replication delivery - just log and move forward
|
|
92
|
-
// This is expected in concurrent scenarios
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
// A successfully applied canonical snapshot repairs any older divergence
|
|
96
|
-
// marker and makes the replica eligible for later evaluation again.
|
|
97
|
-
await this.clearDivergenceMarker();
|
|
98
97
|
});
|
|
99
98
|
}
|
|
100
99
|
/** Removing an absent repair marker is an idempotent replication cleanup. */
|
|
@@ -103,7 +102,7 @@ export class CellImpl {
|
|
|
103
102
|
await this.replicaCollection.delete(this.encodeKey());
|
|
104
103
|
}
|
|
105
104
|
catch (error) {
|
|
106
|
-
if (error instanceof Error && /^Delete failed: record not found$/i.test(error.message)) {
|
|
105
|
+
if (error instanceof Error && /^Delete failed: record(?: .+)? not found$/i.test(error.message)) {
|
|
107
106
|
return;
|
|
108
107
|
}
|
|
109
108
|
throw error;
|
|
@@ -652,7 +651,7 @@ export class CellImpl {
|
|
|
652
651
|
const expectedLeaseId = current.lease && current.lease.expiresAt > Date.now()
|
|
653
652
|
? current.lease.leaseId
|
|
654
653
|
: undefined;
|
|
655
|
-
const result = await this.cellCollection.updateIfVersion(key, current.version, newState, current.authority.epoch, expectedLeaseId, true, current);
|
|
654
|
+
const result = await this.cellCollection.updateIfVersion(key, current.__version ?? current.version, newState, current.authority.epoch, expectedLeaseId, true, current);
|
|
656
655
|
if (!result.updated) {
|
|
657
656
|
if (result.conflictCode === 'REPLICATION_CONFLICT') {
|
|
658
657
|
throw new Error(`REPLICATION_CONFLICT: divergent replica cannot be promoted`);
|
|
@@ -1016,7 +1015,7 @@ export class CellImpl {
|
|
|
1016
1015
|
return this.snapshotFromState(newState);
|
|
1017
1016
|
}
|
|
1018
1017
|
snapshotFromState(state) {
|
|
1019
|
-
|
|
1018
|
+
const snapshot = {
|
|
1020
1019
|
id: this.id,
|
|
1021
1020
|
version: state.version,
|
|
1022
1021
|
value: state.value,
|
|
@@ -1025,6 +1024,11 @@ export class CellImpl {
|
|
|
1025
1024
|
placement: state.placement,
|
|
1026
1025
|
lease: state.lease,
|
|
1027
1026
|
};
|
|
1027
|
+
const storageVersion = state.__version;
|
|
1028
|
+
if (storageVersion !== undefined) {
|
|
1029
|
+
Object.defineProperty(snapshot, '__version', { value: storageVersion, enumerable: false });
|
|
1030
|
+
}
|
|
1031
|
+
return snapshot;
|
|
1028
1032
|
}
|
|
1029
1033
|
on(event, handler) {
|
|
1030
1034
|
if (event === 'change') {
|
|
@@ -15,18 +15,22 @@ export async function configureManagedAccount(options) {
|
|
|
15
15
|
body: JSON.stringify({ email: options.email, password: options.password }),
|
|
16
16
|
});
|
|
17
17
|
await responseJson(authenticated, 'Could not create or sign in to the managed account');
|
|
18
|
+
// fetch follows the feltdb.com -> www.feltdb.com redirect. Reuse the final
|
|
19
|
+
// origin so Node does not strip the explicit Cookie header on later
|
|
20
|
+
// cross-origin redirects.
|
|
21
|
+
const sessionOrigin = authenticated.url ? new URL(authenticated.url).origin : accountUrl;
|
|
18
22
|
const cookie = authenticated.headers.get('set-cookie')?.split(';', 1)[0];
|
|
19
23
|
if (!cookie)
|
|
20
24
|
throw new Error('Managed account service did not return a secure session');
|
|
21
25
|
const headers = { Cookie: cookie, 'Content-Type': 'application/json' };
|
|
22
|
-
const tenants = await responseJson(await request(`${
|
|
26
|
+
const tenants = await responseJson(await request(`${sessionOrigin}/api/tenants`, { headers }), 'Could not load managed workspaces');
|
|
23
27
|
let tenant = Array.isArray(tenants) ? tenants[0] : undefined;
|
|
24
28
|
if (!tenant) {
|
|
25
|
-
tenant = await responseJson(await request(`${
|
|
29
|
+
tenant = await responseJson(await request(`${sessionOrigin}/api/tenants`, {
|
|
26
30
|
method: 'POST', headers, body: JSON.stringify({ name: `${options.applicationName} Workspace` }),
|
|
27
31
|
}), 'Could not create the managed workspace');
|
|
28
32
|
}
|
|
29
|
-
const applicationsUrl = `${
|
|
33
|
+
const applicationsUrl = `${sessionOrigin}/api/tenants/${encodeURIComponent(tenant.id)}/applications`;
|
|
30
34
|
const applications = await responseJson(await request(applicationsUrl, { headers }), 'Could not load managed applications');
|
|
31
35
|
let application = Array.isArray(applications)
|
|
32
36
|
? applications.find(value => value.name === options.applicationName)
|
|
@@ -36,7 +40,10 @@ export async function configureManagedAccount(options) {
|
|
|
36
40
|
method: 'POST', headers, body: JSON.stringify({ name: options.applicationName }),
|
|
37
41
|
}), 'Could not create the managed application');
|
|
38
42
|
}
|
|
39
|
-
|
|
43
|
+
// Provision through the account origin that issued the human session. The
|
|
44
|
+
// resulting key is still used against apiUrl, but setup must not require a
|
|
45
|
+
// browser session to be trusted by every managed data-plane hostname.
|
|
46
|
+
const key = await responseJson(await request(`${sessionOrigin}/api/keys`, {
|
|
40
47
|
method: 'POST', headers,
|
|
41
48
|
body: JSON.stringify({
|
|
42
49
|
id: `${options.applicationName}-cli`,
|
|
@@ -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.5.
|
|
3
|
+
export const FELTDB_PACKAGE_VERSION = '0.5.5';
|
|
4
4
|
export const feltdbPackageRange = `^${FELTDB_PACKAGE_VERSION}`;
|
|
@@ -308,6 +308,7 @@ struct Inner {
|
|
|
308
308
|
capability_locations: CapabilityLocationRegistry,
|
|
309
309
|
bootstrapped: bool,
|
|
310
310
|
applied_transactions: HashSet<String>,
|
|
311
|
+
transaction_payload_hashes: HashMap<String, String>,
|
|
311
312
|
collection_cardinality: HashMap<String, u64>,
|
|
312
313
|
}
|
|
313
314
|
|
|
@@ -361,6 +362,8 @@ pub enum JsonCasResult {
|
|
|
361
362
|
struct TransactionLogRecord {
|
|
362
363
|
record_type: String,
|
|
363
364
|
transaction_id: String,
|
|
365
|
+
#[serde(default)]
|
|
366
|
+
payload_hash: Option<String>,
|
|
364
367
|
state_before: u64,
|
|
365
368
|
state_after: u64,
|
|
366
369
|
rows: Vec<StoredRow>,
|
|
@@ -894,6 +897,10 @@ impl FeltDb {
|
|
|
894
897
|
.contains(transaction_id))
|
|
895
898
|
}
|
|
896
899
|
|
|
900
|
+
pub fn applied_transaction_payload_hash(&self, transaction_id: &str) -> Result<Option<String>> {
|
|
901
|
+
Ok(self.inner.lock().expect("lock poisoned").transaction_payload_hashes.get(transaction_id).cloned())
|
|
902
|
+
}
|
|
903
|
+
|
|
897
904
|
/// Atomically validates and durably applies an ordered mutation batch.
|
|
898
905
|
/// The complete transaction is represented by one log record and becomes
|
|
899
906
|
/// visible in memory only after that record has been appended successfully.
|
|
@@ -904,10 +911,29 @@ impl FeltDb {
|
|
|
904
911
|
preconditions: &[AtomicPrecondition],
|
|
905
912
|
mutations: &[AtomicMutation],
|
|
906
913
|
audit: Option<Value>,
|
|
914
|
+
) -> Result<AtomicCommit> {
|
|
915
|
+
self.apply_atomic_transaction_content_addressed(transaction_id, None, expected_parent, preconditions, mutations, audit)
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
/// Applies a transaction whose identifier is durably bound to a canonical
|
|
919
|
+
/// payload hash. The same ID with a different payload is always a conflict.
|
|
920
|
+
pub fn apply_atomic_transaction_content_addressed(
|
|
921
|
+
&self,
|
|
922
|
+
transaction_id: &str,
|
|
923
|
+
payload_hash: Option<&str>,
|
|
924
|
+
expected_parent: Option<u64>,
|
|
925
|
+
preconditions: &[AtomicPrecondition],
|
|
926
|
+
mutations: &[AtomicMutation],
|
|
927
|
+
audit: Option<Value>,
|
|
907
928
|
) -> Result<AtomicCommit> {
|
|
908
929
|
let (commit, events) = {
|
|
909
930
|
let mut inner = self.inner.lock().expect("lock poisoned");
|
|
910
931
|
if inner.applied_transactions.contains(transaction_id) {
|
|
932
|
+
if let Some(expected_hash) = payload_hash {
|
|
933
|
+
if inner.transaction_payload_hashes.get(transaction_id).map(String::as_str) != Some(expected_hash) {
|
|
934
|
+
return Err(FlowError::CapabilityError(format!("TRANSACTION_ID_PAYLOAD_MISMATCH:{transaction_id}")));
|
|
935
|
+
}
|
|
936
|
+
}
|
|
911
937
|
return Ok(AtomicCommit {
|
|
912
938
|
transaction_id: transaction_id.into(),
|
|
913
939
|
state_before: inner.sequence,
|
|
@@ -1002,6 +1028,7 @@ impl FeltDb {
|
|
|
1002
1028
|
let record = TransactionLogRecord {
|
|
1003
1029
|
record_type: "feltdb.transaction.v1".into(),
|
|
1004
1030
|
transaction_id: transaction_id.into(),
|
|
1031
|
+
payload_hash: payload_hash.map(str::to_owned),
|
|
1005
1032
|
state_before,
|
|
1006
1033
|
state_after: next_sequence,
|
|
1007
1034
|
rows: rows.clone(),
|
|
@@ -1042,6 +1069,7 @@ impl FeltDb {
|
|
|
1042
1069
|
}
|
|
1043
1070
|
inner.sync_state.merge_vector_clock(&vector_clock);
|
|
1044
1071
|
inner.applied_transactions.insert(transaction_id.into());
|
|
1072
|
+
if let Some(hash) = payload_hash { inner.transaction_payload_hashes.insert(transaction_id.into(), hash.into()); }
|
|
1045
1073
|
let events = rows
|
|
1046
1074
|
.iter()
|
|
1047
1075
|
.map(|row| ChangeEvent {
|
|
@@ -2137,6 +2165,9 @@ fn replay_log(inner: &mut Inner) -> Result<()> {
|
|
|
2137
2165
|
}
|
|
2138
2166
|
if value.get("record_type").and_then(Value::as_str) == Some("feltdb.transaction.v1") {
|
|
2139
2167
|
let transaction: TransactionLogRecord = serde_json::from_value(value)?;
|
|
2168
|
+
if let Some(hash) = transaction.payload_hash.clone() {
|
|
2169
|
+
inner.transaction_payload_hashes.insert(transaction.transaction_id.clone(), hash);
|
|
2170
|
+
}
|
|
2140
2171
|
if inner
|
|
2141
2172
|
.applied_transactions
|
|
2142
2173
|
.insert(transaction.transaction_id)
|
|
@@ -1913,6 +1913,23 @@ pub fn execute_transaction(
|
|
|
1913
1913
|
schema: &StateSchema,
|
|
1914
1914
|
request: &TransactionRequest,
|
|
1915
1915
|
write_policy: Option<PolicySubject>,
|
|
1916
|
+
) -> Result<TransactionResult, StateFailure> {
|
|
1917
|
+
execute_transaction_with_policies(db, schema, request, write_policy.as_ref(), None)
|
|
1918
|
+
}
|
|
1919
|
+
pub fn execute_transaction_with_collection_policies(
|
|
1920
|
+
db: &FeltDb,
|
|
1921
|
+
schema: &StateSchema,
|
|
1922
|
+
request: &TransactionRequest,
|
|
1923
|
+
write_policies: &BTreeMap<String, PolicySubject>,
|
|
1924
|
+
) -> Result<TransactionResult, StateFailure> {
|
|
1925
|
+
execute_transaction_with_policies(db, schema, request, None, Some(write_policies))
|
|
1926
|
+
}
|
|
1927
|
+
fn execute_transaction_with_policies(
|
|
1928
|
+
db: &FeltDb,
|
|
1929
|
+
schema: &StateSchema,
|
|
1930
|
+
request: &TransactionRequest,
|
|
1931
|
+
uniform_write_policy: Option<&PolicySubject>,
|
|
1932
|
+
collection_write_policies: Option<&BTreeMap<String, PolicySubject>>,
|
|
1916
1933
|
) -> Result<TransactionResult, StateFailure> {
|
|
1917
1934
|
if request.application_id != schema.application_id
|
|
1918
1935
|
|| request.revision_id != schema.revision_id
|
|
@@ -1944,19 +1961,25 @@ pub fn execute_transaction(
|
|
|
1944
1961
|
request.application_id.as_str(),
|
|
1945
1962
|
request.revision_id.as_str(),
|
|
1946
1963
|
request.schema_version,
|
|
1964
|
+
request.state_namespace.as_deref(),
|
|
1947
1965
|
request.causal_parent,
|
|
1948
1966
|
&request.authorization.subject,
|
|
1967
|
+
&request.preconditions,
|
|
1949
1968
|
&request.operations,
|
|
1950
1969
|
))
|
|
1951
1970
|
.map_err(StateFailure::storage)?;
|
|
1952
1971
|
let transaction_id = request
|
|
1953
1972
|
.transaction_id
|
|
1954
1973
|
.clone()
|
|
1955
|
-
.unwrap_or_else(|| format!("tx_{:x}", Sha256::digest(canonical)));
|
|
1974
|
+
.unwrap_or_else(|| format!("tx_{:x}", Sha256::digest(&canonical)));
|
|
1975
|
+
let payload_hash = format!("sha256:{:x}", Sha256::digest(&canonical));
|
|
1956
1976
|
if db
|
|
1957
1977
|
.has_applied_transaction(&transaction_id)
|
|
1958
1978
|
.map_err(StateFailure::storage)?
|
|
1959
1979
|
{
|
|
1980
|
+
if db.applied_transaction_payload_hash(&transaction_id).map_err(StateFailure::storage)?.as_deref() != Some(payload_hash.as_str()) {
|
|
1981
|
+
return Err(StateFailure::new("CONFLICT", "transaction ID was already committed with a different canonical payload"));
|
|
1982
|
+
}
|
|
1960
1983
|
let state = db.sequence().map_err(StateFailure::storage)?;
|
|
1961
1984
|
let cursor = db
|
|
1962
1985
|
.operation_versions()
|
|
@@ -2088,7 +2111,8 @@ pub fn execute_transaction(
|
|
|
2088
2111
|
.unwrap_or_else(|| persisted.map(|row| Some(row.value.clone())).unwrap_or(None));
|
|
2089
2112
|
|
|
2090
2113
|
// Per-operation record authorization
|
|
2091
|
-
|
|
2114
|
+
let write_policy = collection_write_policies.and_then(|policies| policies.get(&operation.collection)).or(uniform_write_policy);
|
|
2115
|
+
if let Some(policy) = write_policy {
|
|
2092
2116
|
let actor = if request.authorization.subject.is_empty()
|
|
2093
2117
|
|| request.authorization.subject == ":"
|
|
2094
2118
|
{
|
|
@@ -2279,8 +2303,9 @@ pub fn execute_transaction(
|
|
|
2279
2303
|
}
|
|
2280
2304
|
}
|
|
2281
2305
|
let commit = db
|
|
2282
|
-
.
|
|
2306
|
+
.apply_atomic_transaction_content_addressed(
|
|
2283
2307
|
&transaction_id,
|
|
2308
|
+
Some(&payload_hash),
|
|
2284
2309
|
request.causal_parent,
|
|
2285
2310
|
&preconditions,
|
|
2286
2311
|
&mutations,
|
|
@@ -2760,6 +2785,17 @@ mod tests {
|
|
|
2760
2785
|
assert_eq!(failure.actual, Some(Value::from(1)));
|
|
2761
2786
|
}
|
|
2762
2787
|
#[test]
|
|
2788
|
+
fn explicit_transaction_id_is_bound_to_canonical_payload_across_restart() {
|
|
2789
|
+
let path=std::env::temp_dir().join(format!("feltdb-content-id-{}-{}.log",std::process::id(),crate::now_ms()));
|
|
2790
|
+
let schema=schema();
|
|
2791
|
+
let request=TransactionRequest{transaction_id:Some("stable-client-id".into()),tenant_id:"tenant".into(),application_id:"app".into(),revision_id:"rev".into(),schema_version:1,state_namespace:None,causal_parent:None,authorization:auth(),preconditions:vec![],operations:vec![TransactionOperation{kind:TransactionOperationKind::Insert,collection:"incidents".into(),id:"content-bound".into(),value:serde_json::json!({"title":"Original"}),if_version:None}]};
|
|
2792
|
+
{let db=crate::open(&path).unwrap();assert!(!execute_transaction(&db,&schema,&request,None).unwrap().duplicate);assert!(execute_transaction(&db,&schema,&request,None).unwrap().duplicate);}
|
|
2793
|
+
let reopened=crate::open(&path).unwrap();assert!(execute_transaction(&reopened,&schema,&request,None).unwrap().duplicate);
|
|
2794
|
+
let mut changed=request.clone();changed.operations[0].value=serde_json::json!({"title":"Changed"});
|
|
2795
|
+
let failure=execute_transaction(&reopened,&schema,&changed,None).unwrap_err();assert_eq!(failure.code,"CONFLICT");assert!(failure.message.contains("different canonical payload"));
|
|
2796
|
+
std::fs::remove_file(path).ok();
|
|
2797
|
+
}
|
|
2798
|
+
#[test]
|
|
2763
2799
|
fn read_context_remains_a_stable_snapshot() {
|
|
2764
2800
|
let db = db("snapshot-read");
|
|
2765
2801
|
let schema = schema();
|
|
@@ -50,6 +50,12 @@ pub struct ApiKeySummary {
|
|
|
50
50
|
pub revoked: bool,
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
#[derive(Debug, Clone)]
|
|
54
|
+
pub struct CreatedApiKey {
|
|
55
|
+
pub id: String,
|
|
56
|
+
pub secret: String,
|
|
57
|
+
}
|
|
58
|
+
|
|
53
59
|
#[derive(Debug, Clone)]
|
|
54
60
|
pub struct Principal {
|
|
55
61
|
pub key_id: String,
|
|
@@ -152,7 +158,7 @@ impl KeyStore {
|
|
|
152
158
|
name: String,
|
|
153
159
|
scopes: Vec<String>,
|
|
154
160
|
namespaces: Vec<String>,
|
|
155
|
-
) -> Result<
|
|
161
|
+
) -> Result<CreatedApiKey, String> {
|
|
156
162
|
let secret: String = rand::thread_rng()
|
|
157
163
|
.sample_iter(&Alphanumeric)
|
|
158
164
|
.take(48)
|
|
@@ -173,7 +179,7 @@ impl KeyStore {
|
|
|
173
179
|
.write()
|
|
174
180
|
.map_err(|_| "API key store lock poisoned".to_string())?
|
|
175
181
|
.push(ApiKeyRecord {
|
|
176
|
-
id,
|
|
182
|
+
id: id.clone(),
|
|
177
183
|
name,
|
|
178
184
|
hash,
|
|
179
185
|
scopes,
|
|
@@ -181,7 +187,7 @@ impl KeyStore {
|
|
|
181
187
|
revoked: false,
|
|
182
188
|
});
|
|
183
189
|
self.persist()?;
|
|
184
|
-
Ok(token)
|
|
190
|
+
Ok(CreatedApiKey { id, secret: token })
|
|
185
191
|
}
|
|
186
192
|
|
|
187
193
|
pub fn list(&self) -> Result<Vec<ApiKeySummary>, String> {
|
|
@@ -255,13 +261,14 @@ mod tests {
|
|
|
255
261
|
.as_nanos()
|
|
256
262
|
));
|
|
257
263
|
let store = KeyStore::load(&path).unwrap();
|
|
258
|
-
let
|
|
264
|
+
let created = store
|
|
259
265
|
.create(
|
|
260
266
|
"test".to_string(),
|
|
261
267
|
vec!["state:read".to_string()],
|
|
262
268
|
vec!["alpha".to_string()],
|
|
263
269
|
)
|
|
264
270
|
.unwrap();
|
|
271
|
+
let token = created.secret;
|
|
265
272
|
|
|
266
273
|
let file = fs::read_to_string(&path).unwrap();
|
|
267
274
|
assert!(!file.contains(&token));
|
|
@@ -271,8 +278,7 @@ mod tests {
|
|
|
271
278
|
.permits("state:read"));
|
|
272
279
|
assert!(store.authenticate(&token, "beta").is_none());
|
|
273
280
|
assert!(store.authenticate("fdb_live_wrong", "alpha").is_none());
|
|
274
|
-
|
|
275
|
-
assert!(store.revoke(&id).unwrap());
|
|
281
|
+
assert!(store.revoke(&created.id).unwrap());
|
|
276
282
|
assert!(store.authenticate(&token, "alpha").is_none());
|
|
277
283
|
assert!(!store.revoke("missing").unwrap());
|
|
278
284
|
let _ = fs::remove_file(path);
|
|
@@ -45,11 +45,11 @@ pub async fn create_key(
|
|
|
45
45
|
.unwrap_or_default()
|
|
46
46
|
.as_secs();
|
|
47
47
|
|
|
48
|
-
let
|
|
49
|
-
let
|
|
48
|
+
let name = req.id.unwrap_or_else(|| format!("key-{}", timestamp));
|
|
49
|
+
let key = state
|
|
50
50
|
.keys
|
|
51
51
|
.create(
|
|
52
|
-
|
|
52
|
+
name,
|
|
53
53
|
req.scopes,
|
|
54
54
|
vec![req.namespace],
|
|
55
55
|
)
|
|
@@ -57,7 +57,10 @@ pub async fn create_key(
|
|
|
57
57
|
|
|
58
58
|
Ok((
|
|
59
59
|
StatusCode::CREATED,
|
|
60
|
-
Json(CreateKeyResponse {
|
|
60
|
+
Json(CreateKeyResponse {
|
|
61
|
+
secret: key.secret,
|
|
62
|
+
id: key.id,
|
|
63
|
+
}),
|
|
61
64
|
))
|
|
62
65
|
}
|
|
63
66
|
|