mindoodb 0.0.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 +263 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts +5 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts.map +1 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js +17 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js.map +1 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +111 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +237 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -0
- package/dist/appendonlystores/network/HttpTransport.d.ts +78 -0
- package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -0
- package/dist/appendonlystores/network/HttpTransport.js +356 -0
- package/dist/appendonlystores/network/HttpTransport.js.map +1 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +131 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +248 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -0
- package/dist/appendonlystores/network/index.d.ts +8 -0
- package/dist/appendonlystores/network/index.d.ts.map +1 -0
- package/dist/appendonlystores/network/index.js +21 -0
- package/dist/appendonlystores/network/index.js.map +1 -0
- package/dist/browser/crypto/BrowserCryptoAdapter.d.ts +14 -0
- package/dist/browser/crypto/BrowserCryptoAdapter.d.ts.map +1 -0
- package/dist/browser/crypto/BrowserCryptoAdapter.js +30 -0
- package/dist/browser/crypto/BrowserCryptoAdapter.js.map +1 -0
- package/dist/browser/index.d.ts +3 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +26 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/core/BaseMindooDB.d.ts +182 -0
- package/dist/core/BaseMindooDB.d.ts.map +1 -0
- package/dist/core/BaseMindooDB.js +1701 -0
- package/dist/core/BaseMindooDB.js.map +1 -0
- package/dist/core/BaseMindooTenant.d.ts +155 -0
- package/dist/core/BaseMindooTenant.d.ts.map +1 -0
- package/dist/core/BaseMindooTenant.js +673 -0
- package/dist/core/BaseMindooTenant.js.map +1 -0
- package/dist/core/BaseMindooTenantDirectory.d.ts +99 -0
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -0
- package/dist/core/BaseMindooTenantDirectory.js +776 -0
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -0
- package/dist/core/BaseMindooTenantFactory.d.ts +91 -0
- package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -0
- package/dist/core/BaseMindooTenantFactory.js +297 -0
- package/dist/core/BaseMindooTenantFactory.js.map +1 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +111 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +293 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -0
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts +78 -0
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts.map +1 -0
- package/dist/core/appendonlystores/network/AuthenticationService.js +297 -0
- package/dist/core/appendonlystores/network/AuthenticationService.js.map +1 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts +174 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -0
- package/dist/core/appendonlystores/network/NetworkTransport.js +3 -0
- package/dist/core/appendonlystores/network/NetworkTransport.js.map +1 -0
- package/dist/core/appendonlystores/network/types.d.ts +135 -0
- package/dist/core/appendonlystores/network/types.d.ts.map +1 -0
- package/dist/core/appendonlystores/network/types.js +35 -0
- package/dist/core/appendonlystores/network/types.js.map +1 -0
- package/dist/core/appendonlystores/types.d.ts +157 -0
- package/dist/core/appendonlystores/types.d.ts.map +1 -0
- package/dist/core/appendonlystores/types.js +3 -0
- package/dist/core/appendonlystores/types.js.map +1 -0
- package/dist/core/crypto/CryptoAdapter.d.ts +19 -0
- package/dist/core/crypto/CryptoAdapter.d.ts.map +1 -0
- package/dist/core/crypto/CryptoAdapter.js +3 -0
- package/dist/core/crypto/CryptoAdapter.js.map +1 -0
- package/dist/core/crypto/MindooDocSigner.d.ts +106 -0
- package/dist/core/crypto/MindooDocSigner.d.ts.map +1 -0
- package/dist/core/crypto/MindooDocSigner.js +192 -0
- package/dist/core/crypto/MindooDocSigner.js.map +1 -0
- package/dist/core/crypto/RSAEncryption.d.ts +62 -0
- package/dist/core/crypto/RSAEncryption.d.ts.map +1 -0
- package/dist/core/crypto/RSAEncryption.js +167 -0
- package/dist/core/crypto/RSAEncryption.js.map +1 -0
- package/dist/core/errors.d.ts +10 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +17 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +53 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/indexing/virtualviews/IViewEntryAccessCheck.d.ts +33 -0
- package/dist/core/indexing/virtualviews/IViewEntryAccessCheck.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/IViewEntryAccessCheck.js +27 -0
- package/dist/core/indexing/virtualviews/IViewEntryAccessCheck.js.map +1 -0
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts +31 -0
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.js +3 -0
- package/dist/core/indexing/virtualviews/IVirtualViewDataProvider.js.map +1 -0
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +52 -0
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +106 -0
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts +44 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.js +107 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKey.js.map +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts +28 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js +133 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualView.d.ts +109 -0
- package/dist/core/indexing/virtualviews/VirtualView.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualView.js +504 -0
- package/dist/core/indexing/virtualviews/VirtualView.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts +59 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.js +70 -0
- package/dist/core/indexing/virtualviews/VirtualViewColumn.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewDataChange.d.ts +49 -0
- package/dist/core/indexing/virtualviews/VirtualViewDataChange.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewDataChange.js +69 -0
- package/dist/core/indexing/virtualviews/VirtualViewDataChange.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts +121 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js +365 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts +131 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.js +236 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.d.ts +330 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.js +1010 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.js.map +1 -0
- package/dist/core/indexing/virtualviews/index.d.ts +53 -0
- package/dist/core/indexing/virtualviews/index.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/index.js +89 -0
- package/dist/core/indexing/virtualviews/index.js.map +1 -0
- package/dist/core/indexing/virtualviews/types.d.ts +115 -0
- package/dist/core/indexing/virtualviews/types.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/types.js +175 -0
- package/dist/core/indexing/virtualviews/types.js.map +1 -0
- package/dist/core/keys/KeyBag.d.ts +122 -0
- package/dist/core/keys/KeyBag.d.ts.map +1 -0
- package/dist/core/keys/KeyBag.js +401 -0
- package/dist/core/keys/KeyBag.js.map +1 -0
- package/dist/core/types.d.ts +1004 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +10 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/userid/index.d.ts +53 -0
- package/dist/core/userid/index.d.ts.map +1 -0
- package/dist/core/userid/index.js +3 -0
- package/dist/core/userid/index.js.map +1 -0
- package/dist/core/utils/idGeneration.d.ts +109 -0
- package/dist/core/utils/idGeneration.d.ts.map +1 -0
- package/dist/core/utils/idGeneration.js +182 -0
- package/dist/core/utils/idGeneration.js.map +1 -0
- package/dist/core/utils/index.d.ts +5 -0
- package/dist/core/utils/index.d.ts.map +1 -0
- package/dist/core/utils/index.js +19 -0
- package/dist/core/utils/index.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/node/crypto/NodeCryptoAdapter.d.ts +16 -0
- package/dist/node/crypto/NodeCryptoAdapter.d.ts.map +1 -0
- package/dist/node/crypto/NodeCryptoAdapter.js +53 -0
- package/dist/node/crypto/NodeCryptoAdapter.js.map +1 -0
- package/dist/node/index.d.ts +3 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +26 -0
- package/dist/node/index.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthenticationService = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const types_1 = require("./types");
|
|
6
|
+
/**
|
|
7
|
+
* Authentication service for network sync operations.
|
|
8
|
+
*
|
|
9
|
+
* Handles:
|
|
10
|
+
* - Challenge generation (UUID v7)
|
|
11
|
+
* - Signature verification using user's public signing key
|
|
12
|
+
* - JWT token generation and validation
|
|
13
|
+
* - User revocation checks
|
|
14
|
+
*
|
|
15
|
+
* Security features:
|
|
16
|
+
* - Single-use challenges prevent replay attacks
|
|
17
|
+
* - Challenge expiration (5 minutes default)
|
|
18
|
+
* - Token expiration (1 hour default)
|
|
19
|
+
* - Revocation checks against tenant directory
|
|
20
|
+
*/
|
|
21
|
+
class AuthenticationService {
|
|
22
|
+
constructor(cryptoAdapter, directory, tenantId, options) {
|
|
23
|
+
// In-memory challenge storage (in production, use a distributed cache)
|
|
24
|
+
this.challenges = new Map();
|
|
25
|
+
this.cryptoAdapter = cryptoAdapter;
|
|
26
|
+
this.directory = directory;
|
|
27
|
+
this.tenantId = tenantId;
|
|
28
|
+
// Generate random JWT secret if not provided
|
|
29
|
+
this.jwtSecret = options?.jwtSecret || this.cryptoAdapter.getRandomValues(new Uint8Array(32));
|
|
30
|
+
// Default: 5 minutes for challenge, 1 hour for token
|
|
31
|
+
this.challengeExpirationMs = options?.challengeExpirationMs || 5 * 60 * 1000;
|
|
32
|
+
this.tokenExpirationMs = options?.tokenExpirationMs || 60 * 60 * 1000;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Generate a challenge for a user to sign.
|
|
36
|
+
*
|
|
37
|
+
* @param username The username requesting authentication
|
|
38
|
+
* @returns The challenge string (UUID v7)
|
|
39
|
+
* @throws NetworkError if user not found or revoked
|
|
40
|
+
*/
|
|
41
|
+
async generateChallenge(username) {
|
|
42
|
+
console.log(`[AuthenticationService] Generating challenge for user: ${username}`);
|
|
43
|
+
// Check if user exists and is not revoked
|
|
44
|
+
const userKeys = await this.directory.getUserPublicKeys(username);
|
|
45
|
+
if (!userKeys) {
|
|
46
|
+
// Check if user was revoked or never existed
|
|
47
|
+
const isRevoked = await this.directory.isUserRevoked(username);
|
|
48
|
+
if (isRevoked) {
|
|
49
|
+
throw new types_1.NetworkError(types_1.NetworkErrorType.USER_REVOKED, `User ${username} has been revoked`);
|
|
50
|
+
}
|
|
51
|
+
throw new types_1.NetworkError(types_1.NetworkErrorType.USER_NOT_FOUND, `User ${username} not found`);
|
|
52
|
+
}
|
|
53
|
+
// Generate UUID v7 challenge
|
|
54
|
+
const challenge = (0, uuid_1.v7)();
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
// Store challenge
|
|
57
|
+
const authChallenge = {
|
|
58
|
+
challenge,
|
|
59
|
+
username,
|
|
60
|
+
createdAt: now,
|
|
61
|
+
expiresAt: now + this.challengeExpirationMs,
|
|
62
|
+
used: false,
|
|
63
|
+
};
|
|
64
|
+
this.challenges.set(challenge, authChallenge);
|
|
65
|
+
// Clean up expired challenges periodically
|
|
66
|
+
this.cleanupExpiredChallenges();
|
|
67
|
+
console.log(`[AuthenticationService] Generated challenge for user ${username}: ${challenge}`);
|
|
68
|
+
return challenge;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Authenticate a user by verifying their signed challenge.
|
|
72
|
+
*
|
|
73
|
+
* @param challenge The challenge string
|
|
74
|
+
* @param signature The Ed25519 signature of the challenge
|
|
75
|
+
* @returns AuthResult with success status and JWT token
|
|
76
|
+
*/
|
|
77
|
+
async authenticate(challenge, signature) {
|
|
78
|
+
console.log(`[AuthenticationService] Authenticating challenge: ${challenge}`);
|
|
79
|
+
// Get and validate challenge
|
|
80
|
+
const authChallenge = this.challenges.get(challenge);
|
|
81
|
+
if (!authChallenge) {
|
|
82
|
+
console.log(`[AuthenticationService] Challenge not found: ${challenge}`);
|
|
83
|
+
return {
|
|
84
|
+
success: false,
|
|
85
|
+
error: "Challenge not found or expired",
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Check if challenge is expired
|
|
89
|
+
if (Date.now() > authChallenge.expiresAt) {
|
|
90
|
+
console.log(`[AuthenticationService] Challenge expired: ${challenge}`);
|
|
91
|
+
this.challenges.delete(challenge);
|
|
92
|
+
return {
|
|
93
|
+
success: false,
|
|
94
|
+
error: "Challenge expired",
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// Check if challenge was already used
|
|
98
|
+
if (authChallenge.used) {
|
|
99
|
+
console.log(`[AuthenticationService] Challenge already used: ${challenge}`);
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
error: "Challenge already used",
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// Mark challenge as used (single-use)
|
|
106
|
+
authChallenge.used = true;
|
|
107
|
+
const username = authChallenge.username;
|
|
108
|
+
// Get user's public signing key
|
|
109
|
+
const userKeys = await this.directory.getUserPublicKeys(username);
|
|
110
|
+
if (!userKeys) {
|
|
111
|
+
console.log(`[AuthenticationService] User not found or revoked: ${username}`);
|
|
112
|
+
return {
|
|
113
|
+
success: false,
|
|
114
|
+
error: "User not found or revoked",
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// Verify signature
|
|
118
|
+
const isValid = await this.verifySignature(challenge, signature, userKeys.signingPublicKey);
|
|
119
|
+
if (!isValid) {
|
|
120
|
+
console.log(`[AuthenticationService] Invalid signature for user: ${username}`);
|
|
121
|
+
return {
|
|
122
|
+
success: false,
|
|
123
|
+
error: "Invalid signature",
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
// Generate JWT token
|
|
127
|
+
const token = await this.generateToken(username);
|
|
128
|
+
console.log(`[AuthenticationService] Authentication successful for user: ${username}`);
|
|
129
|
+
return {
|
|
130
|
+
success: true,
|
|
131
|
+
token,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Validate a JWT token.
|
|
136
|
+
*
|
|
137
|
+
* @param token The JWT token to validate
|
|
138
|
+
* @returns The token payload if valid, null otherwise
|
|
139
|
+
*/
|
|
140
|
+
async validateToken(token) {
|
|
141
|
+
console.log(`[AuthenticationService] Validating token`);
|
|
142
|
+
try {
|
|
143
|
+
const payload = await this.verifyToken(token);
|
|
144
|
+
if (!payload) {
|
|
145
|
+
console.log(`[AuthenticationService] Invalid token signature`);
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
// Check expiration
|
|
149
|
+
const now = Math.floor(Date.now() / 1000);
|
|
150
|
+
if (payload.exp < now) {
|
|
151
|
+
console.log(`[AuthenticationService] Token expired`);
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
// Check if user is still valid (not revoked)
|
|
155
|
+
const isRevoked = await this.directory.isUserRevoked(payload.sub);
|
|
156
|
+
if (isRevoked) {
|
|
157
|
+
console.log(`[AuthenticationService] User revoked: ${payload.sub}`);
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
console.log(`[AuthenticationService] Token valid for user: ${payload.sub}`);
|
|
161
|
+
return payload;
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
console.error(`[AuthenticationService] Token validation error:`, error);
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Verify an Ed25519 signature.
|
|
170
|
+
*/
|
|
171
|
+
async verifySignature(message, signature, publicKeyPem) {
|
|
172
|
+
const subtle = this.cryptoAdapter.getSubtle();
|
|
173
|
+
try {
|
|
174
|
+
// Import public key
|
|
175
|
+
const pemContents = publicKeyPem
|
|
176
|
+
.replace(/-----BEGIN PUBLIC KEY-----/g, "")
|
|
177
|
+
.replace(/-----END PUBLIC KEY-----/g, "")
|
|
178
|
+
.replace(/\s/g, "");
|
|
179
|
+
const keyData = this.base64ToUint8Array(pemContents);
|
|
180
|
+
const publicKey = await subtle.importKey("spki", keyData.buffer, { name: "Ed25519" }, false, ["verify"]);
|
|
181
|
+
// Verify signature
|
|
182
|
+
const messageBytes = new TextEncoder().encode(message);
|
|
183
|
+
const isValid = await subtle.verify({ name: "Ed25519" }, publicKey, signature.buffer.slice(signature.byteOffset, signature.byteOffset + signature.byteLength), messageBytes.buffer);
|
|
184
|
+
return isValid;
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
console.error(`[AuthenticationService] Signature verification error:`, error);
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Generate a JWT token.
|
|
193
|
+
* Uses HMAC-SHA256 for signing.
|
|
194
|
+
*/
|
|
195
|
+
async generateToken(username) {
|
|
196
|
+
const subtle = this.cryptoAdapter.getSubtle();
|
|
197
|
+
const now = Math.floor(Date.now() / 1000);
|
|
198
|
+
const payload = {
|
|
199
|
+
sub: username,
|
|
200
|
+
iat: now,
|
|
201
|
+
exp: now + Math.floor(this.tokenExpirationMs / 1000),
|
|
202
|
+
tenantId: this.tenantId,
|
|
203
|
+
};
|
|
204
|
+
// Create JWT header and payload
|
|
205
|
+
const header = { alg: "HS256", typ: "JWT" };
|
|
206
|
+
const headerB64 = this.base64UrlEncode(JSON.stringify(header));
|
|
207
|
+
const payloadB64 = this.base64UrlEncode(JSON.stringify(payload));
|
|
208
|
+
// Sign with HMAC-SHA256
|
|
209
|
+
const signingKey = await subtle.importKey("raw", this.jwtSecret.buffer, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
210
|
+
const dataToSign = new TextEncoder().encode(`${headerB64}.${payloadB64}`);
|
|
211
|
+
const signature = await subtle.sign("HMAC", signingKey, dataToSign.buffer);
|
|
212
|
+
const signatureB64 = this.uint8ArrayToBase64Url(new Uint8Array(signature));
|
|
213
|
+
return `${headerB64}.${payloadB64}.${signatureB64}`;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Verify and decode a JWT token.
|
|
217
|
+
*/
|
|
218
|
+
async verifyToken(token) {
|
|
219
|
+
const subtle = this.cryptoAdapter.getSubtle();
|
|
220
|
+
const parts = token.split(".");
|
|
221
|
+
if (parts.length !== 3) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
const [headerB64, payloadB64, signatureB64] = parts;
|
|
225
|
+
try {
|
|
226
|
+
// Verify signature
|
|
227
|
+
const signingKey = await subtle.importKey("raw", this.jwtSecret.buffer, { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
|
|
228
|
+
const dataToVerify = new TextEncoder().encode(`${headerB64}.${payloadB64}`);
|
|
229
|
+
const signature = this.base64UrlToUint8Array(signatureB64);
|
|
230
|
+
const isValid = await subtle.verify("HMAC", signingKey, signature.buffer.slice(signature.byteOffset, signature.byteOffset + signature.byteLength), dataToVerify.buffer);
|
|
231
|
+
if (!isValid) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
// Decode payload
|
|
235
|
+
const payloadJson = this.base64UrlDecode(payloadB64);
|
|
236
|
+
const payload = JSON.parse(payloadJson);
|
|
237
|
+
return payload;
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
console.error(`[AuthenticationService] Token verification error:`, error);
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Clean up expired challenges.
|
|
246
|
+
*/
|
|
247
|
+
cleanupExpiredChallenges() {
|
|
248
|
+
const now = Date.now();
|
|
249
|
+
for (const [challenge, authChallenge] of this.challenges) {
|
|
250
|
+
if (authChallenge.expiresAt < now) {
|
|
251
|
+
this.challenges.delete(challenge);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Base64 URL encoding/decoding utilities
|
|
256
|
+
base64UrlEncode(str) {
|
|
257
|
+
const base64 = btoa(str);
|
|
258
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
259
|
+
}
|
|
260
|
+
base64UrlDecode(str) {
|
|
261
|
+
let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
262
|
+
while (base64.length % 4) {
|
|
263
|
+
base64 += "=";
|
|
264
|
+
}
|
|
265
|
+
return atob(base64);
|
|
266
|
+
}
|
|
267
|
+
uint8ArrayToBase64Url(bytes) {
|
|
268
|
+
let binary = "";
|
|
269
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
270
|
+
binary += String.fromCharCode(bytes[i]);
|
|
271
|
+
}
|
|
272
|
+
const base64 = btoa(binary);
|
|
273
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
274
|
+
}
|
|
275
|
+
base64UrlToUint8Array(str) {
|
|
276
|
+
let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
277
|
+
while (base64.length % 4) {
|
|
278
|
+
base64 += "=";
|
|
279
|
+
}
|
|
280
|
+
const binary = atob(base64);
|
|
281
|
+
const bytes = new Uint8Array(binary.length);
|
|
282
|
+
for (let i = 0; i < binary.length; i++) {
|
|
283
|
+
bytes[i] = binary.charCodeAt(i);
|
|
284
|
+
}
|
|
285
|
+
return bytes;
|
|
286
|
+
}
|
|
287
|
+
base64ToUint8Array(base64) {
|
|
288
|
+
const binary = atob(base64);
|
|
289
|
+
const bytes = new Uint8Array(binary.length);
|
|
290
|
+
for (let i = 0; i < binary.length; i++) {
|
|
291
|
+
bytes[i] = binary.charCodeAt(i);
|
|
292
|
+
}
|
|
293
|
+
return bytes;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
exports.AuthenticationService = AuthenticationService;
|
|
297
|
+
//# sourceMappingURL=AuthenticationService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AuthenticationService.js","sourceRoot":"","sources":["../../../../src/core/appendonlystores/network/AuthenticationService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import type { StoreEntry, StoreEntryMetadata } from "../../types";
|
|
2
|
+
import type { NetworkEncryptedEntry, AuthResult } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Abstract interface for network communication in MindooDB sync.
|
|
5
|
+
*
|
|
6
|
+
* This interface defines the protocol for secure communication between
|
|
7
|
+
* clients and servers (or peer-to-peer). It can be implemented for various
|
|
8
|
+
* transport protocols like HTTP, WebSocket, WebRTC, etc.
|
|
9
|
+
*
|
|
10
|
+
* The authentication flow is:
|
|
11
|
+
* 1. Client calls requestChallenge(username) to get a challenge string
|
|
12
|
+
* 2. Client signs the challenge with their private signing key
|
|
13
|
+
* 3. Client calls authenticate(challenge, signature) to get a JWT token
|
|
14
|
+
* 4. Client uses the token for subsequent findNewEntries() and getEntries() calls
|
|
15
|
+
*
|
|
16
|
+
* Security features:
|
|
17
|
+
* - Challenge-response prevents replay attacks
|
|
18
|
+
* - JWT tokens have expiration for session management
|
|
19
|
+
* - Entry payloads are RSA-encrypted with recipient's public key
|
|
20
|
+
*/
|
|
21
|
+
export interface NetworkTransport {
|
|
22
|
+
/**
|
|
23
|
+
* Request a challenge string for authentication.
|
|
24
|
+
*
|
|
25
|
+
* The server generates a unique challenge (UUID v7) that the client
|
|
26
|
+
* must sign with their private signing key to prove identity.
|
|
27
|
+
*
|
|
28
|
+
* @param username The username requesting authentication
|
|
29
|
+
* @returns The challenge string (UUID v7) to be signed
|
|
30
|
+
* @throws NetworkError with type USER_NOT_FOUND if user doesn't exist
|
|
31
|
+
* @throws NetworkError with type USER_REVOKED if user has been revoked
|
|
32
|
+
*/
|
|
33
|
+
requestChallenge(username: string): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Authenticate by providing a signed challenge.
|
|
36
|
+
*
|
|
37
|
+
* The server verifies the signature using the user's public signing key
|
|
38
|
+
* from the tenant directory. If valid, returns a JWT access token.
|
|
39
|
+
*
|
|
40
|
+
* @param challenge The challenge string that was signed
|
|
41
|
+
* @param signature The Ed25519 signature of the challenge
|
|
42
|
+
* @returns AuthResult with success status and JWT token (if successful)
|
|
43
|
+
* @throws NetworkError with type INVALID_SIGNATURE if signature verification fails
|
|
44
|
+
* @throws NetworkError with type CHALLENGE_EXPIRED if challenge has expired or was already used
|
|
45
|
+
* @throws NetworkError with type USER_REVOKED if user has been revoked
|
|
46
|
+
*/
|
|
47
|
+
authenticate(challenge: string, signature: Uint8Array): Promise<AuthResult>;
|
|
48
|
+
/**
|
|
49
|
+
* Find entries that the remote has which we don't have locally.
|
|
50
|
+
*
|
|
51
|
+
* This is used to identify which entries need to be synchronized.
|
|
52
|
+
* The returned StoreEntryMetadata contains metadata only (no encrypted payload).
|
|
53
|
+
*
|
|
54
|
+
* @param token JWT access token from authenticate()
|
|
55
|
+
* @param haveIds List of entry IDs we already have locally
|
|
56
|
+
* @returns List of entry metadata for entries that exist remotely but not locally
|
|
57
|
+
* @throws NetworkError with type INVALID_TOKEN if token is invalid or expired
|
|
58
|
+
* @throws NetworkError with type USER_REVOKED if user has been revoked since token was issued
|
|
59
|
+
*/
|
|
60
|
+
findNewEntries(token: string, haveIds: string[]): Promise<StoreEntryMetadata[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Find entries for a specific document that the remote has which we don't have locally.
|
|
63
|
+
*
|
|
64
|
+
* This is an optimized version of findNewEntries that only returns entries for a specific document.
|
|
65
|
+
*
|
|
66
|
+
* @param token JWT access token from authenticate()
|
|
67
|
+
* @param haveIds List of entry IDs we already have locally for this document
|
|
68
|
+
* @param docId The document ID to filter by
|
|
69
|
+
* @returns List of entry metadata for the specified document that exist remotely but not locally
|
|
70
|
+
* @throws NetworkError with type INVALID_TOKEN if token is invalid or expired
|
|
71
|
+
* @throws NetworkError with type USER_REVOKED if user has been revoked since token was issued
|
|
72
|
+
*/
|
|
73
|
+
findNewEntriesForDoc(token: string, haveIds: string[], docId: string): Promise<StoreEntryMetadata[]>;
|
|
74
|
+
/**
|
|
75
|
+
* Get entries from the remote store.
|
|
76
|
+
*
|
|
77
|
+
* The returned entries have their payloads RSA-encrypted with the
|
|
78
|
+
* requesting user's public encryption key. The client must decrypt
|
|
79
|
+
* these with their private key to get the original payload.
|
|
80
|
+
*
|
|
81
|
+
* @param token JWT access token from authenticate()
|
|
82
|
+
* @param ids The IDs of entries to retrieve
|
|
83
|
+
* @returns NetworkEncryptedEntry[] with RSA-encrypted payloads
|
|
84
|
+
* @throws NetworkError with type INVALID_TOKEN if token is invalid or expired
|
|
85
|
+
* @throws NetworkError with type USER_REVOKED if user has been revoked since token was issued
|
|
86
|
+
*/
|
|
87
|
+
getEntries(token: string, ids: string[]): Promise<NetworkEncryptedEntry[]>;
|
|
88
|
+
/**
|
|
89
|
+
* Push entries to the remote store.
|
|
90
|
+
*
|
|
91
|
+
* This is used to send locally-created entries to the server for storage.
|
|
92
|
+
* The server will verify that the entry was created by a trusted user
|
|
93
|
+
* (by checking the createdByPublicKey against the tenant directory).
|
|
94
|
+
*
|
|
95
|
+
* @param token JWT access token from authenticate()
|
|
96
|
+
* @param entries The entries to push to the remote store
|
|
97
|
+
* @throws NetworkError with type INVALID_TOKEN if token is invalid or expired
|
|
98
|
+
* @throws NetworkError with type USER_REVOKED if user has been revoked since token was issued
|
|
99
|
+
* @throws NetworkError with type INVALID_SIGNATURE if entry signature verification fails
|
|
100
|
+
*/
|
|
101
|
+
putEntries(token: string, entries: StoreEntry[]): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Check which of the provided IDs exist in the remote store.
|
|
104
|
+
*
|
|
105
|
+
* This is more efficient than getAllIds() when checking a small number of IDs,
|
|
106
|
+
* as it only transfers the IDs that exist rather than all IDs in the store.
|
|
107
|
+
*
|
|
108
|
+
* @param token JWT access token from authenticate()
|
|
109
|
+
* @param ids The IDs to check for existence
|
|
110
|
+
* @returns List of IDs that exist in the remote store (subset of input)
|
|
111
|
+
* @throws NetworkError with type INVALID_TOKEN if token is invalid or expired
|
|
112
|
+
* @throws NetworkError with type USER_REVOKED if user has been revoked since token was issued
|
|
113
|
+
*/
|
|
114
|
+
hasEntries(token: string, ids: string[]): Promise<string[]>;
|
|
115
|
+
/**
|
|
116
|
+
* Get all entry IDs from the remote store.
|
|
117
|
+
*
|
|
118
|
+
* This is used for synchronization to identify which entries the remote has.
|
|
119
|
+
* Returns only the IDs (not the full entries) for efficiency.
|
|
120
|
+
*
|
|
121
|
+
* @param token JWT access token from authenticate()
|
|
122
|
+
* @returns List of all entry IDs in the remote store
|
|
123
|
+
* @throws NetworkError with type INVALID_TOKEN if token is invalid or expired
|
|
124
|
+
* @throws NetworkError with type USER_REVOKED if user has been revoked since token was issued
|
|
125
|
+
*/
|
|
126
|
+
getAllIds(token: string): Promise<string[]>;
|
|
127
|
+
/**
|
|
128
|
+
* Resolve the dependency chain starting from an entry ID.
|
|
129
|
+
*
|
|
130
|
+
* Returns IDs in dependency order, traversing backward through dependencyIds.
|
|
131
|
+
* This is more efficient than client-side traversal as it avoids multiple round trips.
|
|
132
|
+
*
|
|
133
|
+
* @param token JWT access token from authenticate()
|
|
134
|
+
* @param startId The entry ID to start traversal from
|
|
135
|
+
* @param options Optional traversal options:
|
|
136
|
+
* - stopAtEntryType: Stop when encountering an entry of this type (e.g., "doc_snapshot")
|
|
137
|
+
* - maxDepth: Maximum number of hops to traverse
|
|
138
|
+
* - includeStart: Whether to include startId in the result (default: true)
|
|
139
|
+
* @returns List of entry IDs in dependency order (oldest first)
|
|
140
|
+
* @throws NetworkError with type INVALID_TOKEN if token is invalid or expired
|
|
141
|
+
* @throws NetworkError with type USER_REVOKED if user has been revoked since token was issued
|
|
142
|
+
*/
|
|
143
|
+
resolveDependencies(token: string, startId: string, options?: Record<string, unknown>): Promise<string[]>;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Configuration options for network transport implementations.
|
|
147
|
+
*/
|
|
148
|
+
export interface NetworkTransportConfig {
|
|
149
|
+
/**
|
|
150
|
+
* Base URL for the remote server (for HTTP transport)
|
|
151
|
+
*/
|
|
152
|
+
baseUrl?: string;
|
|
153
|
+
/**
|
|
154
|
+
* Timeout for network requests in milliseconds (default: 30000)
|
|
155
|
+
*/
|
|
156
|
+
timeout?: number;
|
|
157
|
+
/**
|
|
158
|
+
* Number of retry attempts for failed requests (default: 3)
|
|
159
|
+
*/
|
|
160
|
+
retryAttempts?: number;
|
|
161
|
+
/**
|
|
162
|
+
* Base delay for exponential backoff in milliseconds (default: 1000)
|
|
163
|
+
*/
|
|
164
|
+
retryDelayMs?: number;
|
|
165
|
+
/**
|
|
166
|
+
* Tenant ID for scoping requests
|
|
167
|
+
*/
|
|
168
|
+
tenantId: string;
|
|
169
|
+
/**
|
|
170
|
+
* Database ID for scoping requests (optional)
|
|
171
|
+
*/
|
|
172
|
+
dbId?: string;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=NetworkTransport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkTransport.d.ts","sourceRoot":"","sources":["../../../../src/core/appendonlystores/network/NetworkTransport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEjE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpD;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAE5E;;;;;;;;;;;OAWG;IACH,cAAc,CACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAEjC;;;;;;;;;;;OAWG;IACH,oBAAoB,CAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAEjC;;;;;;;;;;;;OAYG;IACH,UAAU,CACR,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EAAE,GACZ,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IAEpC;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE5D;;;;;;;;;;OAUG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE5C;;;;;;;;;;;;;;;OAeG;IACH,mBAAmB,CACjB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NetworkTransport.js","sourceRoot":"","sources":["../../../../src/core/appendonlystores/network/NetworkTransport.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { StoreEntryMetadata } from "../../types";
|
|
2
|
+
/**
|
|
3
|
+
* Network-encrypted entry for secure transport over the network.
|
|
4
|
+
*
|
|
5
|
+
* Extends StoreEntryMetadata (metadata stays clear for routing/filtering)
|
|
6
|
+
* but adds an RSA-encrypted version of the payload for transport security.
|
|
7
|
+
*
|
|
8
|
+
* The metadata (docId, id, etc.) is transmitted unencrypted to allow
|
|
9
|
+
* efficient filtering and routing without requiring decryption. The actual
|
|
10
|
+
* payload data is RSA-encrypted with the recipient's public encryption key.
|
|
11
|
+
*/
|
|
12
|
+
export interface NetworkEncryptedEntry extends StoreEntryMetadata {
|
|
13
|
+
/**
|
|
14
|
+
* The original symmetric-encrypted payload, wrapped in RSA encryption
|
|
15
|
+
* for secure network transport.
|
|
16
|
+
*
|
|
17
|
+
* Must be decrypted with the recipient's RSA private key to get the
|
|
18
|
+
* original StoreEntry.encryptedData (which is still encrypted with
|
|
19
|
+
* the symmetric key).
|
|
20
|
+
*
|
|
21
|
+
* This provides defense-in-depth: even if RSA is compromised, the
|
|
22
|
+
* underlying symmetric encryption remains intact.
|
|
23
|
+
*/
|
|
24
|
+
rsaEncryptedPayload: Uint8Array;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* User public keys retrieved from the tenant directory.
|
|
28
|
+
* Used for authentication (signature verification) and encryption (transport encryption).
|
|
29
|
+
*/
|
|
30
|
+
export interface UserPublicKeys {
|
|
31
|
+
/**
|
|
32
|
+
* The user's public signing key (Ed25519, PEM format).
|
|
33
|
+
* Used for verifying signatures on challenges during authentication.
|
|
34
|
+
*/
|
|
35
|
+
signingPublicKey: string;
|
|
36
|
+
/**
|
|
37
|
+
* The user's public encryption key (RSA-OAEP, PEM format).
|
|
38
|
+
* Used for encrypting change payloads for network transport.
|
|
39
|
+
*/
|
|
40
|
+
encryptionPublicKey: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* JWT token payload structure for authenticated sessions.
|
|
44
|
+
*/
|
|
45
|
+
export interface NetworkAuthTokenPayload {
|
|
46
|
+
/**
|
|
47
|
+
* Subject: the username of the authenticated user
|
|
48
|
+
*/
|
|
49
|
+
sub: string;
|
|
50
|
+
/**
|
|
51
|
+
* Issued at: timestamp when the token was issued (Unix epoch seconds)
|
|
52
|
+
*/
|
|
53
|
+
iat: number;
|
|
54
|
+
/**
|
|
55
|
+
* Expiration: timestamp when the token expires (Unix epoch seconds)
|
|
56
|
+
*/
|
|
57
|
+
exp: number;
|
|
58
|
+
/**
|
|
59
|
+
* Tenant ID this token is valid for
|
|
60
|
+
*/
|
|
61
|
+
tenantId: string;
|
|
62
|
+
/**
|
|
63
|
+
* Optional: database ID if token is scoped to a specific database
|
|
64
|
+
*/
|
|
65
|
+
dbId?: string;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Challenge stored server-side for authentication.
|
|
69
|
+
*/
|
|
70
|
+
export interface AuthChallenge {
|
|
71
|
+
/**
|
|
72
|
+
* The challenge string (UUID v7)
|
|
73
|
+
*/
|
|
74
|
+
challenge: string;
|
|
75
|
+
/**
|
|
76
|
+
* The username this challenge was issued for
|
|
77
|
+
*/
|
|
78
|
+
username: string;
|
|
79
|
+
/**
|
|
80
|
+
* Timestamp when the challenge was created (Unix epoch milliseconds)
|
|
81
|
+
*/
|
|
82
|
+
createdAt: number;
|
|
83
|
+
/**
|
|
84
|
+
* Timestamp when the challenge expires (Unix epoch milliseconds)
|
|
85
|
+
*/
|
|
86
|
+
expiresAt: number;
|
|
87
|
+
/**
|
|
88
|
+
* Whether the challenge has been used (for single-use enforcement)
|
|
89
|
+
*/
|
|
90
|
+
used: boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Result of an authentication attempt.
|
|
94
|
+
*/
|
|
95
|
+
export interface AuthResult {
|
|
96
|
+
/**
|
|
97
|
+
* Whether authentication was successful
|
|
98
|
+
*/
|
|
99
|
+
success: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* JWT access token (only present if success is true)
|
|
102
|
+
*/
|
|
103
|
+
token?: string;
|
|
104
|
+
/**
|
|
105
|
+
* Error message (only present if success is false)
|
|
106
|
+
*/
|
|
107
|
+
error?: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Network transport error types for error handling.
|
|
111
|
+
*/
|
|
112
|
+
export declare enum NetworkErrorType {
|
|
113
|
+
/** Token is invalid or expired */
|
|
114
|
+
INVALID_TOKEN = "INVALID_TOKEN",
|
|
115
|
+
/** User has been revoked */
|
|
116
|
+
USER_REVOKED = "USER_REVOKED",
|
|
117
|
+
/** Signature verification failed */
|
|
118
|
+
INVALID_SIGNATURE = "INVALID_SIGNATURE",
|
|
119
|
+
/** Challenge expired or already used */
|
|
120
|
+
CHALLENGE_EXPIRED = "CHALLENGE_EXPIRED",
|
|
121
|
+
/** Network communication error */
|
|
122
|
+
NETWORK_ERROR = "NETWORK_ERROR",
|
|
123
|
+
/** Server-side error */
|
|
124
|
+
SERVER_ERROR = "SERVER_ERROR",
|
|
125
|
+
/** User not found in directory */
|
|
126
|
+
USER_NOT_FOUND = "USER_NOT_FOUND"
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Network transport error with type for structured error handling.
|
|
130
|
+
*/
|
|
131
|
+
export declare class NetworkError extends Error {
|
|
132
|
+
readonly type: NetworkErrorType;
|
|
133
|
+
constructor(type: NetworkErrorType, message: string);
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/core/appendonlystores/network/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD;;;;;;;;;GASG;AACH,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D;;;;;;;;;;OAUG;IACH,mBAAmB,EAAE,UAAU,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,oBAAY,gBAAgB;IAC1B,kCAAkC;IAClC,aAAa,kBAAkB;IAC/B,4BAA4B;IAC5B,YAAY,iBAAiB;IAC7B,oCAAoC;IACpC,iBAAiB,sBAAsB;IACvC,wCAAwC;IACxC,iBAAiB,sBAAsB;IACvC,kCAAkC;IAClC,aAAa,kBAAkB;IAC/B,wBAAwB;IACxB,YAAY,iBAAiB;IAC7B,kCAAkC;IAClC,cAAc,mBAAmB;CAClC;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;aAEnB,IAAI,EAAE,gBAAgB;gBAAtB,IAAI,EAAE,gBAAgB,EACtC,OAAO,EAAE,MAAM;CAKlB"}
|