@feltdb/core 0.7.4 → 0.8.1
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/README.md +25 -0
- package/dist/application-development.d.ts +10 -3
- package/dist/application-development.d.ts.map +1 -1
- package/dist/application-development.js +11 -1
- package/dist/application-manifest.d.ts +2 -0
- package/dist/application-manifest.d.ts.map +1 -1
- package/dist/application-manifest.js +1 -1
- package/dist/application-understanding.d.ts +76 -0
- package/dist/application-understanding.d.ts.map +1 -0
- package/dist/application-understanding.js +282 -0
- package/dist/canonical-application.d.ts +1 -0
- package/dist/canonical-application.d.ts.map +1 -1
- package/dist/canonical-application.js +3 -2
- package/dist/cli/ai-model-config.js +3 -3
- package/dist/cli/cli.js +1 -1
- package/dist/cli/commands.js +321 -45
- package/dist/cli/index.js +1 -1
- package/dist/cli/managed-environment.js +6 -0
- package/dist/cli/managed-project.js +6 -0
- package/dist/cli/proposal-client.js +16 -3
- package/dist/cli/publish-engine.js +8 -5
- package/dist/cli/repository-evidence.js +55 -0
- package/dist/cli/source-sync.js +220 -61
- package/dist/convergence.d.ts +55 -0
- package/dist/convergence.d.ts.map +1 -0
- package/dist/convergence.js +63 -0
- package/dist/create/cli.js +10 -1
- package/dist/create/create.js +10 -12
- package/dist/create/managed-account.js +72 -7
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/crates/feltdb/src/application.rs +14 -0
- package/dist/create/server-source/crates/feltdb/src/lib.rs +20 -2
- package/dist/create/server-source/crates/feltdb-server/src/app_state.rs +12 -24
- package/dist/create/server-source/crates/feltdb-server/src/application_contract.rs +11 -3
- package/dist/create/server-source/crates/feltdb-server/src/authenticated_principal.rs +0 -1
- package/dist/create/server-source/crates/feltdb-server/src/certification_harness.rs +23 -22
- package/dist/create/server-source/crates/feltdb-server/src/connections.rs +14 -0
- package/dist/create/server-source/crates/feltdb-server/src/delegation_token.rs +5 -15
- package/dist/create/server-source/crates/feltdb-server/src/durable_operations.rs +13 -28
- package/dist/create/server-source/crates/feltdb-server/src/identity.rs +79 -14
- package/dist/create/server-source/crates/feltdb-server/src/key_management.rs +28 -7
- package/dist/create/server-source/crates/feltdb-server/src/lib.rs +5 -5
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +1929 -261
- package/dist/create/server-source/crates/feltdb-server/src/managed_diagnostics.rs +10 -30
- package/dist/create/server-source/crates/feltdb-server/src/membership_policy.rs +12 -4
- package/dist/create/server-source/crates/feltdb-server/src/request_telemetry.rs +8 -6
- package/dist/create/server-source/crates/feltdb-server/src/snapshot_cursor.rs +10 -14
- package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +191 -22
- package/dist/create/server-source/crates/feltdb-server/src/tenant_policies.rs +9 -21
- package/dist/create/server-source/crates/feltdb-server/src/transaction_idempotency.rs +5 -3
- package/dist/create/server-source/crates/feltdb-server/src/transaction_recovery.rs +9 -8
- package/dist/create/server-source/crates/feltdb-server/tests/revision_recovery_integration_test.rs +1 -4
- package/dist/create/template/default-project/feltdb.flow +5 -0
- package/dist/create/template/default-project/src/context/AuthContext.tsx +9 -1
- package/dist/create/template/default-project/src/pages/SignUp.tsx +1 -1
- package/dist/flowspec.d.ts +1 -0
- package/dist/flowspec.d.ts.map +1 -1
- package/dist/flowspec.js +51 -12
- package/dist/http-client.d.ts +166 -14
- package/dist/http-client.d.ts.map +1 -1
- package/dist/http-client.js +91 -31
- package/dist/http-db.d.ts +3 -0
- package/dist/http-db.d.ts.map +1 -1
- package/dist/http-db.js +28 -3
- package/dist/index-core.d.ts +5 -0
- package/dist/index-core.d.ts.map +1 -1
- package/dist/index-core.js +5 -0
- package/dist/intent.d.ts +98 -0
- package/dist/intent.d.ts.map +1 -0
- package/dist/intent.js +343 -0
- package/dist/module-intent.d.ts +51 -0
- package/dist/module-intent.d.ts.map +1 -0
- package/dist/module-intent.js +230 -0
- package/dist/module.d.ts +105 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +566 -0
- package/dist/proposal.d.ts +92 -4
- package/dist/proposal.d.ts.map +1 -1
- package/dist/proposal.js +150 -6
- package/dist/studio/app.d.ts +3 -1
- package/dist/studio/app.d.ts.map +1 -1
- package/dist/studio/components/AskFeltDB.d.ts +2 -1
- package/dist/studio/components/AskFeltDB.d.ts.map +1 -1
- package/dist/studio/components/ContractInspector.d.ts +7 -0
- package/dist/studio/components/ContractInspector.d.ts.map +1 -0
- package/dist/studio/components/ManagedInstancePanel.d.ts.map +1 -1
- package/dist/studio/components/ManagedInstancePanel.js +1 -5
- package/dist/studio/components/ModuleExplorer.d.ts +6 -0
- package/dist/studio/components/ModuleExplorer.d.ts.map +1 -0
- package/dist/studio/components/ProposalBrowser.d.ts +10 -1
- package/dist/studio/components/ProposalBrowser.d.ts.map +1 -1
- package/dist/studio/components/StateExplorer.d.ts +6 -7
- package/dist/studio/components/StateExplorer.d.ts.map +1 -1
- package/dist/studio/components/index.d.ts +2 -0
- package/dist/studio/components/index.d.ts.map +1 -1
- package/dist/studio/components/index.js +4 -4
- package/dist/studio/components-Duq2xQWt.js +2845 -0
- package/dist/studio/index.js +193 -147
- package/dist/studio/studio.css +1 -1
- package/dist/studio/utils/index.d.ts +2 -0
- package/dist/studio/utils/index.d.ts.map +1 -1
- package/dist/studio/utils/index.js +14 -12
- package/dist/studio/utils/managed-instance.d.ts +0 -4
- package/dist/studio/utils/managed-instance.d.ts.map +1 -1
- package/dist/studio/utils/managed-instance.js +0 -4
- package/dist/studio/utils/proposal-api.d.ts +56 -0
- package/dist/studio/utils/proposal-api.d.ts.map +1 -0
- package/dist/studio/utils/proposal-api.js +94 -0
- package/dist/studio/utils/service-api.d.ts +81 -0
- package/dist/studio/utils/service-api.d.ts.map +1 -0
- package/dist/studio/utils/service-api.js +51 -0
- package/dist/studio-app/assets/{feltdb_wasm-B-Ccgccb.js → feltdb_wasm-bIqcRzAr.js} +1 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-BE79okwX.wasm +0 -0
- package/dist/studio-app/assets/{index-BRrmvaKw.css → index-Cd_NPw14.css} +1 -1
- package/dist/studio-app/assets/index-XGYdlElN.js +29 -0
- package/dist/studio-app/index.html +2 -2
- package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
- package/dist/workspace/local-development-authority.d.ts +2 -0
- package/dist/workspace/local-development-authority.d.ts.map +1 -1
- package/dist/workspace/local-development-authority.js +128 -4
- package/package.json +1 -1
- package/dist/studio/components-Bm4sjhcX.js +0 -2162
- package/dist/studio-app/assets/dist-DA1MYSzp.js +0 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-wH3enJIA.wasm +0 -0
- package/dist/studio-app/assets/index-CEIqowCh.js +0 -42
- package/dist/studio-app/assets/lib-B2_7fcn7.js +0 -69
- package/dist/studio-app/assets/worker-CARZ5g7K.js +0 -69
|
@@ -137,35 +137,93 @@ impl IdentityStore {
|
|
|
137
137
|
.identities
|
|
138
138
|
.clone())
|
|
139
139
|
}
|
|
140
|
-
pub fn sign_up(
|
|
140
|
+
pub fn sign_up(
|
|
141
|
+
&self,
|
|
142
|
+
email: &str,
|
|
143
|
+
password: &str,
|
|
144
|
+
display_name: Option<String>,
|
|
145
|
+
) -> Result<(Identity, IdentitySession, String), String> {
|
|
141
146
|
let normalized = email.trim().to_lowercase();
|
|
142
|
-
if normalized.is_empty() || password.len() < 8 {
|
|
143
|
-
|
|
147
|
+
if normalized.is_empty() || password.len() < 8 {
|
|
148
|
+
return Err("email and a password of at least 8 characters are required".into());
|
|
149
|
+
}
|
|
150
|
+
if self
|
|
151
|
+
.state
|
|
152
|
+
.read()
|
|
153
|
+
.map_err(|_| "identity lock poisoned")?
|
|
154
|
+
.identities
|
|
155
|
+
.iter()
|
|
156
|
+
.any(|value| value.email.as_deref() == Some(&normalized))
|
|
157
|
+
{
|
|
144
158
|
return Err("identity already exists".into());
|
|
145
159
|
}
|
|
146
|
-
let mut identity = self.normalize(
|
|
160
|
+
let mut identity = self.normalize(
|
|
161
|
+
"password",
|
|
162
|
+
&normalized,
|
|
163
|
+
Some(normalized.clone()),
|
|
164
|
+
display_name,
|
|
165
|
+
serde_json::json!({}),
|
|
166
|
+
)?;
|
|
147
167
|
identity.status = IdentityStatus::Active;
|
|
148
168
|
let mut state = self.state.write().map_err(|_| "identity lock poisoned")?;
|
|
149
|
-
if let Some(stored) = state
|
|
150
|
-
|
|
169
|
+
if let Some(stored) = state
|
|
170
|
+
.identities
|
|
171
|
+
.iter_mut()
|
|
172
|
+
.find(|value| value.identity_id == identity.identity_id)
|
|
173
|
+
{
|
|
174
|
+
stored.status = IdentityStatus::Active;
|
|
175
|
+
}
|
|
176
|
+
state
|
|
177
|
+
.password_hashes
|
|
178
|
+
.insert(identity.subject_id.clone(), Self::hash_password(password)?);
|
|
151
179
|
self.persist(&state)?;
|
|
152
180
|
drop(state);
|
|
153
181
|
let (session, token) = self.issue_session(&identity, "password", None, 15 * 60)?;
|
|
154
182
|
Ok((identity, session, token))
|
|
155
183
|
}
|
|
156
|
-
pub fn sign_in(
|
|
184
|
+
pub fn sign_in(
|
|
185
|
+
&self,
|
|
186
|
+
email: &str,
|
|
187
|
+
password: &str,
|
|
188
|
+
) -> Result<(Identity, IdentitySession, String), String> {
|
|
157
189
|
let normalized = email.trim().to_lowercase();
|
|
158
190
|
let state = self.state.read().map_err(|_| "identity lock poisoned")?;
|
|
159
|
-
let identity = state
|
|
160
|
-
|
|
191
|
+
let identity = state
|
|
192
|
+
.identities
|
|
193
|
+
.iter()
|
|
194
|
+
.find(|value| {
|
|
195
|
+
value.email.as_deref() == Some(&normalized)
|
|
196
|
+
&& value.status == IdentityStatus::Active
|
|
197
|
+
})
|
|
198
|
+
.cloned()
|
|
199
|
+
.ok_or("invalid credentials")?;
|
|
200
|
+
let valid = state
|
|
201
|
+
.password_hashes
|
|
202
|
+
.get(&identity.subject_id)
|
|
203
|
+
.is_some_and(|hash| Self::verify_password(hash, password));
|
|
161
204
|
drop(state);
|
|
162
|
-
if !valid {
|
|
205
|
+
if !valid {
|
|
206
|
+
return Err("invalid credentials".into());
|
|
207
|
+
}
|
|
163
208
|
let (session, token) = self.issue_session(&identity, "password", None, 15 * 60)?;
|
|
164
209
|
Ok((identity, session, token))
|
|
165
210
|
}
|
|
166
211
|
pub fn authenticate_session(&self, token: &str) -> Option<IdentitySession> {
|
|
167
212
|
let current = now();
|
|
168
|
-
self.state
|
|
213
|
+
self.state
|
|
214
|
+
.read()
|
|
215
|
+
.ok()?
|
|
216
|
+
.sessions
|
|
217
|
+
.iter()
|
|
218
|
+
.find(|value| {
|
|
219
|
+
value
|
|
220
|
+
.refresh_hash
|
|
221
|
+
.as_deref()
|
|
222
|
+
.is_some_and(|hash| Self::verify_password(hash, token))
|
|
223
|
+
&& value.status == "active"
|
|
224
|
+
&& value.expires_at > current
|
|
225
|
+
})
|
|
226
|
+
.cloned()
|
|
169
227
|
}
|
|
170
228
|
pub fn sessions(&self, subject: &str) -> Result<Vec<IdentitySession>, String> {
|
|
171
229
|
Ok(self
|
|
@@ -282,11 +340,18 @@ mod tests {
|
|
|
282
340
|
fn actor_tokens_are_short_lived_hashed_and_revocable() {
|
|
283
341
|
let p = std::env::temp_dir().join(format!("identity-session-{}.json", id("test")));
|
|
284
342
|
let store = IdentityStore::load(&p).unwrap();
|
|
285
|
-
let (identity, session, token) = store
|
|
343
|
+
let (identity, session, token) = store
|
|
344
|
+
.sign_up("actor@example.com", "correct horse", Some("Actor".into()))
|
|
345
|
+
.unwrap();
|
|
286
346
|
assert!(session.expires_at - session.issued_at <= 15 * 60);
|
|
287
347
|
assert_ne!(session.refresh_hash.as_deref(), Some(token.as_str()));
|
|
288
|
-
assert_eq!(
|
|
289
|
-
|
|
348
|
+
assert_eq!(
|
|
349
|
+
store.authenticate_session(&token).unwrap().subject_id,
|
|
350
|
+
identity.subject_id
|
|
351
|
+
);
|
|
352
|
+
store
|
|
353
|
+
.revoke_session(&identity.subject_id, &session.session_id, "test")
|
|
354
|
+
.unwrap();
|
|
290
355
|
assert!(store.authenticate_session(&token).is_none());
|
|
291
356
|
let _ = std::fs::remove_file(p);
|
|
292
357
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
use axum::{
|
|
2
|
-
extract::{Path, State},
|
|
2
|
+
extract::{Extension, Path, State},
|
|
3
3
|
http::StatusCode,
|
|
4
4
|
Json,
|
|
5
5
|
};
|
|
6
6
|
use serde::{Deserialize, Serialize};
|
|
7
7
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
8
8
|
|
|
9
|
-
use crate::{
|
|
9
|
+
use crate::{
|
|
10
|
+
app_state::AppState,
|
|
11
|
+
auth::{ApiKeySummary, Principal},
|
|
12
|
+
};
|
|
10
13
|
|
|
11
14
|
#[derive(Debug, Serialize)]
|
|
12
15
|
pub struct KeyListResponse {
|
|
@@ -18,6 +21,7 @@ pub struct CreateKeyRequest {
|
|
|
18
21
|
pub id: Option<String>,
|
|
19
22
|
pub namespace: String,
|
|
20
23
|
pub scopes: Vec<String>,
|
|
24
|
+
pub application_id: Option<String>,
|
|
21
25
|
}
|
|
22
26
|
|
|
23
27
|
#[derive(Debug, Serialize)]
|
|
@@ -38,6 +42,7 @@ pub async fn list_keys(
|
|
|
38
42
|
|
|
39
43
|
pub async fn create_key(
|
|
40
44
|
State(state): State<AppState>,
|
|
45
|
+
Extension(principal): Extension<Principal>,
|
|
41
46
|
Json(req): Json<CreateKeyRequest>,
|
|
42
47
|
) -> Result<(StatusCode, Json<CreateKeyResponse>), (StatusCode, String)> {
|
|
43
48
|
let timestamp = SystemTime::now()
|
|
@@ -46,15 +51,31 @@ pub async fn create_key(
|
|
|
46
51
|
.as_secs();
|
|
47
52
|
|
|
48
53
|
let name = req.id.unwrap_or_else(|| format!("key-{}", timestamp));
|
|
54
|
+
let scopes = req.scopes;
|
|
55
|
+
let mut authentication_namespaces = vec![req.namespace];
|
|
56
|
+
if !authentication_namespaces
|
|
57
|
+
.iter()
|
|
58
|
+
.any(|value| value == state.namespace.as_ref())
|
|
59
|
+
{
|
|
60
|
+
authentication_namespaces.push(state.namespace.to_string());
|
|
61
|
+
}
|
|
49
62
|
let key = state
|
|
50
63
|
.keys
|
|
51
|
-
.create(
|
|
52
|
-
name,
|
|
53
|
-
req.scopes,
|
|
54
|
-
vec![req.namespace],
|
|
55
|
-
)
|
|
64
|
+
.create(name, scopes.clone(), authentication_namespaces)
|
|
56
65
|
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e))?;
|
|
57
66
|
|
|
67
|
+
if let Some(application_id) = req.application_id {
|
|
68
|
+
if let Err(error) = state.tenancy.register_application_service(
|
|
69
|
+
&principal.key_id,
|
|
70
|
+
&key.id,
|
|
71
|
+
&application_id,
|
|
72
|
+
scopes,
|
|
73
|
+
) {
|
|
74
|
+
let _ = state.keys.revoke(&key.id);
|
|
75
|
+
return Err((StatusCode::FORBIDDEN, error));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
58
79
|
Ok((
|
|
59
80
|
StatusCode::CREATED,
|
|
60
81
|
Json(CreateKeyResponse {
|
|
@@ -6,17 +6,17 @@ pub mod auth;
|
|
|
6
6
|
pub mod authenticated_principal;
|
|
7
7
|
pub mod authorization;
|
|
8
8
|
pub mod backup;
|
|
9
|
-
pub mod certification_harness;
|
|
10
|
-
pub mod delegation_token;
|
|
11
|
-
pub mod durable_operations;
|
|
12
|
-
pub mod key_management;
|
|
13
9
|
pub mod causal;
|
|
14
10
|
pub mod certification;
|
|
11
|
+
pub mod certification_harness;
|
|
15
12
|
pub mod clock;
|
|
16
13
|
pub mod cluster;
|
|
17
14
|
pub mod connections;
|
|
18
15
|
pub mod content;
|
|
16
|
+
pub mod delegation_token;
|
|
17
|
+
pub mod durable_operations;
|
|
19
18
|
pub mod identity;
|
|
19
|
+
pub mod key_management;
|
|
20
20
|
pub mod key_provider;
|
|
21
21
|
pub mod leases;
|
|
22
22
|
pub mod managed_diagnostics;
|
|
@@ -29,8 +29,8 @@ pub mod releases;
|
|
|
29
29
|
pub mod request_telemetry;
|
|
30
30
|
pub mod sessions;
|
|
31
31
|
pub mod snapshot_cursor;
|
|
32
|
-
pub mod tenant_policies;
|
|
33
32
|
pub mod tenancy;
|
|
33
|
+
pub mod tenant_policies;
|
|
34
34
|
pub mod transaction_idempotency;
|
|
35
35
|
pub mod transaction_recovery;
|
|
36
36
|
pub mod versions;
|