@entropy-softworks/ui 2026.9.5 → 2026.9.6
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAutoLock.d.ts","sourceRoot":"","sources":["../../src/hooks/useAutoLock.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useAutoLock.d.ts","sourceRoot":"","sources":["../../src/hooks/useAutoLock.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,+DAA+D;IAC/D,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;;;;;;OAiBG;IACH,cAAc,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CAqJ1E"}
|
package/lib/hooks/useAutoLock.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef } from "react";
|
|
2
2
|
import { AppState as RNAppState, Platform } from "react-native";
|
|
3
3
|
const DEFAULT_IDLE_LOCK_MS = 10 * 60 * 1000;
|
|
4
|
+
/** How often the suspend detector below checks in. */
|
|
5
|
+
const HEARTBEAT_MS = 1000;
|
|
6
|
+
/** A gap this large between checks means the app was not running. */
|
|
7
|
+
const SUSPEND_GAP_MS = 4000;
|
|
4
8
|
/**
|
|
5
9
|
* Auto-lock a session after a period of inactivity. Generic over the
|
|
6
10
|
* lock predicate — vault wires `KeyManager.isUnlocked` / `KeyManager.lock`,
|
|
@@ -83,6 +87,34 @@ export function useAutoLock(options) {
|
|
|
83
87
|
armIdleTimer();
|
|
84
88
|
}
|
|
85
89
|
});
|
|
90
|
+
/**
|
|
91
|
+
* The backstop that does not involve AppState at all.
|
|
92
|
+
*
|
|
93
|
+
* AppState was the only way this hook knew the app had gone away, and on a
|
|
94
|
+
* real device it was reported not firing for either a minimise or a screen
|
|
95
|
+
* lock — the vault was still open on return, with the setting on. Rather
|
|
96
|
+
* than keep guessing which event a given platform version emits, this
|
|
97
|
+
* measures the thing that actually matters: a suspended app's timers stop.
|
|
98
|
+
*
|
|
99
|
+
* The interval ticks every second. If more than `SUSPEND_GAP_MS` of wall
|
|
100
|
+
* clock passed since the last tick, the app was not running, whatever the
|
|
101
|
+
* OS did or did not tell us — so lock.
|
|
102
|
+
*
|
|
103
|
+
* The threshold is well above any plausible stall on the JS thread, which
|
|
104
|
+
* is the one other thing that can delay an interval. Four seconds is far
|
|
105
|
+
* more than the heaviest work this app does in one go (opening a vault is
|
|
106
|
+
* milliseconds now that the crypto is native) and still short enough that
|
|
107
|
+
* putting a phone down and picking it up again lands on a locked vault.
|
|
108
|
+
*/
|
|
109
|
+
let lastTick = Date.now();
|
|
110
|
+
const heartbeat = setInterval(() => {
|
|
111
|
+
const now = Date.now();
|
|
112
|
+
const gap = now - lastTick;
|
|
113
|
+
lastTick = now;
|
|
114
|
+
if (Platform.OS !== "web" && gap > SUSPEND_GAP_MS) {
|
|
115
|
+
lockIfEnabled();
|
|
116
|
+
}
|
|
117
|
+
}, HEARTBEAT_MS);
|
|
86
118
|
const cleanups = [];
|
|
87
119
|
if (Platform.OS === "web" && typeof document !== "undefined") {
|
|
88
120
|
const onVisibility = () => {
|
|
@@ -101,6 +133,7 @@ export function useAutoLock(options) {
|
|
|
101
133
|
armIdleTimer();
|
|
102
134
|
return () => {
|
|
103
135
|
subscription.remove();
|
|
136
|
+
clearInterval(heartbeat);
|
|
104
137
|
for (const fn of cleanups) {
|
|
105
138
|
fn();
|
|
106
139
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAutoLock.js","sourceRoot":"","sources":["../../src/hooks/useAutoLock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEhE,MAAM,oBAAoB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"useAutoLock.js","sourceRoot":"","sources":["../../src/hooks/useAutoLock.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/hooks/useAutoLock.ts
CHANGED
|
@@ -3,6 +3,11 @@ import { AppState as RNAppState, Platform } from "react-native";
|
|
|
3
3
|
|
|
4
4
|
const DEFAULT_IDLE_LOCK_MS = 10 * 60 * 1000;
|
|
5
5
|
|
|
6
|
+
/** How often the suspend detector below checks in. */
|
|
7
|
+
const HEARTBEAT_MS = 1000;
|
|
8
|
+
/** A gap this large between checks means the app was not running. */
|
|
9
|
+
const SUSPEND_GAP_MS = 4000;
|
|
10
|
+
|
|
6
11
|
export interface UseAutoLockOptions {
|
|
7
12
|
/**
|
|
8
13
|
* Reports whether the session is currently "unlocked" (vault-style
|
|
@@ -128,6 +133,35 @@ export function useAutoLock(options: UseAutoLockOptions): UseAutoLockResult {
|
|
|
128
133
|
}
|
|
129
134
|
});
|
|
130
135
|
|
|
136
|
+
/**
|
|
137
|
+
* The backstop that does not involve AppState at all.
|
|
138
|
+
*
|
|
139
|
+
* AppState was the only way this hook knew the app had gone away, and on a
|
|
140
|
+
* real device it was reported not firing for either a minimise or a screen
|
|
141
|
+
* lock — the vault was still open on return, with the setting on. Rather
|
|
142
|
+
* than keep guessing which event a given platform version emits, this
|
|
143
|
+
* measures the thing that actually matters: a suspended app's timers stop.
|
|
144
|
+
*
|
|
145
|
+
* The interval ticks every second. If more than `SUSPEND_GAP_MS` of wall
|
|
146
|
+
* clock passed since the last tick, the app was not running, whatever the
|
|
147
|
+
* OS did or did not tell us — so lock.
|
|
148
|
+
*
|
|
149
|
+
* The threshold is well above any plausible stall on the JS thread, which
|
|
150
|
+
* is the one other thing that can delay an interval. Four seconds is far
|
|
151
|
+
* more than the heaviest work this app does in one go (opening a vault is
|
|
152
|
+
* milliseconds now that the crypto is native) and still short enough that
|
|
153
|
+
* putting a phone down and picking it up again lands on a locked vault.
|
|
154
|
+
*/
|
|
155
|
+
let lastTick = Date.now();
|
|
156
|
+
const heartbeat = setInterval(() => {
|
|
157
|
+
const now = Date.now();
|
|
158
|
+
const gap = now - lastTick;
|
|
159
|
+
lastTick = now;
|
|
160
|
+
if (Platform.OS !== "web" && gap > SUSPEND_GAP_MS) {
|
|
161
|
+
lockIfEnabled();
|
|
162
|
+
}
|
|
163
|
+
}, HEARTBEAT_MS);
|
|
164
|
+
|
|
131
165
|
const cleanups: (() => void)[] = [];
|
|
132
166
|
|
|
133
167
|
if (Platform.OS === "web" && typeof document !== "undefined") {
|
|
@@ -150,6 +184,7 @@ export function useAutoLock(options: UseAutoLockOptions): UseAutoLockResult {
|
|
|
150
184
|
|
|
151
185
|
return () => {
|
|
152
186
|
subscription.remove();
|
|
187
|
+
clearInterval(heartbeat);
|
|
153
188
|
for (const fn of cleanups) {
|
|
154
189
|
fn();
|
|
155
190
|
}
|