Skip to content

Commit ac398e7

Browse files
authored
Fix/group charter issues (#426)
* fix: make eVault provisioning in groups instant * chore: fix eid-wallet w3id logic * fix: cerberus issues with new infra * chore: format * chore: fix build
1 parent 01c09dc commit ac398e7

17 files changed

Lines changed: 435 additions & 309 deletions

File tree

infrastructure/eid-wallet/src/routes/(app)/scan-qr/scanLogic.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,7 @@ export function createScanLogic({
237237
created ? "key-generated" : "key-exists",
238238
);
239239

240-
const w3idResult = await globalState.keyService.getPublicKey(
241-
vault.ename,
242-
"signing",
243-
);
240+
const w3idResult = vault.ename;
244241
if (!w3idResult) {
245242
throw new Error("Failed to get W3ID");
246243
}
@@ -260,18 +257,10 @@ export function createScanLogic({
260257
const authPayload = {
261258
ename: vault.ename,
262259
session: get(session),
263-
w3id: w3idResult,
264260
signature: signature,
265261
appVersion: "0.4.0",
266262
};
267263

268-
console.log("🔐 Auth payload with signature:", {
269-
ename: authPayload.ename,
270-
session: authPayload.session,
271-
w3id: authPayload.w3id,
272-
signatureLength: authPayload.signature.length,
273-
});
274-
275264
const redirectUrl = get(redirect);
276265
if (!redirectUrl) {
277266
throw new Error(
@@ -534,10 +523,7 @@ export function createScanLogic({
534523
created ? "key-generated" : "key-exists",
535524
);
536525

537-
const w3idResult = await globalState.keyService.getPublicKey(
538-
vault.ename,
539-
"signing",
540-
);
526+
const w3idResult = vault.ename;
541527
if (!w3idResult) {
542528
throw new Error("Failed to get W3ID");
543529
}
@@ -678,10 +664,7 @@ export function createScanLogic({
678664
created ? "key-generated" : "key-exists",
679665
);
680666

681-
const w3idResult = await globalState.keyService.getPublicKey(
682-
vault.ename,
683-
"signing",
684-
);
667+
const w3idResult = vault.ename;
685668
if (!w3idResult) {
686669
throw new Error("Failed to get W3ID");
687670
}

infrastructure/evault-core/src/core/protocol/vault-access-guard.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ export class VaultAccessGuard {
175175

176176
// Check if envelope exists and user has access
177177
const { hasAccess, exists } = await this.checkAccess(metaEnvelopeId, context);
178+
179+
// For update operations, if envelope doesn't exist, allow the resolver to create it
180+
if (!exists && args.input) {
181+
// This is an update/create operation - let the resolver handle it
182+
const result = await resolver(parent, args, context);
183+
return this.filterACL(result);
184+
}
185+
178186
if (!hasAccess) {
179187
// If envelope doesn't exist, return null (not found)
180188
if (!exists) {

infrastructure/web3-adapter/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ async function createGroupManifestWithRetry(
212212
STORE_META_ENVELOPE,
213213
{
214214
input: {
215-
ontology: "550e8400-e29b-41d4-a716-446655440001", // GroupManifest schema ID
215+
ontology: "550e8400-e29b-41d4-a716-446655440003", // GroupManifest schema ID
216216
payload: groupManifest,
217217
acl: ["*"],
218218
},

platforms/blabsy-w3ds-auth-api/src/web3adapter/watchers/firestoreWatcher.ts

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ export class FirestoreWatcher {
1818
private retryCount = 0;
1919
private readonly maxRetries: number = 10; // Increased retries
2020
private readonly retryDelay: number = 1000; // 1 second
21-
private isFirstSnapshot = true; // Skip the initial snapshot that contains all existing documents
21+
private watcherStartTime: number = Date.now(); // Track when watcher starts
22+
private firstSnapshotReceived = false; // Track if we've received the first snapshot
2223

2324
// Track processed document IDs to prevent duplicates
2425
private processedIds = new Set<string>();
@@ -57,23 +58,53 @@ export class FirestoreWatcher {
5758

5859
// Reset stopped flag when starting
5960
this.stopped = false;
61+
62+
// Reset watcher start time
63+
this.watcherStartTime = Date.now();
64+
this.firstSnapshotReceived = false;
6065

6166
try {
62-
// Set up real-time listener (only for new changes, not existing documents)
67+
// Set up real-time listener
6368
this.unsubscribe = this.collection.onSnapshot(
6469
async (snapshot) => {
6570
// Update last snapshot time for health monitoring
6671
this.lastSnapshotTime = Date.now();
6772

68-
// Skip the first snapshot which contains all existing documents
69-
if (this.isFirstSnapshot) {
70-
console.log(`Skipping initial snapshot for ${collectionPath} (contains all existing documents)`);
71-
this.isFirstSnapshot = false;
73+
// On first snapshot, only skip documents that were created/modified BEFORE watcher started
74+
// This ensures we don't miss any new documents created right as the watcher starts
75+
if (!this.firstSnapshotReceived) {
76+
console.log(`First snapshot received for ${collectionPath} with ${snapshot.size} documents`);
77+
this.firstSnapshotReceived = true;
78+
79+
// Process only documents modified AFTER watcher start time
80+
const recentChanges = snapshot.docChanges().filter((change) => {
81+
const doc = change.doc;
82+
const data = doc.data();
83+
84+
// Check if document was modified after watcher started
85+
// Use updatedAt if available, otherwise createdAt
86+
const timestamp = data.updatedAt || data.createdAt;
87+
if (timestamp && timestamp.toMillis) {
88+
const docTime = timestamp.toMillis();
89+
return docTime >= this.watcherStartTime;
90+
}
91+
92+
// If no timestamp, process it to be safe
93+
return true;
94+
});
95+
96+
if (recentChanges.length > 0) {
97+
console.log(`Processing ${recentChanges.length} recent changes from first snapshot`);
98+
await this.processChanges(recentChanges);
99+
} else {
100+
console.log(`No recent changes in first snapshot, skipping`);
101+
}
102+
103+
this.retryCount = 0;
72104
return;
73105
}
74106

75-
// Don't skip snapshots - queue them instead to handle large databases
76-
// Process snapshot asynchronously without blocking new snapshots
107+
// For subsequent snapshots, process all changes normally
77108
this.processSnapshot(snapshot).catch((error) => {
78109
console.error("Error processing snapshot:", error);
79110
this.handleError(error);
@@ -205,8 +236,9 @@ export class FirestoreWatcher {
205236
this.unsubscribe = null;
206237
}
207238

208-
// Reset first snapshot flag
209-
this.isFirstSnapshot = true;
239+
// Reset watcher state
240+
this.watcherStartTime = Date.now();
241+
this.firstSnapshotReceived = false;
210242
this.lastSnapshotTime = Date.now();
211243

212244
// Reset reconnection attempt counter on successful reconnect
@@ -323,8 +355,9 @@ export class FirestoreWatcher {
323355
this.unsubscribe = null;
324356
}
325357

326-
// Reset first snapshot flag when restarting
327-
this.isFirstSnapshot = true;
358+
// Reset watcher state when restarting
359+
this.watcherStartTime = Date.now();
360+
this.firstSnapshotReceived = false;
328361
this.lastSnapshotTime = Date.now();
329362

330363
try {
@@ -343,8 +376,10 @@ export class FirestoreWatcher {
343376
}
344377
}
345378

346-
private async processSnapshot(snapshot: QuerySnapshot): Promise<void> {
347-
const changes = snapshot.docChanges();
379+
/**
380+
* Processes an array of document changes
381+
*/
382+
private async processChanges(changes: DocumentChange[]): Promise<void> {
348383
const collectionPath =
349384
this.collection instanceof CollectionReference
350385
? this.collection.path
@@ -412,6 +447,12 @@ export class FirestoreWatcher {
412447
await Promise.all(processPromises);
413448
}
414449

450+
private async processSnapshot(snapshot: QuerySnapshot): Promise<void> {
451+
const changes = snapshot.docChanges();
452+
await this.processChanges(changes);
453+
}
454+
455+
415456
private async handleCreateOrUpdate(
416457
doc: FirebaseFirestore.QueryDocumentSnapshot<DocumentData>,
417458
data: DocumentData

platforms/blabsy/src/lib/context/chat-context.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,19 @@ export function ChatContextProvider({
117117
return -1;
118118
if (!a.lastMessage?.timestamp && b.lastMessage?.timestamp)
119119
return 1;
120-
// If neither has lastMessage, sort by updatedAt
121-
return b.updatedAt.toMillis() - a.updatedAt.toMillis();
120+
// If neither has lastMessage, sort by updatedAt (with null checks)
121+
if (a.updatedAt && b.updatedAt) {
122+
return b.updatedAt.toMillis() - a.updatedAt.toMillis();
123+
}
124+
// If only one has updatedAt, prioritize it
125+
if (a.updatedAt && !b.updatedAt) return -1;
126+
if (!a.updatedAt && b.updatedAt) return 1;
127+
// If both are null, sort by createdAt as fallback
128+
if (a.createdAt && b.createdAt) {
129+
return b.createdAt.toMillis() - a.createdAt.toMillis();
130+
}
131+
// If all else fails, maintain order
132+
return 0;
122133
});
123134

124135
setChats(sortedChats);

0 commit comments

Comments
 (0)