@le-space/orbitdb-identity-provider-webauthn-did 0.1.0 → 0.2.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 +132 -410
- package/package.json +35 -5
- package/src/index.js +58 -503
- package/src/keystore/encryption.js +579 -0
- package/src/keystore/index.js +6 -0
- package/src/keystore/provider.js +555 -0
- package/src/keystore-encryption.js +6 -0
- package/src/varsig/assertion.js +205 -0
- package/src/varsig/credential.js +144 -0
- package/src/varsig/domain.js +11 -0
- package/src/varsig/identity.js +161 -0
- package/src/varsig/index.js +6 -0
- package/src/varsig/provider.js +78 -0
- package/src/varsig/storage.js +46 -0
- package/src/varsig/utils.js +43 -0
- package/src/verification.js +33 -33
- package/src/webauthn/provider.js +542 -0
- package/verification.js +1 -0
package/src/verification.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WebAuthn DID Verification Utilities
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Provides verification functions for WebAuthn DID identities in OrbitDB contexts.
|
|
5
5
|
* These utilities help verify database operations, identity storage, and data integrity
|
|
6
6
|
* without relying on external network calls or IPFS gateway timeouts.
|
|
@@ -15,27 +15,27 @@
|
|
|
15
15
|
*/
|
|
16
16
|
export async function verifyDatabaseUpdate(database, identityHash, expectedWebAuthnDID) {
|
|
17
17
|
console.log('🔄 Verifying database update event');
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
// Simple logic: if an update is happening in our database and our database
|
|
20
20
|
// identity matches the expected WebAuthn DID, then the update is from us
|
|
21
21
|
const databaseIdentity = database.identity;
|
|
22
22
|
const identityMatches = databaseIdentity?.id === expectedWebAuthnDID;
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
// Additional check: verify we have write access to this database
|
|
25
25
|
let hasWriteAccess = false;
|
|
26
26
|
try {
|
|
27
27
|
// Try to get the access controller configuration
|
|
28
28
|
const writePermissions = database.access?.write || [];
|
|
29
|
-
hasWriteAccess = writePermissions.includes(expectedWebAuthnDID) ||
|
|
29
|
+
hasWriteAccess = writePermissions.includes(expectedWebAuthnDID) ||
|
|
30
30
|
writePermissions.includes('*') ||
|
|
31
31
|
writePermissions.length === 0; // Default access
|
|
32
32
|
} catch (error) {
|
|
33
33
|
console.warn('Could not check write permissions:', error.message);
|
|
34
34
|
hasWriteAccess = true; // Assume we have access if we can't check
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
const verificationSuccess = identityMatches && hasWriteAccess;
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
return {
|
|
40
40
|
success: verificationSuccess,
|
|
41
41
|
identityHash,
|
|
@@ -61,18 +61,18 @@ export async function verifyDatabaseUpdate(database, identityHash, expectedWebAu
|
|
|
61
61
|
*/
|
|
62
62
|
export async function verifyIdentityStorage(identities, identity, timeoutMs = 5000) {
|
|
63
63
|
console.log('🔍 Verifying identity storage...');
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
try {
|
|
66
66
|
// Try to retrieve the identity from the store with a timeout
|
|
67
67
|
const retrievedIdentity = await Promise.race([
|
|
68
68
|
identities.getIdentity(identity.hash),
|
|
69
|
-
new Promise((_, reject) =>
|
|
69
|
+
new Promise((_, reject) =>
|
|
70
70
|
setTimeout(() => reject(new Error('Identity retrieval timeout')), timeoutMs)
|
|
71
71
|
)
|
|
72
72
|
]);
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
const success = !!retrievedIdentity && retrievedIdentity.id === identity.id;
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
return {
|
|
77
77
|
success,
|
|
78
78
|
storedCorrectly: success,
|
|
@@ -82,10 +82,10 @@ export async function verifyIdentityStorage(identities, identity, timeoutMs = 50
|
|
|
82
82
|
error: success ? null : 'Identity not found or ID mismatch',
|
|
83
83
|
timestamp: Date.now()
|
|
84
84
|
};
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
} catch (error) {
|
|
87
87
|
console.warn('⚠️ Could not verify identity storage:', error.message);
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
return {
|
|
90
90
|
success: false,
|
|
91
91
|
storedCorrectly: false,
|
|
@@ -111,31 +111,31 @@ export async function verifyIdentityStorage(identities, identity, timeoutMs = 50
|
|
|
111
111
|
export async function verifyDataEntries(database, dataEntries, expectedWebAuthnDID, options = {}) {
|
|
112
112
|
const { matchFn, checkLog = true } = options;
|
|
113
113
|
const verificationResults = new Map();
|
|
114
|
-
|
|
114
|
+
|
|
115
115
|
console.log(`🔍 Starting verification of ${dataEntries.length} data entries...`);
|
|
116
116
|
console.log(`🎯 Expected WebAuthn DID: ${expectedWebAuthnDID}`);
|
|
117
|
-
|
|
117
|
+
|
|
118
118
|
try {
|
|
119
119
|
// Check if our database identity matches the expected WebAuthn DID
|
|
120
120
|
const databaseIdentity = database.identity;
|
|
121
121
|
const databaseIdentityMatches = databaseIdentity?.id === expectedWebAuthnDID;
|
|
122
|
-
|
|
123
|
-
console.log(
|
|
122
|
+
|
|
123
|
+
console.log('🔑 Database identity check:', {
|
|
124
124
|
databaseDID: databaseIdentity?.id,
|
|
125
125
|
expectedDID: expectedWebAuthnDID,
|
|
126
126
|
matches: databaseIdentityMatches
|
|
127
127
|
});
|
|
128
|
-
|
|
128
|
+
|
|
129
129
|
for (const entry of dataEntries) {
|
|
130
130
|
try {
|
|
131
131
|
console.log(`📝 Verifying entry: ${entry.id}`);
|
|
132
|
-
|
|
132
|
+
|
|
133
133
|
// Method 1: Check if we can access the entry in our database
|
|
134
134
|
const entryInDb = await database.get(entry.id);
|
|
135
135
|
const entryExists = !!entryInDb;
|
|
136
|
-
const entryMatches = matchFn ? matchFn(entryInDb, entry) :
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
const entryMatches = matchFn ? matchFn(entryInDb, entry) :
|
|
137
|
+
(entryExists && entryInDb.id === entry.id);
|
|
138
|
+
|
|
139
139
|
// Method 2: Get identity hash from log (optional)
|
|
140
140
|
let identityHash = 'unknown';
|
|
141
141
|
if (checkLog) {
|
|
@@ -150,12 +150,12 @@ export async function verifyDataEntries(database, dataEntries, expectedWebAuthnD
|
|
|
150
150
|
console.warn(`Could not read log for entry ${entry.id}:`, logError.message);
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
|
|
153
|
+
|
|
154
154
|
// Pragmatic verification logic:
|
|
155
155
|
// If we can read the entry from our database AND our database identity matches
|
|
156
156
|
// the expected WebAuthn DID, then this entry was created by us
|
|
157
157
|
const verificationSuccess = entryExists && entryMatches && databaseIdentityMatches;
|
|
158
|
-
|
|
158
|
+
|
|
159
159
|
const result = {
|
|
160
160
|
success: verificationSuccess,
|
|
161
161
|
identityHash,
|
|
@@ -170,15 +170,15 @@ export async function verifyDataEntries(database, dataEntries, expectedWebAuthnD
|
|
|
170
170
|
},
|
|
171
171
|
timestamp: Date.now()
|
|
172
172
|
};
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
if (!verificationSuccess) {
|
|
175
175
|
result.error = `Pragmatic verification failed: entryExists=${entryExists}, entryMatches=${entryMatches}, identityMatches=${databaseIdentityMatches}`;
|
|
176
176
|
}
|
|
177
|
-
|
|
177
|
+
|
|
178
178
|
verificationResults.set(entry.id, result);
|
|
179
|
-
|
|
179
|
+
|
|
180
180
|
console.log(`${verificationSuccess ? '✅' : '❌'} Entry ${entry.id}: ${verificationSuccess ? 'VERIFIED' : 'FAILED'}`);
|
|
181
|
-
|
|
181
|
+
|
|
182
182
|
} catch (error) {
|
|
183
183
|
console.warn(`⚠️ Error verifying entry ${entry.id}:`, error);
|
|
184
184
|
verificationResults.set(entry.id, {
|
|
@@ -189,10 +189,10 @@ export async function verifyDataEntries(database, dataEntries, expectedWebAuthnD
|
|
|
189
189
|
});
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
|
|
192
|
+
|
|
193
193
|
} catch (error) {
|
|
194
194
|
console.error('❌ Error in pragmatic verification:', error);
|
|
195
|
-
|
|
195
|
+
|
|
196
196
|
// Ultra-fallback: If we can see entries in our database, they must be ours
|
|
197
197
|
for (const entry of dataEntries) {
|
|
198
198
|
verificationResults.set(entry.id, {
|
|
@@ -204,7 +204,7 @@ export async function verifyDataEntries(database, dataEntries, expectedWebAuthnD
|
|
|
204
204
|
});
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
|
-
|
|
207
|
+
|
|
208
208
|
console.log(`✅ Verification completed: ${verificationResults.size} entries processed`);
|
|
209
209
|
return verificationResults;
|
|
210
210
|
}
|
|
@@ -216,10 +216,10 @@ export async function verifyDataEntries(database, dataEntries, expectedWebAuthnD
|
|
|
216
216
|
*/
|
|
217
217
|
export function isValidWebAuthnDID(did) {
|
|
218
218
|
if (!did || typeof did !== 'string') return false;
|
|
219
|
-
|
|
219
|
+
|
|
220
220
|
// Check for proper did:key format (WebAuthn keys now use did:key format)
|
|
221
221
|
// Pattern: did:key:z followed by base58btc encoded multikey
|
|
222
|
-
const didKeyRegex = /^did:key:z[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]
|
|
222
|
+
const didKeyRegex = /^did:key:z[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{20,}$/;
|
|
223
223
|
return didKeyRegex.test(did);
|
|
224
224
|
}
|
|
225
225
|
|
|
@@ -270,4 +270,4 @@ export default {
|
|
|
270
270
|
extractWebAuthnDIDSuffix,
|
|
271
271
|
compareWebAuthnDIDs,
|
|
272
272
|
createVerificationResult
|
|
273
|
-
};
|
|
273
|
+
};
|