querysub 0.692.0 → 0.694.0
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/package.json
CHANGED
|
@@ -27,6 +27,8 @@ const LATENCY_SAMPLE_LIMIT = 20;
|
|
|
27
27
|
const LATENCY_HISTORY_LIMIT = 100;
|
|
28
28
|
// Forget nodes we haven't been able to reach for this long.
|
|
29
29
|
const NODE_EXPIRY_TIME = LATENCY_POLL_INTERVAL * 5;
|
|
30
|
+
// Each of the first pings to a node replaces the history instead of adding to it, so only the last of them survives into the real history.
|
|
31
|
+
const LATENCY_WARMUP_PINGS = 3;
|
|
30
32
|
|
|
31
33
|
export type NodeLatencyInfo = {
|
|
32
34
|
averageLatency: number;
|
|
@@ -70,15 +72,19 @@ export function getOwnLatencies(): { [nodeId: string]: number } {
|
|
|
70
72
|
|
|
71
73
|
function recordLatency(nodeId: string, latency: number) {
|
|
72
74
|
let prev = latencyByNode.get(nodeId);
|
|
73
|
-
let
|
|
75
|
+
let pingCount = prev?.sampleCount || 0;
|
|
74
76
|
let history = prev?.history || [];
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
if (pingCount < LATENCY_WARMUP_PINGS) {
|
|
78
|
+
history = [latency];
|
|
79
|
+
} else {
|
|
80
|
+
history.push(latency);
|
|
81
|
+
if (history.length > LATENCY_HISTORY_LIMIT) {
|
|
82
|
+
history.shift();
|
|
83
|
+
}
|
|
78
84
|
}
|
|
79
85
|
latencyByNode.set(nodeId, {
|
|
80
|
-
averageLatency: ((
|
|
81
|
-
sampleCount:
|
|
86
|
+
averageLatency: history.reduce((sum, x) => sum + x, 0) / history.length,
|
|
87
|
+
sampleCount: pingCount + 1,
|
|
82
88
|
lastSeen: Date.now(),
|
|
83
89
|
history,
|
|
84
90
|
});
|
|
@@ -1075,6 +1075,11 @@ export class Querysub {
|
|
|
1075
1075
|
if (isClient()) {
|
|
1076
1076
|
throw new Error(`--client processes cannot host a service. Either stop passing --client and keep the process on the network and trusted, or stop calling hostServer and call Querysub.configRootDiscoveryLocation instead. You MUST provide configRootDiscoveryLocation a valid nodeId. Which means either you do server selection manually, or if you are developing, just point it to "127-0-0-1.${getDomain()}:your local port here"`);
|
|
1077
1077
|
}
|
|
1078
|
+
// Hot reloading on public servers breaks things when we update (as the git pull triggers a hot reload), so... don't do that.
|
|
1079
|
+
if (!isPublic() || yargObj.hot) {
|
|
1080
|
+
watchFilesAndTriggerHotReloading();
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1078
1083
|
await getIdentityCAPromise(getDomain());
|
|
1079
1084
|
let times: {
|
|
1080
1085
|
name: string;
|
|
@@ -30,6 +30,11 @@ export type InputLabelProps = Omit<InputProps, "label" | "title"> & {
|
|
|
30
30
|
fillWidth?: boolean | number;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
// A checkbox is a small square that reads as belonging to the words beside it, so it sits tight against
|
|
34
|
+
// its label; every other input is a box of its own and wants room between the two.
|
|
35
|
+
const LABEL_GAP = 8;
|
|
36
|
+
const CHECKBOX_LABEL_GAP = 2;
|
|
37
|
+
|
|
33
38
|
function roundToDecimals(value: number, decimals: number) {
|
|
34
39
|
return Math.round(value * 10 ** decimals) / 10 ** decimals;
|
|
35
40
|
}
|
|
@@ -148,7 +153,7 @@ export class InputLabel extends qreact.Component<InputLabelProps> {
|
|
|
148
153
|
}
|
|
149
154
|
return (
|
|
150
155
|
<label onClick={onClick} class={
|
|
151
|
-
css.hbox(
|
|
156
|
+
css.hbox(props.checkbox ? CHECKBOX_LABEL_GAP : LABEL_GAP).button.relative
|
|
152
157
|
+ " trigger-hover "
|
|
153
158
|
+ props.outerClass
|
|
154
159
|
+ (props.flavor === "large" && css.fontSize(18, "soft"))
|
|
@@ -6,7 +6,7 @@ import { isNode, sha256Hash, timeInHour } from "socket-function/src/misc";
|
|
|
6
6
|
import { registerAliveChecker } from "../2-proxy/garbageCollection";
|
|
7
7
|
import { generateLoginEmail } from "./loginEmail";
|
|
8
8
|
import { logErrors } from "../errors";
|
|
9
|
-
import { PermissionsParameters } from "../3-path-functions/syncSchema";
|
|
9
|
+
import { PermissionsCallback, PermissionsParameters } from "../3-path-functions/syncSchema";
|
|
10
10
|
import { sendEmail_postmark } from "../email_ims_notifications/postmark";
|
|
11
11
|
import { isClient } from "../config2";
|
|
12
12
|
import { getExternalIP } from "../misc/networking";
|
|
@@ -457,6 +457,17 @@ export function satisifiedUserType(currentType: UserType, minimumType: UserType)
|
|
|
457
457
|
return currentType === minimumType || userTypeRanking[currentType] > userTypeRanking[minimumType];
|
|
458
458
|
}
|
|
459
459
|
|
|
460
|
+
export function createWildcardUserPERMISSIONS(config: { wildcardIndex: number; allowSuperUser?: boolean; }): PermissionsCallback {
|
|
461
|
+
let check: PermissionsCallback = permissionsConfig => {
|
|
462
|
+
if (config.allowSuperUser && isSuperUserPERMISSIONS()) return true;
|
|
463
|
+
let userId = getUserIdAllowUndefined();
|
|
464
|
+
if (!userId) return false;
|
|
465
|
+
return permissionsConfig.pathWildcards[config.wildcardIndex] === userId;
|
|
466
|
+
};
|
|
467
|
+
check.callImmutable = true;
|
|
468
|
+
return check;
|
|
469
|
+
}
|
|
470
|
+
|
|
460
471
|
export function createUserPERMISSIONS(userType: UserType) {
|
|
461
472
|
return () => {
|
|
462
473
|
let allowed = isCurrentUserType(userType);
|