(fix): broken connections
This commit is contained in:
parent
5602b0a916
commit
0dff15cc28
5 changed files with 79 additions and 47 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6d97b5b9935b15d957444d38609378c66a24262a
|
Subproject commit 594646ac39d986f0787aa614a99d580035a67318
|
||||||
|
|
@ -144,7 +144,7 @@ export function Provider(props: {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
blockConnection?: boolean;
|
blockConnection?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const { load } = useStorage();
|
const { load, save } = useStorage();
|
||||||
|
|
||||||
const [readyState, setReadyState] = useState<number>(
|
const [readyState, setReadyState] = useState<number>(
|
||||||
ConnectionState.Disconnected,
|
ConnectionState.Disconnected,
|
||||||
|
|
@ -300,13 +300,19 @@ export function Provider(props: {
|
||||||
|
|
||||||
await MTPClient.init();
|
await MTPClient.init();
|
||||||
|
|
||||||
const [userId, keyring] = await Promise.all([
|
const [userId, keyring, storedSessionId] = await Promise.all([
|
||||||
load("user_id"),
|
load("user_id"),
|
||||||
load("mtp_keyring"),
|
load("mtp_keyring"),
|
||||||
|
load("session_id"),
|
||||||
]);
|
]);
|
||||||
if (!userId || !keyring) {
|
if (!userId || !keyring) {
|
||||||
throw new Error("Missing login credentials");
|
throw new Error("Missing login credentials");
|
||||||
}
|
}
|
||||||
|
let sessionId = storedSessionId;
|
||||||
|
if (!Number.isSafeInteger(sessionId) || sessionId <= 0) {
|
||||||
|
sessionId = Date.now();
|
||||||
|
await save("session_id", sessionId);
|
||||||
|
}
|
||||||
const forcedOmikronUrl = await load("forced_omikron_url");
|
const forcedOmikronUrl = await load("forced_omikron_url");
|
||||||
const forcedOmikronPublicKey = await load("forced_omikron_public_key");
|
const forcedOmikronPublicKey = await load("forced_omikron_public_key");
|
||||||
|
|
||||||
|
|
@ -404,27 +410,6 @@ export function Provider(props: {
|
||||||
clientRef.current = client;
|
clientRef.current = client;
|
||||||
setReadyState(client.state);
|
setReadyState(client.state);
|
||||||
|
|
||||||
const authPayload = new Promise<
|
|
||||||
ProtocolMessage<"IdentificationResponse">
|
|
||||||
>((resolve, reject) => {
|
|
||||||
const unsubscribe = client.subscribe(
|
|
||||||
"IdentificationResponse",
|
|
||||||
(message) => {
|
|
||||||
try {
|
|
||||||
unsubscribe();
|
|
||||||
if (message.type.startsWith("Error")) {
|
|
||||||
reject(new Error(`Authentication failed: ${message.type}`));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve(validateResponse("IdentificationResponse", message));
|
|
||||||
} catch (authPayloadError) {
|
|
||||||
unsubscribe();
|
|
||||||
reject(authPayloadError);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
clearReconnectTimer();
|
clearReconnectTimer();
|
||||||
|
|
||||||
// Schedule reconnect reset
|
// Schedule reconnect reset
|
||||||
|
|
@ -438,7 +423,31 @@ export function Provider(props: {
|
||||||
setIdentifying(true);
|
setIdentifying(true);
|
||||||
|
|
||||||
await client.auth();
|
await client.auth();
|
||||||
const finalResponse = await authPayload;
|
const finalResponse = validateResponse(
|
||||||
|
"ClientStateSync",
|
||||||
|
await client.request("ClientConnected", {
|
||||||
|
SessionId: sessionId,
|
||||||
|
VersionNumber: 0,
|
||||||
|
CacheValid: false,
|
||||||
|
CacheSchemaVersion: 0,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (finalResponse.type.startsWith("Error")) {
|
||||||
|
throw new Error(
|
||||||
|
`State synchronization failed: ${finalResponse.type}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const acknowledgement = await client.request("ClientStateAck", {
|
||||||
|
SessionId: sessionId,
|
||||||
|
VersionNumber: finalResponse.data.VersionNumber,
|
||||||
|
});
|
||||||
|
if (acknowledgement.type.startsWith("Error")) {
|
||||||
|
throw new Error(
|
||||||
|
`State acknowledgement failed: ${acknowledgement.type}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (disposed || clientRef.current !== client) return;
|
if (disposed || clientRef.current !== client) return;
|
||||||
|
|
||||||
|
|
@ -451,11 +460,15 @@ export function Provider(props: {
|
||||||
} catch (connectError) {
|
} catch (connectError) {
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
cleanup();
|
cleanup();
|
||||||
|
const connectErrorMessage =
|
||||||
|
connectError instanceof Error
|
||||||
|
? connectError.message
|
||||||
|
: String(connectError ?? "Unknown error");
|
||||||
log(
|
log(
|
||||||
0,
|
0,
|
||||||
"mtp",
|
"mtp",
|
||||||
"red",
|
"red",
|
||||||
"Connection/authentication attempt failed",
|
`Connection/authentication attempt failed: ${connectErrorMessage}`,
|
||||||
getProtocolErrorDetails(connectError) ?? connectError,
|
getProtocolErrorDetails(connectError) ?? connectError,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -465,10 +478,7 @@ export function Provider(props: {
|
||||||
log(0, "mtp", "red", "Reconnection attempts exhausted", connectError);
|
log(0, "mtp", "red", "Reconnection attempts exhausted", connectError);
|
||||||
sonnerToast.error("Connection failed", {
|
sonnerToast.error("Connection failed", {
|
||||||
id: "mtp-connection-toast",
|
id: "mtp-connection-toast",
|
||||||
description:
|
description: connectErrorMessage.split(":")[0],
|
||||||
connectError instanceof Error
|
|
||||||
? connectError.message.split(":")[0]
|
|
||||||
: String(connectError ?? "Unknown error"),
|
|
||||||
icon: null,
|
icon: null,
|
||||||
duration: Infinity,
|
duration: Infinity,
|
||||||
closeButton: true,
|
closeButton: true,
|
||||||
|
|
@ -531,7 +541,7 @@ export function Provider(props: {
|
||||||
setIdentifying(false);
|
setIdentifying(false);
|
||||||
sonnerToast.dismiss("mtp-connection-toast");
|
sonnerToast.dismiss("mtp-connection-toast");
|
||||||
};
|
};
|
||||||
}, [mtpUrl, props.blockConnection, load]);
|
}, [mtpUrl, props.blockConnection, load, save]);
|
||||||
|
|
||||||
// No Iota check
|
// No Iota check
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ const authPayload = z.object({
|
||||||
Contacts: z
|
Contacts: z
|
||||||
.array(
|
.array(
|
||||||
z.object({
|
z.object({
|
||||||
LastMessageAt: z.number(),
|
LastMessageAt: z.number().default(0),
|
||||||
UserId: z.number(),
|
UserId: z.number(),
|
||||||
LastMessage: z
|
LastMessage: z
|
||||||
.object({
|
.object({
|
||||||
|
|
@ -114,7 +114,7 @@ const authPayload = z.object({
|
||||||
SenderId: z.number(),
|
SenderId: z.number(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
Messages: z.array(Message),
|
Messages: z.array(Message).default([]),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.default([]),
|
.default([]),
|
||||||
|
|
@ -129,6 +129,16 @@ const authPayload = z.object({
|
||||||
.default([]),
|
.default([]),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const clientStateSync = authPayload.extend({
|
||||||
|
SessionId: z.number().int().positive(),
|
||||||
|
VersionNumber: z.number().int().nonnegative(),
|
||||||
|
CacheSchemaVersion: z.number().int().nonnegative(),
|
||||||
|
SyncMode: z.enum(["full", "delta"]),
|
||||||
|
Messages: z.array(Message).default([]),
|
||||||
|
DeletedMessageIds: z.array(z.number()).default([]),
|
||||||
|
DeletedContactIds: z.array(z.number()).default([]),
|
||||||
|
});
|
||||||
|
|
||||||
export type Contacts = z.infer<typeof authPayload.shape.Contacts>;
|
export type Contacts = z.infer<typeof authPayload.shape.Contacts>;
|
||||||
export type Communities = z.infer<typeof authPayload.shape.Communities>;
|
export type Communities = z.infer<typeof authPayload.shape.Communities>;
|
||||||
export type Calls = z.infer<typeof authPayload.shape.Calls>;
|
export type Calls = z.infer<typeof authPayload.shape.Calls>;
|
||||||
|
|
@ -184,6 +194,26 @@ export const mtp = {
|
||||||
request: z.object({}).optional(),
|
request: z.object({}).optional(),
|
||||||
response: authPayload,
|
response: authPayload,
|
||||||
},
|
},
|
||||||
|
ClientConnected: {
|
||||||
|
request: z.object({
|
||||||
|
SessionId: z.number().int().positive(),
|
||||||
|
VersionNumber: z.number().int().nonnegative(),
|
||||||
|
CacheValid: z.boolean(),
|
||||||
|
CacheSchemaVersion: z.number().int().nonnegative(),
|
||||||
|
}),
|
||||||
|
response: clientStateSync,
|
||||||
|
},
|
||||||
|
ClientStateSync: {
|
||||||
|
request: z.object({}).optional(),
|
||||||
|
response: clientStateSync,
|
||||||
|
},
|
||||||
|
ClientStateAck: {
|
||||||
|
request: z.object({
|
||||||
|
SessionId: z.number().int().positive(),
|
||||||
|
VersionNumber: z.number().int().nonnegative(),
|
||||||
|
}),
|
||||||
|
response: z.object({}),
|
||||||
|
},
|
||||||
GetUserData: {
|
GetUserData: {
|
||||||
request: z.object({
|
request: z.object({
|
||||||
UserId: z.number().optional(),
|
UserId: z.number().optional(),
|
||||||
|
|
|
||||||
18
pnpm-lock.yaml
generated
18
pnpm-lock.yaml
generated
|
|
@ -6,7 +6,7 @@ settings:
|
||||||
|
|
||||||
overrides:
|
overrides:
|
||||||
'@methanium/ui': https://git.methanium.net/methanium/ui/releases/download/0.0.8/methanium-ui.tgz
|
'@methanium/ui': https://git.methanium.net/methanium/ui/releases/download/0.0.8/methanium-ui.tgz
|
||||||
mtp: https://git.methanium.net/methanium/mtp/releases/download/0.2.0-3919eb46fd/mtp-0.2.0.tgz
|
mtp: link:../mtp
|
||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
||||||
|
|
@ -16,8 +16,8 @@ importers:
|
||||||
specifier: https://git.methanium.net/methanium/ui/releases/download/0.0.8/methanium-ui.tgz
|
specifier: https://git.methanium.net/methanium/ui/releases/download/0.0.8/methanium-ui.tgz
|
||||||
version: https://git.methanium.net/methanium/ui/releases/download/0.0.8/methanium-ui.tgz(@date-fns/tz@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(date-fns@4.4.0)(react-dom@19.2.7(react@19.2.7))(react-is@19.2.7)(react@19.2.7)(redux@5.0.1)(typescript@6.0.3)
|
version: https://git.methanium.net/methanium/ui/releases/download/0.0.8/methanium-ui.tgz(@date-fns/tz@1.5.0)(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(date-fns@4.4.0)(react-dom@19.2.7(react@19.2.7))(react-is@19.2.7)(react@19.2.7)(redux@5.0.1)(typescript@6.0.3)
|
||||||
mtp:
|
mtp:
|
||||||
specifier: https://git.methanium.net/methanium/mtp/releases/download/0.2.0-3919eb46fd/mtp-0.2.0.tgz
|
specifier: link:../mtp
|
||||||
version: https://git.methanium.net/methanium/mtp/releases/download/0.2.0-3919eb46fd/mtp-0.2.0.tgz
|
version: link:../mtp
|
||||||
sonner:
|
sonner:
|
||||||
specifier: ^2.0.7
|
specifier: ^2.0.7
|
||||||
version: 2.0.7(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
version: 2.0.7(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
|
||||||
|
|
@ -700,8 +700,8 @@ importers:
|
||||||
specifier: ^1.14.0
|
specifier: ^1.14.0
|
||||||
version: 1.23.0(react@19.2.7)
|
version: 1.23.0(react@19.2.7)
|
||||||
mtp:
|
mtp:
|
||||||
specifier: https://git.methanium.net/methanium/mtp/releases/download/0.2.0-3919eb46fd/mtp-0.2.0.tgz
|
specifier: link:../../../mtp
|
||||||
version: https://git.methanium.net/methanium/mtp/releases/download/0.2.0-3919eb46fd/mtp-0.2.0.tgz
|
version: link:../../../mtp
|
||||||
react:
|
react:
|
||||||
specifier: ^19.2.0
|
specifier: ^19.2.0
|
||||||
version: 19.2.7
|
version: 19.2.7
|
||||||
|
|
@ -4006,10 +4006,6 @@ packages:
|
||||||
ms@2.1.3:
|
ms@2.1.3:
|
||||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
mtp@https://git.methanium.net/methanium/mtp/releases/download/0.2.0-3919eb46fd/mtp-0.2.0.tgz:
|
|
||||||
resolution: {integrity: sha512-Adfwu1N48pSNZXaLpBW//uAeFaDCHYMOjWg+APG4TxEwCyQjXygCxBuEdUOjOxVZP9cK8L/K5Mf5HBO1+bd4HA==, tarball: https://git.methanium.net/methanium/mtp/releases/download/0.2.0-3919eb46fd/mtp-0.2.0.tgz}
|
|
||||||
version: 0.2.0
|
|
||||||
|
|
||||||
nanoid@3.3.15:
|
nanoid@3.3.15:
|
||||||
resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==}
|
resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
|
|
@ -8254,10 +8250,6 @@ snapshots:
|
||||||
|
|
||||||
ms@2.1.3: {}
|
ms@2.1.3: {}
|
||||||
|
|
||||||
mtp@https://git.methanium.net/methanium/mtp/releases/download/0.2.0-3919eb46fd/mtp-0.2.0.tgz:
|
|
||||||
dependencies:
|
|
||||||
yaml: 2.9.0
|
|
||||||
|
|
||||||
nanoid@3.3.15: {}
|
nanoid@3.3.15: {}
|
||||||
|
|
||||||
nanoid@3.3.16: {}
|
nanoid@3.3.16: {}
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,4 @@ allowBuilds:
|
||||||
esbuild: true
|
esbuild: true
|
||||||
overrides:
|
overrides:
|
||||||
"@methanium/ui": "https://git.methanium.net/methanium/ui/releases/download/0.0.8/methanium-ui.tgz"
|
"@methanium/ui": "https://git.methanium.net/methanium/ui/releases/download/0.0.8/methanium-ui.tgz"
|
||||||
mtp: "https://git.methanium.net/methanium/mtp/releases/download/0.2.0-3919eb46fd/mtp-0.2.0.tgz"
|
mtp: "link:../mtp"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue