@arbidocs/client 0.4.2 → 0.4.4
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/index.cjs +132 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +43 -2
- package/dist/index.d.ts +43 -2
- package/dist/index.js +132 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -17199,6 +17199,13 @@ interface AutoReloginMiddlewareConfig {
|
|
|
17199
17199
|
reloginHandler: ReloginHandler;
|
|
17200
17200
|
/** URL substrings that should never trigger re-login (e.g. the login endpoint itself) */
|
|
17201
17201
|
reloginExcludePatterns?: string[];
|
|
17202
|
+
/**
|
|
17203
|
+
* Re-open the selected workspace on the server session without a new login. Resolves true when
|
|
17204
|
+
* done. Used on 400 "No active workspace" (the server lost the open-workspace state while the
|
|
17205
|
+
* token is still valid); when it is absent or returns false, a full re-login (which also
|
|
17206
|
+
* re-opens the workspace) is tried instead.
|
|
17207
|
+
*/
|
|
17208
|
+
reopenWorkspaceHandler?: () => Promise<boolean>;
|
|
17202
17209
|
onRetryCloneFailed?: () => void;
|
|
17203
17210
|
/** Called when re-login was attempted but failed (returned null). Use to clear stale auth state. */
|
|
17204
17211
|
onReloginFailed?: () => void;
|
|
@@ -17815,6 +17822,13 @@ interface ArbiClientOptions {
|
|
|
17815
17822
|
userExtId?: string;
|
|
17816
17823
|
serverSessionKey: Uint8Array;
|
|
17817
17824
|
}) => void;
|
|
17825
|
+
/**
|
|
17826
|
+
* Called when the session cannot be recovered: a request failed with 401 (or 400 "No active
|
|
17827
|
+
* workspace") and neither a workspace re-open nor a silent re-login worked because the server
|
|
17828
|
+
* REFUSED it (not a network failure, which leaves the session alone). The host shows "your
|
|
17829
|
+
* session expired, sign in again". Not called before anyone has logged in.
|
|
17830
|
+
*/
|
|
17831
|
+
onSessionExpired?: () => void;
|
|
17818
17832
|
/**
|
|
17819
17833
|
* Optional session storage provider for the relogin handler.
|
|
17820
17834
|
*
|
|
@@ -17844,8 +17858,10 @@ interface ArbiClient {
|
|
|
17844
17858
|
loginWithKey(params: LoginWithKeyParams): Promise<LoginResult>;
|
|
17845
17859
|
logout(): Promise<void>;
|
|
17846
17860
|
changePassword(params: ChangePasswordParams): Promise<ChangePasswordResult>;
|
|
17847
|
-
/** Instant re-login using stored private key */
|
|
17861
|
+
/** Instant re-login using stored private key (re-opens the selected workspace too) */
|
|
17848
17862
|
relogin(): Promise<string | null>;
|
|
17863
|
+
/** Re-open the selected workspace on the server session, without a new login */
|
|
17864
|
+
reopenWorkspace(): Promise<boolean>;
|
|
17849
17865
|
};
|
|
17850
17866
|
/** Crypto utilities */
|
|
17851
17867
|
crypto: {
|
|
@@ -17967,4 +17983,29 @@ declare function isMessageType<T extends WebSocketServerMessage>(msg: WebSocketS
|
|
|
17967
17983
|
*/
|
|
17968
17984
|
declare function createReloginHandler(deps: ReloginDeps): () => Promise<string | null>;
|
|
17969
17985
|
|
|
17970
|
-
|
|
17986
|
+
/**
|
|
17987
|
+
* Workspace re-open (no re-login)
|
|
17988
|
+
*
|
|
17989
|
+
* The server keeps "which workspace is open, and its key sealed for this session" on the session.
|
|
17990
|
+
* When that state is gone while the access token is still valid (a server restart, a rotated
|
|
17991
|
+
* session, an expired workspace session), requests fail with 400 "No active workspace - call
|
|
17992
|
+
* /open first". Re-opening needs no new login: unwrap the workspace key with the stored signing
|
|
17993
|
+
* key, seal it for the stored server session key, POST /open.
|
|
17994
|
+
*/
|
|
17995
|
+
|
|
17996
|
+
interface ReopenDeps {
|
|
17997
|
+
crypto: Pick<CryptoProvider, 'ensureReady' | 'deriveEncryptionKeypair' | 'sealedBoxDecrypt' | 'sealKeyForSession'>;
|
|
17998
|
+
sessionStorage: SessionStorageProvider;
|
|
17999
|
+
authState: Pick<AuthStateProvider, 'getSelectedWorkspaceId'>;
|
|
18000
|
+
getAccessToken(): string | null;
|
|
18001
|
+
workspaceKeyRefreshProvider: WorkspaceKeyRefreshProvider;
|
|
18002
|
+
workspaceOpenProvider: WorkspaceOpenProvider;
|
|
18003
|
+
}
|
|
18004
|
+
/**
|
|
18005
|
+
* Returns `reopenWorkspace()`: resolves true when the selected workspace is open again on the
|
|
18006
|
+
* server session, false when it cannot be (nothing selected, no stored keys, server refused).
|
|
18007
|
+
* Concurrent calls share one in-flight attempt.
|
|
18008
|
+
*/
|
|
18009
|
+
declare function createWorkspaceReopener(deps: ReopenDeps): () => Promise<boolean>;
|
|
18010
|
+
|
|
18011
|
+
export { type $defs, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, type KeyPair, type LoginCredentials, type LoginParams, type LoginProvider, type LoginRequest, type LoginResult, type LoginWithKeyParams, type OnReloginSuccess, type PasswordChangeCredentials, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginHandler, type ReopenDeps, type SessionData, type SessionKeys, type SessionManager, type SessionState, type SessionStorageProvider, type SsoTokenProvider, type TokenProvider, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceOpenProvider, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsConnectionClosedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, clearAllData, clearSession, type components, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, type operations, parseServerMessage, type paths, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey, type webhooks };
|
package/dist/index.d.ts
CHANGED
|
@@ -17199,6 +17199,13 @@ interface AutoReloginMiddlewareConfig {
|
|
|
17199
17199
|
reloginHandler: ReloginHandler;
|
|
17200
17200
|
/** URL substrings that should never trigger re-login (e.g. the login endpoint itself) */
|
|
17201
17201
|
reloginExcludePatterns?: string[];
|
|
17202
|
+
/**
|
|
17203
|
+
* Re-open the selected workspace on the server session without a new login. Resolves true when
|
|
17204
|
+
* done. Used on 400 "No active workspace" (the server lost the open-workspace state while the
|
|
17205
|
+
* token is still valid); when it is absent or returns false, a full re-login (which also
|
|
17206
|
+
* re-opens the workspace) is tried instead.
|
|
17207
|
+
*/
|
|
17208
|
+
reopenWorkspaceHandler?: () => Promise<boolean>;
|
|
17202
17209
|
onRetryCloneFailed?: () => void;
|
|
17203
17210
|
/** Called when re-login was attempted but failed (returned null). Use to clear stale auth state. */
|
|
17204
17211
|
onReloginFailed?: () => void;
|
|
@@ -17815,6 +17822,13 @@ interface ArbiClientOptions {
|
|
|
17815
17822
|
userExtId?: string;
|
|
17816
17823
|
serverSessionKey: Uint8Array;
|
|
17817
17824
|
}) => void;
|
|
17825
|
+
/**
|
|
17826
|
+
* Called when the session cannot be recovered: a request failed with 401 (or 400 "No active
|
|
17827
|
+
* workspace") and neither a workspace re-open nor a silent re-login worked because the server
|
|
17828
|
+
* REFUSED it (not a network failure, which leaves the session alone). The host shows "your
|
|
17829
|
+
* session expired, sign in again". Not called before anyone has logged in.
|
|
17830
|
+
*/
|
|
17831
|
+
onSessionExpired?: () => void;
|
|
17818
17832
|
/**
|
|
17819
17833
|
* Optional session storage provider for the relogin handler.
|
|
17820
17834
|
*
|
|
@@ -17844,8 +17858,10 @@ interface ArbiClient {
|
|
|
17844
17858
|
loginWithKey(params: LoginWithKeyParams): Promise<LoginResult>;
|
|
17845
17859
|
logout(): Promise<void>;
|
|
17846
17860
|
changePassword(params: ChangePasswordParams): Promise<ChangePasswordResult>;
|
|
17847
|
-
/** Instant re-login using stored private key */
|
|
17861
|
+
/** Instant re-login using stored private key (re-opens the selected workspace too) */
|
|
17848
17862
|
relogin(): Promise<string | null>;
|
|
17863
|
+
/** Re-open the selected workspace on the server session, without a new login */
|
|
17864
|
+
reopenWorkspace(): Promise<boolean>;
|
|
17849
17865
|
};
|
|
17850
17866
|
/** Crypto utilities */
|
|
17851
17867
|
crypto: {
|
|
@@ -17967,4 +17983,29 @@ declare function isMessageType<T extends WebSocketServerMessage>(msg: WebSocketS
|
|
|
17967
17983
|
*/
|
|
17968
17984
|
declare function createReloginHandler(deps: ReloginDeps): () => Promise<string | null>;
|
|
17969
17985
|
|
|
17970
|
-
|
|
17986
|
+
/**
|
|
17987
|
+
* Workspace re-open (no re-login)
|
|
17988
|
+
*
|
|
17989
|
+
* The server keeps "which workspace is open, and its key sealed for this session" on the session.
|
|
17990
|
+
* When that state is gone while the access token is still valid (a server restart, a rotated
|
|
17991
|
+
* session, an expired workspace session), requests fail with 400 "No active workspace - call
|
|
17992
|
+
* /open first". Re-opening needs no new login: unwrap the workspace key with the stored signing
|
|
17993
|
+
* key, seal it for the stored server session key, POST /open.
|
|
17994
|
+
*/
|
|
17995
|
+
|
|
17996
|
+
interface ReopenDeps {
|
|
17997
|
+
crypto: Pick<CryptoProvider, 'ensureReady' | 'deriveEncryptionKeypair' | 'sealedBoxDecrypt' | 'sealKeyForSession'>;
|
|
17998
|
+
sessionStorage: SessionStorageProvider;
|
|
17999
|
+
authState: Pick<AuthStateProvider, 'getSelectedWorkspaceId'>;
|
|
18000
|
+
getAccessToken(): string | null;
|
|
18001
|
+
workspaceKeyRefreshProvider: WorkspaceKeyRefreshProvider;
|
|
18002
|
+
workspaceOpenProvider: WorkspaceOpenProvider;
|
|
18003
|
+
}
|
|
18004
|
+
/**
|
|
18005
|
+
* Returns `reopenWorkspace()`: resolves true when the selected workspace is open again on the
|
|
18006
|
+
* server session, false when it cannot be (nothing selected, no stored keys, server refused).
|
|
18007
|
+
* Concurrent calls share one in-flight attempt.
|
|
18008
|
+
*/
|
|
18009
|
+
declare function createWorkspaceReopener(deps: ReopenDeps): () => Promise<boolean>;
|
|
18010
|
+
|
|
18011
|
+
export { type $defs, API_PREFIX, type ArbiClient, type ArbiClientOptions, type AuthStateProvider, type AutoReloginMiddlewareConfig, type BearerAuthMiddlewareConfig, type ChangePasswordParams, type ChangePasswordRequest, type ChangePasswordResult, type CryptoProvider, type KeyPair, type LoginCredentials, type LoginParams, type LoginProvider, type LoginRequest, type LoginResult, type LoginWithKeyParams, type OnReloginSuccess, type PasswordChangeCredentials, type RegisterParams, type RegisterRequest, type RegisterResult, type RegistrationCredentials, type ReloginDeps, type ReloginHandler, type ReopenDeps, type SessionData, type SessionKeys, type SessionManager, type SessionState, type SessionStorageProvider, type SsoTokenProvider, type TokenProvider, type UserKeypairs, type WebSocketClientMessage, type WebSocketServerMessage, type WorkspaceKeyRefreshProvider, type WorkspaceOpenProvider, type WsAuthMessage, type WsAuthResultMessage, type WsBatchCompleteMessage, type WsConnectionClosedMessage, type WsErrorMessage, type WsNotificationResponse, type WsPresenceUpdateMessage, type WsResponseCompleteMessage, type WsTaskUpdateMessage, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, clearAllData, clearSession, type components, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, type operations, parseServerMessage, type paths, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey, type webhooks };
|
package/dist/index.js
CHANGED
|
@@ -385,6 +385,21 @@ function createBearerAuthMiddleware(config) {
|
|
|
385
385
|
}
|
|
386
386
|
|
|
387
387
|
// src/middleware/auto-relogin.ts
|
|
388
|
+
var NO_ACTIVE_WORKSPACE = /no active workspace/i;
|
|
389
|
+
async function isNoActiveWorkspace(response) {
|
|
390
|
+
try {
|
|
391
|
+
return NO_ACTIVE_WORKSPACE.test(await response.clone().text());
|
|
392
|
+
} catch {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
function safeClone(request) {
|
|
397
|
+
try {
|
|
398
|
+
return request.clone();
|
|
399
|
+
} catch {
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
388
403
|
function createAutoReloginMiddleware(config) {
|
|
389
404
|
const cloneCache = /* @__PURE__ */ new WeakMap();
|
|
390
405
|
return {
|
|
@@ -395,6 +410,25 @@ function createAutoReloginMiddleware(config) {
|
|
|
395
410
|
}
|
|
396
411
|
},
|
|
397
412
|
async onResponse({ response, request }) {
|
|
413
|
+
if (response.status === 400 && await isNoActiveWorkspace(response)) {
|
|
414
|
+
let token = null;
|
|
415
|
+
let recovered = await config.reopenWorkspaceHandler?.() ?? false;
|
|
416
|
+
if (!recovered) {
|
|
417
|
+
token = await config.reloginHandler();
|
|
418
|
+
recovered = token !== null;
|
|
419
|
+
}
|
|
420
|
+
if (!recovered) {
|
|
421
|
+
config.onReloginFailed?.();
|
|
422
|
+
return response;
|
|
423
|
+
}
|
|
424
|
+
const retry = cloneCache.get(request) ?? safeClone(request);
|
|
425
|
+
if (retry) {
|
|
426
|
+
if (token) retry.headers.set("Authorization", `Bearer ${token}`);
|
|
427
|
+
return fetch(retry);
|
|
428
|
+
}
|
|
429
|
+
config.onRetryCloneFailed?.();
|
|
430
|
+
return response;
|
|
431
|
+
}
|
|
398
432
|
if (response.status === 400) {
|
|
399
433
|
const isSafeMethod = ["GET", "HEAD", "DELETE"].includes(request.method);
|
|
400
434
|
if (isSafeMethod) {
|
|
@@ -555,6 +589,47 @@ function createReloginHandler(deps) {
|
|
|
555
589
|
};
|
|
556
590
|
}
|
|
557
591
|
|
|
592
|
+
// src/relogin/reopen.ts
|
|
593
|
+
function createWorkspaceReopener(deps) {
|
|
594
|
+
let inFlight = null;
|
|
595
|
+
return function reopenWorkspace() {
|
|
596
|
+
if (inFlight) return inFlight;
|
|
597
|
+
inFlight = (async () => {
|
|
598
|
+
try {
|
|
599
|
+
const workspaceId = deps.authState.getSelectedWorkspaceId();
|
|
600
|
+
const accessToken = deps.getAccessToken();
|
|
601
|
+
if (!workspaceId || !accessToken) return false;
|
|
602
|
+
const session = await deps.sessionStorage.getSession();
|
|
603
|
+
if (!session?.signingPrivateKey || !session.serverSessionKey) return false;
|
|
604
|
+
await deps.crypto.ensureReady();
|
|
605
|
+
const wrappedKey = await deps.workspaceKeyRefreshProvider.getWrappedKey(
|
|
606
|
+
accessToken,
|
|
607
|
+
workspaceId
|
|
608
|
+
);
|
|
609
|
+
if (!wrappedKey) return false;
|
|
610
|
+
const encryptionKeyPair = deps.crypto.deriveEncryptionKeypair({
|
|
611
|
+
publicKey: session.signingPrivateKey.slice(32, 64),
|
|
612
|
+
secretKey: session.signingPrivateKey
|
|
613
|
+
});
|
|
614
|
+
const workspaceKey = deps.crypto.sealedBoxDecrypt(wrappedKey, encryptionKeyPair.secretKey);
|
|
615
|
+
const sealed = await deps.crypto.sealKeyForSession(workspaceKey, session.serverSessionKey);
|
|
616
|
+
const opened = await deps.workspaceOpenProvider.openWorkspace(
|
|
617
|
+
accessToken,
|
|
618
|
+
workspaceId,
|
|
619
|
+
sealed
|
|
620
|
+
);
|
|
621
|
+
return opened === true;
|
|
622
|
+
} catch (error) {
|
|
623
|
+
console.error("[API] Failed to re-open workspace:", error);
|
|
624
|
+
return false;
|
|
625
|
+
} finally {
|
|
626
|
+
inFlight = null;
|
|
627
|
+
}
|
|
628
|
+
})();
|
|
629
|
+
return inFlight;
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
|
|
558
633
|
// src/storage/indexed-db.ts
|
|
559
634
|
var DB_NAME = "arbi-crypto";
|
|
560
635
|
var DB_VERSION = 2;
|
|
@@ -1002,6 +1077,7 @@ function createArbiClient(options) {
|
|
|
1002
1077
|
credentials = "include",
|
|
1003
1078
|
ssoTokenProvider = null,
|
|
1004
1079
|
onReloginSuccess,
|
|
1080
|
+
onSessionExpired,
|
|
1005
1081
|
sessionStorage: sessionStorageOverride,
|
|
1006
1082
|
userEmail
|
|
1007
1083
|
} = options;
|
|
@@ -1022,6 +1098,7 @@ function createArbiClient(options) {
|
|
|
1022
1098
|
sealKeyForSession,
|
|
1023
1099
|
fromBase64: base64ToBytes
|
|
1024
1100
|
};
|
|
1101
|
+
let reloginUnreachable = false;
|
|
1025
1102
|
const loginProvider = {
|
|
1026
1103
|
async login(payload) {
|
|
1027
1104
|
const rawFetch = createFetchClient({
|
|
@@ -1029,14 +1106,21 @@ function createArbiClient(options) {
|
|
|
1029
1106
|
credentials,
|
|
1030
1107
|
fetch: retryFetch
|
|
1031
1108
|
});
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1109
|
+
let response;
|
|
1110
|
+
try {
|
|
1111
|
+
response = await rawFetch.POST("/v1/user/login", {
|
|
1112
|
+
body: {
|
|
1113
|
+
email: payload.email,
|
|
1114
|
+
signature: payload.signature,
|
|
1115
|
+
timestamp: payload.timestamp,
|
|
1116
|
+
sso_token: payload.ssoToken
|
|
1117
|
+
}
|
|
1118
|
+
});
|
|
1119
|
+
} catch (error) {
|
|
1120
|
+
console.warn("[API] Login call unreachable:", error);
|
|
1121
|
+
reloginUnreachable = true;
|
|
1122
|
+
return null;
|
|
1123
|
+
}
|
|
1040
1124
|
if (response.error || !response.data) {
|
|
1041
1125
|
console.warn("[API] Login call failed:", response.error);
|
|
1042
1126
|
return null;
|
|
@@ -1067,15 +1151,46 @@ function createArbiClient(options) {
|
|
|
1067
1151
|
return workspace?.wrapped_key ?? null;
|
|
1068
1152
|
}
|
|
1069
1153
|
};
|
|
1070
|
-
const
|
|
1154
|
+
const workspaceOpenProvider = {
|
|
1155
|
+
async openWorkspace(accessToken, workspaceId, encryptedWorkspaceKey) {
|
|
1156
|
+
try {
|
|
1157
|
+
const response = await retryFetch(`${baseUrl}${API_PREFIX}/workspace/${workspaceId}/open`, {
|
|
1158
|
+
method: "POST",
|
|
1159
|
+
headers: {
|
|
1160
|
+
Authorization: `Bearer ${accessToken}`,
|
|
1161
|
+
"Content-Type": "application/json"
|
|
1162
|
+
},
|
|
1163
|
+
body: JSON.stringify({ workspace_key: encryptedWorkspaceKey }),
|
|
1164
|
+
credentials
|
|
1165
|
+
});
|
|
1166
|
+
return response.ok ? true : null;
|
|
1167
|
+
} catch {
|
|
1168
|
+
return null;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
const rawReloginHandler = createReloginHandler({
|
|
1071
1173
|
crypto: cryptoProvider,
|
|
1072
1174
|
sessionStorage,
|
|
1073
1175
|
authState,
|
|
1074
1176
|
ssoTokenProvider,
|
|
1075
1177
|
loginProvider,
|
|
1076
1178
|
workspaceKeyRefreshProvider,
|
|
1179
|
+
workspaceOpenProvider,
|
|
1077
1180
|
onReloginSuccess
|
|
1078
1181
|
});
|
|
1182
|
+
const reloginHandler = () => {
|
|
1183
|
+
reloginUnreachable = false;
|
|
1184
|
+
return rawReloginHandler();
|
|
1185
|
+
};
|
|
1186
|
+
const reopenWorkspace = createWorkspaceReopener({
|
|
1187
|
+
crypto: cryptoProvider,
|
|
1188
|
+
sessionStorage,
|
|
1189
|
+
authState,
|
|
1190
|
+
getAccessToken: () => session.getState().accessToken,
|
|
1191
|
+
workspaceKeyRefreshProvider,
|
|
1192
|
+
workspaceOpenProvider
|
|
1193
|
+
});
|
|
1079
1194
|
const fetchClient = createFetchClient({
|
|
1080
1195
|
baseUrl,
|
|
1081
1196
|
credentials,
|
|
@@ -1085,7 +1200,11 @@ function createArbiClient(options) {
|
|
|
1085
1200
|
fetchClient.use(
|
|
1086
1201
|
createAutoReloginMiddleware({
|
|
1087
1202
|
reloginHandler,
|
|
1088
|
-
reloginExcludePatterns
|
|
1203
|
+
reloginExcludePatterns,
|
|
1204
|
+
reopenWorkspaceHandler: reopenWorkspace,
|
|
1205
|
+
onReloginFailed: () => {
|
|
1206
|
+
if (!reloginUnreachable && session.getState().userEmail) onSessionExpired?.();
|
|
1207
|
+
}
|
|
1089
1208
|
})
|
|
1090
1209
|
);
|
|
1091
1210
|
const authDeps = {
|
|
@@ -1102,7 +1221,8 @@ function createArbiClient(options) {
|
|
|
1102
1221
|
loginWithKey: (params) => loginWithKey(params, authDeps),
|
|
1103
1222
|
logout: () => logout(session),
|
|
1104
1223
|
changePassword: (params) => changePassword(params, authDeps),
|
|
1105
|
-
relogin: reloginHandler
|
|
1224
|
+
relogin: reloginHandler,
|
|
1225
|
+
reopenWorkspace
|
|
1106
1226
|
},
|
|
1107
1227
|
crypto: {
|
|
1108
1228
|
initSodium,
|
|
@@ -1156,6 +1276,6 @@ function isMessageType(msg, type) {
|
|
|
1156
1276
|
return msg.type === type;
|
|
1157
1277
|
}
|
|
1158
1278
|
|
|
1159
|
-
export { API_PREFIX, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, clearAllData, clearSession, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, parseServerMessage, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey };
|
|
1279
|
+
export { API_PREFIX, base64Decode, base64Encode, base64ToBytes, buildWebSocketUrl, bytesToBase64, clearAllData, clearSession, computeSharedSecret, createArbiClient, createAuthMessage, createAutoReloginMiddleware, createBearerAuthMiddleware, createContentHash, createReloginHandler, createSessionManager, createWorkspaceReopener, decryptFile, decryptMessage, decryptMessageWithSharedSecret, deriveEncryptionKeypairFromSigning, derivePublicKey, encryptFile, encryptMessage, encryptMessageWithSharedSecret, generateKeyPairs, generateLoginCredentials, generateLoginCredentialsFromKey, generatePasswordChangeCredentials, generateRandomSigningKeypair, generateRecoveryPasswordChangeCredentials, generateRegistrationCredentials, generateUserKeypairs, getSession, getUserEncryptionKeypair, hasSession, initSodium, initializeDatabase, isMessageType, parseServerMessage, prewarmKeyPairs, saveSession, sealKeyForSession, sealedBoxDecrypt, sealedBoxEncrypt, signMessage, updateSigningPrivateKey };
|
|
1160
1280
|
//# sourceMappingURL=index.js.map
|
|
1161
1281
|
//# sourceMappingURL=index.js.map
|