react-native-dev-guard 1.0.0 → 1.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/LICENSE +1 -1
- package/README.md +6 -6
- package/android/src/main/cpp/devguard-lib.cpp +12 -11
- package/android/src/main/java/com/devguard/DevGuardModule.kt +15 -0
- package/cpp/devguard_core.c +82 -4
- package/cpp/devguard_core.h +15 -13
- package/ios/DevGuard.mm +20 -6
- package/lib/components/LockScreen.d.ts +2 -0
- package/lib/components/LockScreen.js +90 -44
- package/lib/index.d.ts +4 -1
- package/lib/index.js +166 -148
- package/lib/internal/obf.d.ts +72 -0
- package/lib/internal/obf.js +100 -0
- package/lib/services/CacheService.js +3 -11
- package/lib/services/GuardEnforcement.d.ts +3 -12
- package/lib/services/GuardEnforcement.js +34 -15
- package/lib/services/cacheCrypto.d.ts +6 -0
- package/lib/services/cacheCrypto.js +40 -0
- package/lib/types/branding.d.ts +21 -0
- package/lib/types/branding.js +30 -0
- package/lib/utils/contactUrls.d.ts +4 -0
- package/lib/utils/contactUrls.js +18 -0
- package/package.json +9 -3
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.useDevGuard = exports.DevGuardProvider = void 0;
|
|
6
|
+
exports.resolveBrandingFooter = exports.useDevGuard = exports.DevGuardProvider = void 0;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
8
|
const react_1 = require("react");
|
|
9
9
|
const react_native_1 = require("react-native");
|
|
@@ -21,10 +21,10 @@ const DiagnosticOverlay_1 = require("./components/DiagnosticOverlay");
|
|
|
21
21
|
const DevGuardLogger_1 = require("./services/DevGuardLogger");
|
|
22
22
|
const GuardEnforcement_1 = require("./services/GuardEnforcement");
|
|
23
23
|
const RemoteWipeService_1 = require("./services/RemoteWipeService");
|
|
24
|
+
const obf_1 = require("./internal/obf");
|
|
24
25
|
const react_native_2 = require("react-native");
|
|
25
26
|
const react_native_safe_area_context_1 = require("react-native-safe-area-context");
|
|
26
27
|
const { DevGuard: DevGuardNative } = react_native_1.NativeModules;
|
|
27
|
-
const API_URL = 'https://api.devguard.uk/devguard';
|
|
28
28
|
const DevGuardContext = (0, react_1.createContext)(undefined);
|
|
29
29
|
const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = true, failSafe = 'open' }) => {
|
|
30
30
|
const authSecret = secret ?? apiKey;
|
|
@@ -35,6 +35,7 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
35
35
|
const heartbeatTimer = (0, react_1.useRef)(null);
|
|
36
36
|
const lastSyncTime = (0, react_1.useRef)(0);
|
|
37
37
|
const [showDiagnostics, setShowDiagnostics] = (0, react_1.useState)(false);
|
|
38
|
+
const isCompromisedRef = (0, react_1.useRef)(false);
|
|
38
39
|
const lastLifecycleSyncTime = (0, react_1.useRef)(0);
|
|
39
40
|
// Mirror of `response` for use inside long-lived closures (AppState listener,
|
|
40
41
|
// heartbeat). Those callbacks are registered once, so reading the `response`
|
|
@@ -42,6 +43,7 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
42
43
|
// telemetry consent and lifecycle gating. The ref always holds the latest.
|
|
43
44
|
// (Parity with Flutter, where these reads hit the `_cachedResponse` field.)
|
|
44
45
|
const responseRef = (0, react_1.useRef)(null);
|
|
46
|
+
const verifyChainRef = (0, react_1.useRef)(Promise.resolve());
|
|
45
47
|
(0, react_1.useEffect)(() => {
|
|
46
48
|
responseRef.current = response;
|
|
47
49
|
}, [response]);
|
|
@@ -94,144 +96,154 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
94
96
|
return true;
|
|
95
97
|
};
|
|
96
98
|
const verify = async (force = false, trigger) => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
try {
|
|
102
|
-
const hardware = HardwareService_1.HardwareService.getInstance();
|
|
103
|
-
const deviceId = await hardware.getDeviceId();
|
|
104
|
-
// Use the ref (not the possibly-stale closed-over `response`) so advanced
|
|
105
|
-
// telemetry consent is honored on heartbeat/lifecycle-triggered syncs.
|
|
106
|
-
const metadata = await hardware.getMetadata(responseRef.current?.betaFeatures);
|
|
107
|
-
const timestamp = Date.now().toString();
|
|
108
|
-
// Align payload with Flutter: Metadata map is the core payload 'p'
|
|
109
|
-
const payload = JSON.stringify({
|
|
110
|
-
...metadata,
|
|
111
|
-
projectId,
|
|
112
|
-
timestamp: parseInt(timestamp, 10)
|
|
113
|
-
});
|
|
114
|
-
// GZip + Base64 Tunneling (v1-gzip)
|
|
115
|
-
const compressed = pako_1.default.gzip(payload);
|
|
116
|
-
const uint8ToBase64 = (data) => {
|
|
117
|
-
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
118
|
-
let result = '';
|
|
119
|
-
let i;
|
|
120
|
-
const l = data.length;
|
|
121
|
-
for (i = 2; i < l; i += 3) {
|
|
122
|
-
result += chars[data[i - 2] >> 2];
|
|
123
|
-
result += chars[((data[i - 2] & 0x03) << 4) | (data[i - 1] >> 4)];
|
|
124
|
-
result += chars[((data[i - 1] & 0x0f) << 2) | (data[i] >> 6)];
|
|
125
|
-
result += chars[data[i] & 0x3f];
|
|
126
|
-
}
|
|
127
|
-
if (i === l + 1) {
|
|
128
|
-
result += chars[data[i - 2] >> 2];
|
|
129
|
-
result += chars[(data[i - 2] & 0x03) << 4];
|
|
130
|
-
result += '==';
|
|
131
|
-
}
|
|
132
|
-
else if (i === l) {
|
|
133
|
-
result += chars[data[i - 2] >> 2];
|
|
134
|
-
result += chars[((data[i - 2] & 0x03) << 4) | (data[i - 1] >> 4)];
|
|
135
|
-
result += chars[(data[i - 1] & 0x0f) << 2];
|
|
136
|
-
result += '=';
|
|
137
|
-
}
|
|
138
|
-
return result;
|
|
139
|
-
};
|
|
140
|
-
const base64Payload = uint8ToBase64(compressed);
|
|
141
|
-
const signature = await DevGuardNative.generateSignature(projectId, parseInt(timestamp, 10));
|
|
142
|
-
const fetchUrl = API_URL;
|
|
143
|
-
const fetchOptions = {
|
|
144
|
-
method: 'POST',
|
|
145
|
-
headers: {
|
|
146
|
-
'Content-Type': 'application/json',
|
|
147
|
-
'X-DevGuard-Signature': signature,
|
|
148
|
-
'X-DevGuard-Timestamp': timestamp,
|
|
149
|
-
'X-DevGuard-Tunnel': 'v1-gzip',
|
|
150
|
-
...(authSecret ? { 'X-DevGuard-API-Key': authSecret } : {})
|
|
151
|
-
},
|
|
152
|
-
body: JSON.stringify({
|
|
153
|
-
projectId,
|
|
154
|
-
deviceId: metadata.deviceId,
|
|
155
|
-
deviceName: metadata.deviceName,
|
|
156
|
-
model: metadata.model,
|
|
157
|
-
os: metadata.os,
|
|
158
|
-
version: metadata.version,
|
|
159
|
-
isPhysicalDevice: metadata.isPhysicalDevice,
|
|
160
|
-
username: metadata.username,
|
|
161
|
-
email: metadata.email,
|
|
162
|
-
phone: metadata.phone,
|
|
163
|
-
customData: metadata.customData,
|
|
164
|
-
fingerprint: metadata.fingerprint,
|
|
165
|
-
deviceToken: metadata.deviceToken,
|
|
166
|
-
location: metadata.location,
|
|
167
|
-
p: base64Payload
|
|
168
|
-
})
|
|
169
|
-
};
|
|
170
|
-
const fetchResponse = await fetch(fetchUrl, fetchOptions);
|
|
171
|
-
if (!fetchResponse.ok) {
|
|
172
|
-
throw new Error('API_UNREACHABLE');
|
|
99
|
+
const run = async () => {
|
|
100
|
+
if (!shouldSync(force, trigger)) {
|
|
101
|
+
console.log(obf_1.Obf.syncSkipped);
|
|
102
|
+
return;
|
|
173
103
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
104
|
+
try {
|
|
105
|
+
const hardware = HardwareService_1.HardwareService.getInstance();
|
|
106
|
+
const deviceId = await hardware.getDeviceId();
|
|
107
|
+
// Use the ref (not the possibly-stale closed-over `response`) so advanced
|
|
108
|
+
// telemetry consent is honored on heartbeat/lifecycle-triggered syncs.
|
|
109
|
+
const metadata = await hardware.getMetadata(responseRef.current?.betaFeatures);
|
|
110
|
+
const timestamp = Date.now().toString();
|
|
111
|
+
// Align payload with Flutter: Metadata map is the core payload 'p'
|
|
112
|
+
const payload = JSON.stringify({
|
|
113
|
+
...metadata,
|
|
114
|
+
[obf_1.Obf.projectId]: projectId,
|
|
115
|
+
timestamp: parseInt(timestamp, 10)
|
|
116
|
+
});
|
|
117
|
+
// GZip + Base64 Tunneling (v1-gzip)
|
|
118
|
+
const compressed = pako_1.default.gzip(payload);
|
|
119
|
+
const uint8ToBase64 = (data) => {
|
|
120
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
121
|
+
let result = '';
|
|
122
|
+
let i;
|
|
123
|
+
const l = data.length;
|
|
124
|
+
for (i = 2; i < l; i += 3) {
|
|
125
|
+
result += chars[data[i - 2] >> 2];
|
|
126
|
+
result += chars[((data[i - 2] & 0x03) << 4) | (data[i - 1] >> 4)];
|
|
127
|
+
result += chars[((data[i - 1] & 0x0f) << 2) | (data[i] >> 6)];
|
|
128
|
+
result += chars[data[i] & 0x3f];
|
|
129
|
+
}
|
|
130
|
+
if (i === l + 1) {
|
|
131
|
+
result += chars[data[i - 2] >> 2];
|
|
132
|
+
result += chars[(data[i - 2] & 0x03) << 4];
|
|
133
|
+
result += '==';
|
|
183
134
|
}
|
|
184
|
-
else {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
135
|
+
else if (i === l) {
|
|
136
|
+
result += chars[data[i - 2] >> 2];
|
|
137
|
+
result += chars[((data[i - 2] & 0x03) << 4) | (data[i - 1] >> 4)];
|
|
138
|
+
result += chars[(data[i - 1] & 0x0f) << 2];
|
|
139
|
+
result += '=';
|
|
188
140
|
}
|
|
141
|
+
return result;
|
|
142
|
+
};
|
|
143
|
+
const base64Payload = uint8ToBase64(compressed);
|
|
144
|
+
const signature = await DevGuardNative.generateSignature(projectId, parseInt(timestamp, 10));
|
|
145
|
+
const fetchUrl = obf_1.Obf.defaultApiUrl;
|
|
146
|
+
const fetchOptions = {
|
|
147
|
+
method: 'POST',
|
|
148
|
+
headers: {
|
|
149
|
+
[obf_1.Obf.contentType]: obf_1.Obf.appJson,
|
|
150
|
+
[obf_1.Obf.hdrSig]: signature,
|
|
151
|
+
[obf_1.Obf.hdrTs]: timestamp,
|
|
152
|
+
[obf_1.Obf.hdrTunnel]: obf_1.Obf.tunnelV1,
|
|
153
|
+
...(authSecret ? { [obf_1.Obf.hdrApiKey]: authSecret } : {})
|
|
154
|
+
},
|
|
155
|
+
body: JSON.stringify({
|
|
156
|
+
[obf_1.Obf.projectId]: projectId,
|
|
157
|
+
[obf_1.Obf.deviceId]: metadata.deviceId,
|
|
158
|
+
[obf_1.Obf.deviceName]: metadata.deviceName,
|
|
159
|
+
[obf_1.Obf.model]: metadata.model,
|
|
160
|
+
[obf_1.Obf.os]: metadata.os,
|
|
161
|
+
[obf_1.Obf.version]: metadata.version,
|
|
162
|
+
[obf_1.Obf.isPhysicalDevice]: metadata.isPhysicalDevice,
|
|
163
|
+
[obf_1.Obf.username]: metadata.username,
|
|
164
|
+
[obf_1.Obf.email]: metadata.email,
|
|
165
|
+
[obf_1.Obf.phone]: metadata.phone,
|
|
166
|
+
[obf_1.Obf.customData]: metadata.customData,
|
|
167
|
+
[obf_1.Obf.fingerprint]: metadata.fingerprint,
|
|
168
|
+
[obf_1.Obf.deviceToken]: metadata.deviceToken,
|
|
169
|
+
[obf_1.Obf.location]: metadata.location,
|
|
170
|
+
[obf_1.Obf.payloadField]: base64Payload
|
|
171
|
+
})
|
|
172
|
+
};
|
|
173
|
+
const fetchResponse = await fetch(fetchUrl, fetchOptions);
|
|
174
|
+
if (!fetchResponse.ok) {
|
|
175
|
+
throw new Error(obf_1.Obf.apiUnreachable);
|
|
176
|
+
}
|
|
177
|
+
const responseText = await fetchResponse.text();
|
|
178
|
+
const result = JSON.parse(responseText);
|
|
179
|
+
// Verify Response Signature
|
|
180
|
+
const responseSig = fetchResponse.headers.get(obf_1.Obf.respSig);
|
|
181
|
+
if (responseSig) {
|
|
182
|
+
const isValid = await DevGuardNative.verifyResponse(responseText, responseSig);
|
|
183
|
+
if (!isValid) {
|
|
184
|
+
if (result[obf_1.Obf.betaFeatures]?.[obf_1.Obf.bypassSignature] === true) {
|
|
185
|
+
console.warn(obf_1.Obf.invalidSigBypassLog);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
console.error(obf_1.Obf.invalidSigLog);
|
|
189
|
+
const enforced = await GuardEnforcement_1.GuardEnforcement.apply({ ...result, status: 'LOCKED' }, metadata, isCompromisedRef.current);
|
|
190
|
+
responseRef.current = enforced;
|
|
191
|
+
setResponse(enforced);
|
|
192
|
+
setStatus('LOCKED');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
console.warn(obf_1.Obf.missingSigLog);
|
|
199
|
+
}
|
|
200
|
+
// Client-side enforcement (emulator / compromised) — parity with Flutter.
|
|
201
|
+
const enforced = await GuardEnforcement_1.GuardEnforcement.apply(result, metadata, isCompromisedRef.current);
|
|
202
|
+
const finalStatus = String(enforced[obf_1.Obf.statusField] || 'ERROR').toUpperCase();
|
|
203
|
+
responseRef.current = enforced; // keep ref fresh for chained/triggered syncs
|
|
204
|
+
setResponse(enforced);
|
|
205
|
+
setStatus(finalStatus);
|
|
206
|
+
setShowWarning(finalStatus === 'WARNING');
|
|
207
|
+
lastSyncTime.current = Date.now();
|
|
208
|
+
CacheService_1.CacheService.saveResponse(projectId, enforced);
|
|
209
|
+
// Handle Beta Features (Parity with Flutter)
|
|
210
|
+
if (finalStatus === 'WARNING' && result.betaFeatures?.vibrateOnWarning === true) {
|
|
211
|
+
react_native_1.Vibration.vibrate();
|
|
212
|
+
}
|
|
213
|
+
const wipeNonce = result.betaFeatures?.wipeNonce;
|
|
214
|
+
if (typeof wipeNonce === 'number' && wipeNonce > 0) {
|
|
215
|
+
await executeRemoteWipe(wipeNonce);
|
|
216
|
+
}
|
|
217
|
+
// Heartbeat management
|
|
218
|
+
startHeartbeat(result);
|
|
219
|
+
// Handle Device Token (Parity with Flutter)
|
|
220
|
+
if (result.deviceToken) {
|
|
221
|
+
await DeviceTokenService_1.DeviceTokenService.getInstance().saveToken(result.deviceToken, result.betaFeatures?.secureEnclave === true);
|
|
222
|
+
}
|
|
223
|
+
// Handle Remote Commands (Parity with Flutter)
|
|
224
|
+
if (result.remoteCommand && result.remoteCommand !== 'none') {
|
|
225
|
+
await handleRemoteCommand(result.remoteCommand);
|
|
226
|
+
}
|
|
227
|
+
// Clear logs after successful sync
|
|
228
|
+
if (metadata.usageLogs && metadata.usageLogs.length > 0) {
|
|
229
|
+
await UsageLogger_1.UsageLogger.getInstance().clearLogs();
|
|
189
230
|
}
|
|
190
231
|
}
|
|
191
|
-
|
|
192
|
-
console.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
setStatus(finalStatus);
|
|
200
|
-
setShowWarning(finalStatus === 'WARNING');
|
|
201
|
-
lastSyncTime.current = Date.now();
|
|
202
|
-
CacheService_1.CacheService.saveResponse(projectId, enforced);
|
|
203
|
-
// Handle Beta Features (Parity with Flutter)
|
|
204
|
-
if (finalStatus === 'WARNING' && result.betaFeatures?.vibrateOnWarning === true) {
|
|
205
|
-
react_native_1.Vibration.vibrate();
|
|
206
|
-
}
|
|
207
|
-
const wipeNonce = result.betaFeatures?.wipeNonce;
|
|
208
|
-
if (typeof wipeNonce === 'number' && wipeNonce > 0) {
|
|
209
|
-
await executeRemoteWipe(wipeNonce);
|
|
210
|
-
}
|
|
211
|
-
// Heartbeat management
|
|
212
|
-
startHeartbeat(result);
|
|
213
|
-
// Handle Device Token (Parity with Flutter)
|
|
214
|
-
if (result.deviceToken) {
|
|
215
|
-
await DeviceTokenService_1.DeviceTokenService.getInstance().saveToken(result.deviceToken, result.betaFeatures?.secureEnclave === true);
|
|
216
|
-
}
|
|
217
|
-
// Handle Remote Commands (Parity with Flutter)
|
|
218
|
-
if (result.remoteCommand && result.remoteCommand !== 'none') {
|
|
219
|
-
await handleRemoteCommand(result.remoteCommand);
|
|
220
|
-
}
|
|
221
|
-
// Clear logs after successful sync
|
|
222
|
-
if (metadata.usageLogs && metadata.usageLogs.length > 0) {
|
|
223
|
-
await UsageLogger_1.UsageLogger.getInstance().clearLogs();
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
catch (e) {
|
|
227
|
-
console.error('DevGuard Verification Failed:', e);
|
|
228
|
-
if (failSafe === 'open' && status === 'PENDING') {
|
|
229
|
-
setStatus('ACTIVE');
|
|
230
|
-
}
|
|
231
|
-
else if (failSafe === 'closed') {
|
|
232
|
-
setStatus('LOCKED');
|
|
232
|
+
catch (e) {
|
|
233
|
+
console.error('DevGuard Verification Failed:', e);
|
|
234
|
+
if (failSafe === 'open' && status === 'PENDING') {
|
|
235
|
+
setStatus('ACTIVE');
|
|
236
|
+
}
|
|
237
|
+
else if (failSafe === 'closed') {
|
|
238
|
+
setStatus('LOCKED');
|
|
239
|
+
}
|
|
233
240
|
}
|
|
234
|
-
}
|
|
241
|
+
};
|
|
242
|
+
// Always serialize verify runs — never reset the chain on force, or parallel
|
|
243
|
+
// fetches race and a stale WARNING response can overwrite LOCKED (physical E2E).
|
|
244
|
+
const chained = verifyChainRef.current.then(() => run()).catch(() => { });
|
|
245
|
+
verifyChainRef.current = chained;
|
|
246
|
+
return chained;
|
|
235
247
|
};
|
|
236
248
|
const startHeartbeat = (res) => {
|
|
237
249
|
if (heartbeatTimer.current)
|
|
@@ -287,20 +299,20 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
287
299
|
const hashedKey = crypto_js_1.default.SHA256(key).toString();
|
|
288
300
|
const timestamp = Date.now().toString();
|
|
289
301
|
const signature = await DevGuardNative.generateSignature(projectId, parseInt(timestamp, 10));
|
|
290
|
-
const payload = JSON.stringify({ projectId, providedKey: hashedKey });
|
|
291
|
-
const fetchResponse = await fetch(`${
|
|
302
|
+
const payload = JSON.stringify({ [obf_1.Obf.projectId]: projectId, [obf_1.Obf.providedKey]: hashedKey });
|
|
303
|
+
const fetchResponse = await fetch(`${obf_1.Obf.defaultApiUrl}${obf_1.Obf.unlockPath}`, {
|
|
292
304
|
method: 'POST',
|
|
293
305
|
headers: {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
...(authSecret ? {
|
|
306
|
+
[obf_1.Obf.contentType]: obf_1.Obf.appJson,
|
|
307
|
+
[obf_1.Obf.hdrSig]: signature,
|
|
308
|
+
[obf_1.Obf.hdrTs]: timestamp,
|
|
309
|
+
...(authSecret ? { [obf_1.Obf.hdrApiKey]: authSecret } : {})
|
|
298
310
|
},
|
|
299
311
|
body: payload
|
|
300
312
|
});
|
|
301
313
|
if (fetchResponse.ok) {
|
|
302
314
|
const text = await fetchResponse.text();
|
|
303
|
-
if (text ===
|
|
315
|
+
if (text === obf_1.Obf.unlocked) {
|
|
304
316
|
await verify();
|
|
305
317
|
return true;
|
|
306
318
|
}
|
|
@@ -332,13 +344,10 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
332
344
|
const deviceId = await HardwareService_1.HardwareService.getInstance().getDeviceId();
|
|
333
345
|
await DevGuardLogger_1.DevGuardLogger.init(deviceId);
|
|
334
346
|
const isJailbroken = await react_native_jailbreak_1.default.check();
|
|
347
|
+
isCompromisedRef.current = isJailbroken;
|
|
335
348
|
if (isJailbroken) {
|
|
336
|
-
|
|
337
|
-
setResponse(
|
|
338
|
-
status: 'LOCKED',
|
|
339
|
-
title: 'Security Alert',
|
|
340
|
-
message: 'This application cannot run on jailbroken or rooted devices for security reasons.',
|
|
341
|
-
});
|
|
349
|
+
const locked = await GuardEnforcement_1.GuardEnforcement.apply({ status: 'ACTIVE' }, { isPhysicalDevice: true }, true);
|
|
350
|
+
setResponse(locked);
|
|
342
351
|
setStatus('LOCKED');
|
|
343
352
|
return;
|
|
344
353
|
}
|
|
@@ -384,7 +393,7 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
384
393
|
}, []);
|
|
385
394
|
const isLocked = status === 'LOCKED' || status === 'EXPIRED';
|
|
386
395
|
const showBugIcon = response?.betaFeatures?.showDiagnosticLogs === true;
|
|
387
|
-
return ((0, jsx_runtime_1.jsxs)(DevGuardContext.Provider, { value: { status, verify, unlock, setDeviceUser, isLocked, response }, children: [showWarning && status === 'WARNING' && ((0, jsx_runtime_1.jsx)(SecurityToast_1.SecurityToast, { title: response?.title || 'Security Warning', message: response?.message })), autoProtect && isLocked ? ((0, jsx_runtime_1.jsx)(LockScreen_1.LockScreen, { status: status, title: response?.title, message: response?.message, contactEmail: response?.contactEmail, contactPhone: response?.contactPhone, contactWhatsapp: response?.contactWhatsapp, allowUnlock: response?.allowUnlock, onUnlock: unlock })) : ((0, jsx_runtime_1.jsxs)(react_native_2.View, { style: { flex: 1 }, children: [children, showBugIcon && ((0, jsx_runtime_1.jsx)(react_native_safe_area_context_1.SafeAreaInsetsContext.Consumer, { children: (insets) => {
|
|
396
|
+
return ((0, jsx_runtime_1.jsxs)(DevGuardContext.Provider, { value: { status, verify, unlock, setDeviceUser, isLocked, response }, children: [showWarning && status === 'WARNING' && ((0, jsx_runtime_1.jsx)(SecurityToast_1.SecurityToast, { title: response?.title || 'Security Warning', message: response?.message })), autoProtect && isLocked ? ((0, jsx_runtime_1.jsxs)(react_native_2.View, { style: { flex: 1 }, children: [(0, jsx_runtime_1.jsx)(LockScreen_1.LockScreen, { status: status, title: response?.title, message: response?.message, contactEmail: response?.contactEmail, contactPhone: response?.contactPhone, contactWhatsapp: response?.contactWhatsapp, allowUnlock: response?.allowUnlock === true, branding: response?.branding, onUnlock: unlock }), (0, jsx_runtime_1.jsx)(react_native_2.View, { style: styles.hiddenWhileLocked, pointerEvents: "none", children: children })] })) : ((0, jsx_runtime_1.jsxs)(react_native_2.View, { style: { flex: 1 }, children: [children, showBugIcon && ((0, jsx_runtime_1.jsx)(react_native_safe_area_context_1.SafeAreaInsetsContext.Consumer, { children: (insets) => {
|
|
388
397
|
const safeInsets = insets || { top: 0, bottom: 0, right: 0, left: 0 };
|
|
389
398
|
return ((0, jsx_runtime_1.jsx)(react_native_2.TouchableOpacity, { style: [
|
|
390
399
|
styles.bugIcon,
|
|
@@ -394,6 +403,13 @@ const DevGuardProvider = ({ children, projectId, secret, apiKey, autoProtect = t
|
|
|
394
403
|
};
|
|
395
404
|
exports.DevGuardProvider = DevGuardProvider;
|
|
396
405
|
const styles = react_native_2.StyleSheet.create({
|
|
406
|
+
hiddenWhileLocked: {
|
|
407
|
+
position: 'absolute',
|
|
408
|
+
width: 1,
|
|
409
|
+
height: 1,
|
|
410
|
+
opacity: 0,
|
|
411
|
+
overflow: 'hidden',
|
|
412
|
+
},
|
|
397
413
|
bugIcon: {
|
|
398
414
|
position: 'absolute',
|
|
399
415
|
right: 20,
|
|
@@ -417,3 +433,5 @@ const useDevGuard = () => {
|
|
|
417
433
|
return context;
|
|
418
434
|
};
|
|
419
435
|
exports.useDevGuard = useDevGuard;
|
|
436
|
+
var branding_1 = require("./types/branding");
|
|
437
|
+
Object.defineProperty(exports, "resolveBrandingFooter", { enumerable: true, get: function () { return branding_1.resolveBrandingFooter; } });
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** Auto-generated by tool/genObf.js — do not edit by hand. */
|
|
2
|
+
export declare const Obf: {
|
|
3
|
+
readonly symX9: string;
|
|
4
|
+
readonly symV2: string;
|
|
5
|
+
readonly symS3: string;
|
|
6
|
+
readonly symG4: string;
|
|
7
|
+
readonly symH5: string;
|
|
8
|
+
readonly symX6: string;
|
|
9
|
+
readonly symD7: string;
|
|
10
|
+
readonly symR8: string;
|
|
11
|
+
readonly symE1: string;
|
|
12
|
+
readonly contentType: string;
|
|
13
|
+
readonly appJson: string;
|
|
14
|
+
readonly hdrSig: string;
|
|
15
|
+
readonly hdrTs: string;
|
|
16
|
+
readonly hdrTunnel: string;
|
|
17
|
+
readonly hdrApiKey: string;
|
|
18
|
+
readonly respSig: string;
|
|
19
|
+
readonly tunnelV1: string;
|
|
20
|
+
readonly projectId: string;
|
|
21
|
+
readonly deviceId: string;
|
|
22
|
+
readonly deviceName: string;
|
|
23
|
+
readonly model: string;
|
|
24
|
+
readonly os: string;
|
|
25
|
+
readonly version: string;
|
|
26
|
+
readonly isPhysicalDevice: string;
|
|
27
|
+
readonly username: string;
|
|
28
|
+
readonly email: string;
|
|
29
|
+
readonly phone: string;
|
|
30
|
+
readonly customData: string;
|
|
31
|
+
readonly fingerprint: string;
|
|
32
|
+
readonly deviceToken: string;
|
|
33
|
+
readonly location: string;
|
|
34
|
+
readonly payloadField: string;
|
|
35
|
+
readonly unlockPath: string;
|
|
36
|
+
readonly providedKey: string;
|
|
37
|
+
readonly unlocked: string;
|
|
38
|
+
readonly defaultApiUrl: string;
|
|
39
|
+
readonly betaFeatures: string;
|
|
40
|
+
readonly bypassSignature: string;
|
|
41
|
+
readonly statusField: string;
|
|
42
|
+
readonly emulatorTitle: string;
|
|
43
|
+
readonly emulatorMessage: string;
|
|
44
|
+
readonly securityTitle: string;
|
|
45
|
+
readonly compromisedMessage: string;
|
|
46
|
+
readonly compromisedLog: string;
|
|
47
|
+
readonly missingSigLog: string;
|
|
48
|
+
readonly invalidSigBypassLog: string;
|
|
49
|
+
readonly invalidSigLog: string;
|
|
50
|
+
readonly invalidUnlockKey: string;
|
|
51
|
+
readonly enterUnlockKey: string;
|
|
52
|
+
readonly licenseKeyHint: string;
|
|
53
|
+
readonly cancelLabel: string;
|
|
54
|
+
readonly unlockLabel: string;
|
|
55
|
+
readonly whatsappSupport: string;
|
|
56
|
+
readonly emailSupport: string;
|
|
57
|
+
readonly callSupport: string;
|
|
58
|
+
readonly defaultLockMessage: string;
|
|
59
|
+
readonly contactOpenError: string;
|
|
60
|
+
readonly poweredBy: string;
|
|
61
|
+
readonly securedBy: string;
|
|
62
|
+
readonly brandDefault: string;
|
|
63
|
+
readonly brandWebsite: string;
|
|
64
|
+
readonly apiUnreachable: string;
|
|
65
|
+
readonly syncSkipped: string;
|
|
66
|
+
};
|
|
67
|
+
/** Native policy gate result codes (dg_e1). */
|
|
68
|
+
export declare const PolicyLock: {
|
|
69
|
+
readonly allow: 0;
|
|
70
|
+
readonly emulator: 1;
|
|
71
|
+
readonly compromised: 2;
|
|
72
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Auto-generated by tool/genObf.js — do not edit by hand. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.PolicyLock = exports.Obf = void 0;
|
|
5
|
+
const MASK = [0xF1, 0x3A, 0xC7, 0x82, 0x5E, 0xD9, 0x44, 0xAB];
|
|
6
|
+
function _d(encoded) {
|
|
7
|
+
const bytes = Uint8Array.from(encoded.map((b, i) => b ^ MASK[i % MASK.length]));
|
|
8
|
+
let out = '';
|
|
9
|
+
let i = 0;
|
|
10
|
+
while (i < bytes.length) {
|
|
11
|
+
const c = bytes[i++];
|
|
12
|
+
if (c < 0x80)
|
|
13
|
+
out += String.fromCharCode(c);
|
|
14
|
+
else if (c < 0xe0)
|
|
15
|
+
out += String.fromCharCode(((c & 0x1f) << 6) | (bytes[i++] & 0x3f));
|
|
16
|
+
else if (c < 0xf0) {
|
|
17
|
+
out += String.fromCharCode(((c & 0x0f) << 12) | ((bytes[i++] & 0x3f) << 6) | (bytes[i++] & 0x3f));
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
const code = ((c & 0x07) << 18) |
|
|
21
|
+
((bytes[i++] & 0x3f) << 12) |
|
|
22
|
+
((bytes[i++] & 0x3f) << 6) |
|
|
23
|
+
(bytes[i++] & 0x3f);
|
|
24
|
+
const offset = code - 0x10000;
|
|
25
|
+
out += String.fromCharCode(0xd800 + (offset >> 10), 0xdc00 + (offset & 0x3ff));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
exports.Obf = {
|
|
31
|
+
get symX9() { return _d([149, 93, 152, 250, 103]); },
|
|
32
|
+
get symV2() { return _d([149, 93, 152, 244, 108]); },
|
|
33
|
+
get symS3() { return _d([149, 93, 152, 241, 109]); },
|
|
34
|
+
get symG4() { return _d([149, 93, 152, 229, 106]); },
|
|
35
|
+
get symH5() { return _d([149, 93, 152, 234, 107]); },
|
|
36
|
+
get symX6() { return _d([149, 93, 152, 250, 104]); },
|
|
37
|
+
get symD7() { return _d([149, 93, 152, 230, 105]); },
|
|
38
|
+
get symR8() { return _d([149, 93, 152, 240, 102]); },
|
|
39
|
+
get symE1() { return _d([149, 93, 152, 231, 111]); },
|
|
40
|
+
get contentType() { return _d([178, 85, 169, 246, 59, 183, 48, 134, 165, 67, 183, 231]); },
|
|
41
|
+
get appJson() { return _d([144, 74, 183, 238, 55, 186, 37, 223, 152, 85, 169, 173, 52, 170, 43, 197]); },
|
|
42
|
+
get hdrSig() { return _d([169, 23, 131, 231, 40, 158, 49, 202, 131, 94, 234, 209, 55, 190, 42, 202, 133, 79, 181, 231]); },
|
|
43
|
+
get hdrTs() { return _d([169, 23, 131, 231, 40, 158, 49, 202, 131, 94, 234, 214, 55, 180, 33, 216, 133, 91, 170, 242]); },
|
|
44
|
+
get hdrTunnel() { return _d([169, 23, 131, 231, 40, 158, 49, 202, 131, 94, 234, 214, 43, 183, 42, 206, 157]); },
|
|
45
|
+
get hdrApiKey() { return _d([169, 23, 131, 231, 40, 158, 49, 202, 131, 94, 234, 195, 14, 144, 105, 224, 148, 67]); },
|
|
46
|
+
get respSig() { return _d([137, 23, 163, 231, 40, 190, 49, 202, 131, 94, 234, 240, 59, 170, 52, 196, 159, 73, 162, 175, 45, 176, 35, 197, 144, 78, 178, 240, 59]); },
|
|
47
|
+
get tunnelV1() { return _d([135, 11, 234, 229, 36, 176, 52]); },
|
|
48
|
+
get projectId() { return _d([129, 72, 168, 232, 59, 186, 48, 226, 149]); },
|
|
49
|
+
get deviceId() { return _d([149, 95, 177, 235, 61, 188, 13, 207]); },
|
|
50
|
+
get deviceName() { return _d([149, 95, 177, 235, 61, 188, 10, 202, 156, 95]); },
|
|
51
|
+
get model() { return _d([156, 85, 163, 231, 50]); },
|
|
52
|
+
get os() { return _d([158, 73]); },
|
|
53
|
+
get version() { return _d([135, 95, 181, 241, 55, 182, 42]); },
|
|
54
|
+
get isPhysicalDevice() { return _d([152, 73, 151, 234, 39, 170, 45, 200, 144, 86, 131, 231, 40, 176, 39, 206]); },
|
|
55
|
+
get username() { return _d([132, 73, 162, 240, 48, 184, 41, 206]); },
|
|
56
|
+
get email() { return _d([148, 87, 166, 235, 50]); },
|
|
57
|
+
get phone() { return _d([129, 82, 168, 236, 59]); },
|
|
58
|
+
get customData() { return _d([146, 79, 180, 246, 49, 180, 0, 202, 133, 91]); },
|
|
59
|
+
get fingerprint() { return _d([151, 83, 169, 229, 59, 171, 52, 217, 152, 84, 179]); },
|
|
60
|
+
get deviceToken() { return _d([149, 95, 177, 235, 61, 188, 16, 196, 154, 95, 169]); },
|
|
61
|
+
get location() { return _d([157, 85, 164, 227, 42, 176, 43, 197]); },
|
|
62
|
+
get payloadField() { return _d([129]); },
|
|
63
|
+
get unlockPath() { return _d([222, 79, 169, 238, 49, 186, 47]); },
|
|
64
|
+
get providedKey() { return _d([129, 72, 168, 244, 55, 189, 33, 207, 186, 95, 190]); },
|
|
65
|
+
get unlocked() { return _d([164, 84, 171, 237, 61, 178, 33, 207]); },
|
|
66
|
+
get defaultApiUrl() { return _d([153, 78, 179, 242, 45, 227, 107, 132, 144, 74, 174, 172, 58, 188, 50, 204, 132, 91, 181, 230, 112, 172, 47, 132, 149, 95, 177, 229, 43, 184, 54, 207]); },
|
|
67
|
+
get betaFeatures() { return _d([147, 95, 179, 227, 24, 188, 37, 223, 132, 72, 162, 241]); },
|
|
68
|
+
get bypassSignature() { return _d([147, 67, 183, 227, 45, 170, 23, 194, 150, 84, 166, 246, 43, 171, 33]); },
|
|
69
|
+
get statusField() { return _d([130, 78, 166, 246, 43, 170]); },
|
|
70
|
+
get emulatorTitle() { return _d([180, 87, 178, 238, 63, 173, 43, 217, 209, 126, 162, 246, 59, 186, 48, 206, 149]); },
|
|
71
|
+
get emulatorMessage() { return _d([165, 82, 174, 241, 126, 184, 52, 219, 157, 83, 164, 227, 42, 176, 43, 197, 209, 89, 166, 236, 48, 182, 48, 139, 131, 79, 169, 162, 49, 183, 100, 206, 156, 79, 171, 227, 42, 182, 54, 216, 209, 85, 181, 162, 45, 176, 41, 222, 157, 91, 179, 237, 44, 170, 100, 205, 158, 72, 231, 241, 59, 186, 49, 217, 152, 78, 190, 162, 44, 188, 37, 216, 158, 84, 180, 172]); },
|
|
72
|
+
get securityTitle() { return _d([162, 95, 164, 247, 44, 176, 48, 210, 209, 123, 171, 231, 44, 173]); },
|
|
73
|
+
get compromisedMessage() { return _d([165, 82, 174, 241, 126, 184, 52, 219, 157, 83, 164, 227, 42, 176, 43, 197, 209, 89, 166, 236, 48, 182, 48, 139, 131, 79, 169, 162, 49, 183, 100, 193, 144, 83, 171, 224, 44, 182, 47, 206, 159, 26, 168, 240, 126, 171, 43, 196, 133, 95, 163, 162, 58, 188, 50, 194, 146, 95, 180, 162, 56, 182, 54, 139, 130, 95, 164, 247, 44, 176, 48, 210, 209, 72, 162, 227, 45, 182, 42, 216, 223]); },
|
|
74
|
+
get compromisedLog() { return _d([181, 95, 177, 197, 43, 184, 54, 207, 209, 105, 162, 225, 43, 171, 45, 223, 136, 26, 134, 238, 59, 171, 48, 145, 209, 121, 168, 239, 46, 171, 43, 198, 152, 73, 162, 230, 126, 189, 33, 221, 152, 89, 162, 162, 58, 188, 48, 206, 146, 78, 162, 230, 112]); },
|
|
75
|
+
get missingSigLog() { return _d([181, 95, 177, 197, 43, 184, 54, 207, 209, 105, 162, 225, 43, 171, 45, 223, 136, 26, 134, 238, 59, 171, 48, 145, 209, 119, 174, 241, 45, 176, 42, 204, 209, 73, 162, 240, 40, 188, 54, 139, 131, 95, 180, 242, 49, 183, 55, 206, 209, 73, 174, 229, 48, 184, 48, 222, 131, 95, 233]); },
|
|
76
|
+
get invalidSigBypassLog() { return _d([181, 95, 177, 197, 43, 184, 54, 207, 209, 105, 162, 225, 43, 171, 45, 223, 136, 26, 144, 227, 44, 183, 45, 197, 150, 0, 231, 203, 48, 175, 37, 199, 152, 94, 231, 241, 59, 171, 50, 206, 131, 26, 181, 231, 45, 169, 43, 197, 130, 95, 231, 241, 55, 190, 42, 202, 133, 79, 181, 231, 114, 249, 38, 222, 133, 26, 165, 251, 46, 184, 55, 216, 162, 83, 160, 236, 63, 173, 49, 217, 148, 26, 174, 241, 126, 152, 7, 255, 184, 108, 130, 172]); },
|
|
77
|
+
get invalidSigLog() { return _d([181, 95, 177, 197, 43, 184, 54, 207, 209, 105, 162, 225, 43, 171, 45, 223, 136, 26, 134, 238, 59, 171, 48, 145, 209, 115, 169, 244, 63, 181, 45, 207, 209, 73, 162, 240, 40, 188, 54, 139, 131, 95, 180, 242, 49, 183, 55, 206, 209, 73, 174, 229, 48, 184, 48, 222, 131, 95, 230, 162, 14, 182, 55, 216, 152, 88, 171, 231, 126, 173, 37, 198, 129, 95, 181, 235, 48, 190, 100, 207, 148, 78, 162, 225, 42, 188, 32, 133]); },
|
|
78
|
+
get invalidUnlockKey() { return _d([184, 84, 177, 227, 50, 176, 32, 139, 132, 84, 171, 237, 61, 178, 100, 192, 148, 67, 233, 162, 14, 181, 33, 202, 130, 95, 231, 246, 44, 160, 100, 202, 150, 91, 174, 236, 112]); },
|
|
79
|
+
get enterUnlockKey() { return _d([1, 165, 83, 19, 126, 156, 42, 223, 148, 72, 231, 215, 48, 181, 43, 200, 154, 26, 140, 231, 39]); },
|
|
80
|
+
get licenseKeyHint() { return _d([180, 84, 179, 231, 44, 249, 8, 194, 146, 95, 169, 241, 59, 249, 15, 206, 136]); },
|
|
81
|
+
get cancelLabel() { return _d([178, 91, 169, 225, 59, 181]); },
|
|
82
|
+
get unlockLabel() { return _d([164, 84, 171, 237, 61, 178]); },
|
|
83
|
+
get whatsappSupport() { return _d([166, 82, 166, 246, 45, 152, 52, 219, 209, 105, 178, 242, 46, 182, 54, 223]); },
|
|
84
|
+
get emailSupport() { return _d([180, 87, 166, 235, 50, 249, 23, 222, 129, 74, 168, 240, 42]); },
|
|
85
|
+
get callSupport() { return _d([178, 91, 171, 238, 126, 138, 49, 219, 129, 85, 181, 246]); },
|
|
86
|
+
get defaultLockMessage() { return _d([165, 82, 174, 241, 126, 184, 52, 219, 157, 83, 164, 227, 42, 176, 43, 197, 209, 82, 166, 241, 126, 187, 33, 206, 159, 26, 181, 231, 51, 182, 48, 206, 157, 67, 231, 238, 49, 186, 47, 206, 149, 26, 165, 251, 126, 173, 44, 206, 209, 94, 162, 244, 59, 181, 43, 219, 148, 72, 233]); },
|
|
87
|
+
get contactOpenError() { return _d([178, 85, 178, 238, 58, 249, 42, 196, 133, 26, 168, 242, 59, 183, 100, 223, 153, 95, 231, 225, 49, 183, 48, 202, 146, 78, 231, 227, 46, 169, 40, 194, 146, 91, 179, 235, 49, 183, 106, 139, 161, 86, 162, 227, 45, 188, 100, 198, 144, 81, 162, 162, 45, 172, 54, 206, 209, 83, 179, 162, 55, 170, 100, 194, 159, 73, 179, 227, 50, 181, 33, 207, 209, 91, 169, 230, 126, 186, 43, 197, 151, 83, 160, 247, 44, 188, 32, 133]); },
|
|
88
|
+
get poweredBy() { return _d([161, 85, 176, 231, 44, 188, 32, 139, 147, 67]); },
|
|
89
|
+
get securedBy() { return _d([162, 95, 164, 247, 44, 188, 32, 139, 147, 67]); },
|
|
90
|
+
get brandDefault() { return _d([181, 95, 177, 197, 43, 184, 54, 207]); },
|
|
91
|
+
get brandWebsite() { return _d([153, 78, 179, 242, 45, 227, 107, 132, 149, 95, 177, 229, 43, 184, 54, 207, 223, 79, 172]); },
|
|
92
|
+
get apiUnreachable() { return _d([176, 106, 142, 221, 11, 151, 22, 238, 176, 121, 143, 195, 28, 149, 1]); },
|
|
93
|
+
get syncSkipped() { return _d([181, 95, 177, 197, 43, 184, 54, 207, 203, 26, 148, 251, 48, 186, 100, 216, 154, 83, 183, 242, 59, 189, 100, 207, 132, 95, 231, 246, 49, 249, 52, 196, 157, 83, 164, 251, 112]); },
|
|
94
|
+
};
|
|
95
|
+
/** Native policy gate result codes (dg_e1). */
|
|
96
|
+
exports.PolicyLock = {
|
|
97
|
+
allow: 0,
|
|
98
|
+
emulator: 1,
|
|
99
|
+
compromised: 2,
|
|
100
|
+
};
|
|
@@ -32,22 +32,17 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
-
};
|
|
38
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
36
|
exports.CacheService = void 0;
|
|
40
37
|
const Keychain = __importStar(require("react-native-keychain"));
|
|
41
|
-
const
|
|
38
|
+
const cacheCrypto_1 = require("./cacheCrypto");
|
|
42
39
|
class CacheService {
|
|
43
40
|
static SERVICE_NAME = 'devguard.cache.service';
|
|
44
41
|
static WIPE_SERVICE = 'devguard.wipe.service';
|
|
45
42
|
static async saveResponse(projectId, response) {
|
|
46
43
|
try {
|
|
47
44
|
const dataString = JSON.stringify(response);
|
|
48
|
-
|
|
49
|
-
const encrypted = crypto_js_1.default.AES.encrypt(dataString, projectId).toString();
|
|
50
|
-
// Store in secure keychain
|
|
45
|
+
const encrypted = (0, cacheCrypto_1.encryptCachePayload)(projectId, dataString);
|
|
51
46
|
await Keychain.setGenericPassword(`devguard_${projectId}`, encrypted, { service: this.SERVICE_NAME });
|
|
52
47
|
}
|
|
53
48
|
catch (e) {
|
|
@@ -58,10 +53,7 @@ class CacheService {
|
|
|
58
53
|
try {
|
|
59
54
|
const credentials = await Keychain.getGenericPassword({ service: this.SERVICE_NAME });
|
|
60
55
|
if (credentials && credentials.username === `devguard_${projectId}`) {
|
|
61
|
-
const
|
|
62
|
-
// Decrypt using projectId
|
|
63
|
-
const bytes = crypto_js_1.default.AES.decrypt(encrypted, projectId);
|
|
64
|
-
const decrypted = bytes.toString(crypto_js_1.default.enc.Utf8);
|
|
56
|
+
const decrypted = (0, cacheCrypto_1.decryptCachePayload)(projectId, credentials.password);
|
|
65
57
|
if (decrypted) {
|
|
66
58
|
return JSON.parse(decrypted);
|
|
67
59
|
}
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Client-side policy enforcement applied to a server response before it is
|
|
3
|
-
* shown to the user. Mirrors
|
|
4
|
-
* platforms behave identically.
|
|
3
|
+
* shown to the user. Mirrors Flutter `GuardEnforcement` + native `dg_e1`.
|
|
5
4
|
*/
|
|
6
5
|
export declare class GuardEnforcement {
|
|
7
|
-
|
|
8
|
-
* Applies enforcement rules to a fresh server response.
|
|
9
|
-
*
|
|
10
|
-
* - `blockEmulators`: if the project blocks emulators and the current device
|
|
11
|
-
* is not a physical device, the response is overridden to LOCKED.
|
|
12
|
-
*
|
|
13
|
-
* @param response The parsed server response (mutated copy returned).
|
|
14
|
-
* @param metadata The device metadata collected for this sync.
|
|
15
|
-
*/
|
|
6
|
+
private static evaluatePolicy;
|
|
16
7
|
static apply(response: any, metadata: {
|
|
17
8
|
isPhysicalDevice?: boolean;
|
|
18
|
-
}): any
|
|
9
|
+
}, isCompromised?: boolean): Promise<any>;
|
|
19
10
|
}
|