ugly-app 0.1.717 → 0.1.718
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/cli/version.d.ts +1 -1
- package/dist/cli/version.js +1 -1
- package/dist/native/index.d.ts +2 -0
- package/dist/native/index.d.ts.map +1 -1
- package/dist/native/index.js +1 -0
- package/dist/native/index.js.map +1 -1
- package/dist/native/proxyHost.d.ts +19 -0
- package/dist/native/proxyHost.d.ts.map +1 -0
- package/dist/native/proxyHost.js +139 -0
- package/dist/native/proxyHost.js.map +1 -0
- package/dist/server/auth/magicLinkTemplate.d.ts +1 -1
- package/dist/server/auth/magicLinkTemplate.d.ts.map +1 -1
- package/dist/server/auth/magicLinkTemplate.js +12 -6
- package/dist/server/auth/magicLinkTemplate.js.map +1 -1
- package/dist/server/auth/workersMagicLink.d.ts.map +1 -1
- package/dist/server/auth/workersMagicLink.js +15 -1
- package/dist/server/auth/workersMagicLink.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/version.ts +1 -1
- package/src/native/index.ts +2 -0
- package/src/native/proxyHost.test.ts +126 -0
- package/src/native/proxyHost.ts +162 -0
- package/src/server/auth/magicLinkTemplate.ts +13 -5
- package/src/server/auth/workersMagicLink.ts +16 -1
package/dist/cli/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.1.
|
|
1
|
+
export declare const CLI_VERSION = "0.1.718";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/cli/version.js
CHANGED
package/dist/native/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export { defineTask, taskContext } from './defineTask.js';
|
|
|
21
21
|
export type { TaskDefinition, TaskContext } from './defineTask.js';
|
|
22
22
|
export { MCP_CATALOG } from './mcp-catalog.js';
|
|
23
23
|
export { createProxyClient, nativeSigner } from './proxyClient.js';
|
|
24
|
+
export { createProxyHost } from './proxyHost.js';
|
|
25
|
+
export type { ProxyHost, ProxyHostOpts } from './proxyHost.js';
|
|
24
26
|
export type { ProxyClient, ProxyClientOpts, ProxySocket, HostInfo, RTCFactory, } from './proxyClient.js';
|
|
25
27
|
export { isDesktopChannel, withProxy, enableUglyProxy, installProxyClient, dispatchNativeEvent, DESKTOP_NAMESPACES } from './proxy.js';
|
|
26
28
|
export type { WithProxyOpts } from './proxy.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,OAAO,EACP,WAAW,EACX,SAAS,EACT,QAAQ,EACR,MAAM,EACN,SAAS,EACT,cAAc,EACd,aAAa,EACb,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,eAAe,EACf,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/E,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtF,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACtE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACnE,YAAY,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,QAAQ,EACR,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACvI,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnF,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,OAAO,EACP,WAAW,EACX,SAAS,EACT,QAAQ,EACR,MAAM,EACN,SAAS,EACT,cAAc,EACd,aAAa,EACb,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,SAAS,EACT,WAAW,EACX,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,QAAQ,EACR,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,eAAe,EACf,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,QAAQ,EACR,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/E,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtF,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACtE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/D,YAAY,EACV,WAAW,EACX,eAAe,EACf,WAAW,EACX,QAAQ,EACR,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACvI,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACnF,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/native/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export { defineTask, taskContext } from './defineTask.js';
|
|
|
12
12
|
export { MCP_CATALOG } from './mcp-catalog.js';
|
|
13
13
|
// ── Ugly Proxy (remote UglyNative over WebRTC) ──
|
|
14
14
|
export { createProxyClient, nativeSigner } from './proxyClient.js';
|
|
15
|
+
export { createProxyHost } from './proxyHost.js';
|
|
15
16
|
export { isDesktopChannel, withProxy, enableUglyProxy, installProxyClient, dispatchNativeEvent, DESKTOP_NAMESPACES } from './proxy.js';
|
|
16
17
|
export { fpTag, verifyFpTag, parseFingerprint, mskSigner } from './proxyCrypto.js';
|
|
17
18
|
//# sourceMappingURL=index.js.map
|
package/dist/native/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE/E,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,0EAA0E;AAC1E,wFAAwF;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAUtF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,gFAAgF;AAChF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,mDAAmD;AACnD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/native/index.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE/E,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,0EAA0E;AAC1E,wFAAwF;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAUtF,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,gFAAgF;AAChF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,mDAAmD;AACnD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AASjD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEvI,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ProxySigner } from './proxyCrypto.js';
|
|
2
|
+
import type { ProxySocket, RTCFactory } from './proxyClient.js';
|
|
3
|
+
export interface ProxyHostOpts {
|
|
4
|
+
socket: ProxySocket;
|
|
5
|
+
/** Verify the client's offer fingerprint + sign our answer (MSK-bound). */
|
|
6
|
+
signer?: ProxySigner;
|
|
7
|
+
iceServers?: RTCIceServer[];
|
|
8
|
+
rtcFactory?: RTCFactory;
|
|
9
|
+
/** Handle a tunneled request. `origin` is the app the client declared. Throw → error frame. */
|
|
10
|
+
onInvoke: (channel: string, payload: unknown, origin: string) => Promise<unknown>;
|
|
11
|
+
}
|
|
12
|
+
export interface ProxyHost {
|
|
13
|
+
stop(): void;
|
|
14
|
+
/** Push an evt frame to every client subscribed to `event` (live inspect streams). */
|
|
15
|
+
broadcast(event: string, data: unknown): void;
|
|
16
|
+
peerCount(): number;
|
|
17
|
+
}
|
|
18
|
+
export declare function createProxyHost(opts: ProxyHostOpts): ProxyHost;
|
|
19
|
+
//# sourceMappingURL=proxyHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxyHost.d.ts","sourceRoot":"","sources":["../../src/native/proxyHost.ts"],"names":[],"mappings":"AAaA,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,+FAA+F;IAC/F,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACnF;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,IAAI,IAAI,CAAC;IACb,sFAAsF;IACtF,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9C,SAAS,IAAI,MAAM,CAAC;CACrB;AAkBD,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG,SAAS,CAgH9D"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Browser-side host of the Ugly Proxy: the symmetric counterpart of
|
|
2
|
+
// proxyClient. A shell with NO native host (chiefly the MOBILE SPA, where the
|
|
3
|
+
// whole proxy stack lives in the webview) registers as a proxy HOST and ANSWERS
|
|
4
|
+
// a remote inspector's WebRTC offer, then dispatches the tunneled inspect.*
|
|
5
|
+
// (or any UglyNative) calls. Signaling rides the app Socket's rtc:* messages;
|
|
6
|
+
// DTLS encrypts; the MSK-bound fingerprint check authenticates the client.
|
|
7
|
+
//
|
|
8
|
+
// NOTE: on the DESKTOP the host lives in the Electron main (ugly-studio
|
|
9
|
+
// hostHub/werift) — a desktop *renderer* host was tried + reverted. This module
|
|
10
|
+
// is for shells that have no main process, where the SPA is the only host there
|
|
11
|
+
// can be. RTCPeerConnection + Socket are injectable so it's unit-testable and
|
|
12
|
+
// can drive werift in node tests.
|
|
13
|
+
import { parseFingerprint } from './proxyCrypto.js';
|
|
14
|
+
function rec(d) {
|
|
15
|
+
return (d ?? {});
|
|
16
|
+
}
|
|
17
|
+
export function createProxyHost(opts) {
|
|
18
|
+
const rtcFactory = opts.rtcFactory ?? ((cfg) => new RTCPeerConnection(cfg));
|
|
19
|
+
const peers = new Map(); // keyed by client deviceId (`from`)
|
|
20
|
+
const subs = new Set();
|
|
21
|
+
const offs = [];
|
|
22
|
+
async function onOffer(d) {
|
|
23
|
+
const from = String(d['from'] ?? '');
|
|
24
|
+
if (!from)
|
|
25
|
+
return;
|
|
26
|
+
const sdp = String(d['sdp'] ?? '');
|
|
27
|
+
const origin = String(d['origin'] ?? '');
|
|
28
|
+
if (opts.signer) {
|
|
29
|
+
const ok = await opts.signer.verify('client', parseFingerprint(sdp) ?? '', String(d['fpTag'] ?? ''));
|
|
30
|
+
if (!ok) {
|
|
31
|
+
opts.socket.emit('rtc:error', { to: from, reason: 'fingerprint-auth-failed' });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
peers.get(from)?.pc.close();
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
/* noop */
|
|
40
|
+
}
|
|
41
|
+
const pc = rtcFactory({ iceServers: opts.iceServers ?? [] });
|
|
42
|
+
const peer = { pc, dc: null, origin };
|
|
43
|
+
peers.set(from, peer);
|
|
44
|
+
pc.onicecandidate = (e) => {
|
|
45
|
+
if (e.candidate)
|
|
46
|
+
opts.socket.emit('rtc:ice', { to: from, candidate: e.candidate.toJSON() });
|
|
47
|
+
};
|
|
48
|
+
pc.ondatachannel = (e) => {
|
|
49
|
+
peer.dc = e.channel;
|
|
50
|
+
e.channel.onmessage = (m) => void onFrame(peer, e.channel, m.data);
|
|
51
|
+
};
|
|
52
|
+
await pc.setRemoteDescription({ type: 'offer', sdp });
|
|
53
|
+
const answer = await pc.createAnswer();
|
|
54
|
+
await pc.setLocalDescription(answer);
|
|
55
|
+
const answerSdp = pc.localDescription?.sdp ?? answer.sdp ?? '';
|
|
56
|
+
const tag = opts.signer ? await opts.signer.sign('host', parseFingerprint(answerSdp) ?? '') : undefined;
|
|
57
|
+
opts.socket.emit('rtc:answer', { to: from, sdp: answerSdp, fpTag: tag });
|
|
58
|
+
}
|
|
59
|
+
async function onIce(d) {
|
|
60
|
+
const peer = peers.get(String(d['from'] ?? ''));
|
|
61
|
+
if (!peer)
|
|
62
|
+
return;
|
|
63
|
+
try {
|
|
64
|
+
await peer.pc.addIceCandidate(d['candidate']);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
/* benign — candidate races */
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function onFrame(peer, dc, raw) {
|
|
71
|
+
let f;
|
|
72
|
+
try {
|
|
73
|
+
f = JSON.parse(typeof raw === 'string' ? raw : new TextDecoder().decode(raw));
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (f.t === 'req' && f.id !== undefined) {
|
|
79
|
+
try {
|
|
80
|
+
const result = await opts.onInvoke(String(f.channel), f.payload, peer.origin);
|
|
81
|
+
send(dc, { t: 'res', id: f.id, ok: true, result });
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
send(dc, { t: 'res', id: f.id, ok: false, error: String(err?.message ?? err) });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else if (f.t === 'sub' && f.id !== undefined) {
|
|
88
|
+
// Register the live subscription; broadcast() fans matching events out.
|
|
89
|
+
// Snapshot is null — the client's panels also pull the current buffer via req.
|
|
90
|
+
subs.add({ dc, event: String(f.channel ?? ''), id: f.id });
|
|
91
|
+
send(dc, { t: 'res', id: f.id, ok: true, result: { snapshot: null } });
|
|
92
|
+
}
|
|
93
|
+
else if (f.t === 'unsub' && f.id !== undefined) {
|
|
94
|
+
for (const s of [...subs])
|
|
95
|
+
if (s.dc === dc && s.id === f.id)
|
|
96
|
+
subs.delete(s);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function send(dc, frame) {
|
|
100
|
+
try {
|
|
101
|
+
if (dc.readyState === 'open')
|
|
102
|
+
dc.send(JSON.stringify(frame));
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
/* channel gone */
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
offs.push(opts.socket.on('rtc:offer', (d) => void onOffer(rec(d))));
|
|
109
|
+
offs.push(opts.socket.on('rtc:ice', (d) => void onIce(rec(d))));
|
|
110
|
+
return {
|
|
111
|
+
stop() {
|
|
112
|
+
for (const off of offs) {
|
|
113
|
+
try {
|
|
114
|
+
off();
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
/* noop */
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (const peer of peers.values()) {
|
|
121
|
+
try {
|
|
122
|
+
peer.pc.close();
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
/* noop */
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
peers.clear();
|
|
129
|
+
subs.clear();
|
|
130
|
+
},
|
|
131
|
+
broadcast(event, data) {
|
|
132
|
+
for (const s of subs)
|
|
133
|
+
if (s.event === event)
|
|
134
|
+
send(s.dc, { t: 'evt', event, data });
|
|
135
|
+
},
|
|
136
|
+
peerCount: () => peers.size,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=proxyHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxyHost.js","sourceRoot":"","sources":["../../src/native/proxyHost.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* the same in every mail client. The button colour is black so it survives
|
|
7
7
|
* light/dark-mode inversion.
|
|
8
8
|
*/
|
|
9
|
-
export declare function magicLinkEmail(url: string, appName: string, expiresMin: number): {
|
|
9
|
+
export declare function magicLinkEmail(url: string, appName: string, expiresMin: number, iconUrl?: string): {
|
|
10
10
|
subject: string;
|
|
11
11
|
html: string;
|
|
12
12
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magicLinkTemplate.d.ts","sourceRoot":"","sources":["../../../src/server/auth/magicLinkTemplate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"magicLinkTemplate.d.ts","sourceRoot":"","sources":["../../../src/server/auth/magicLinkTemplate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,GACf;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAmBjD"}
|
|
@@ -6,15 +6,21 @@
|
|
|
6
6
|
* the same in every mail client. The button colour is black so it survives
|
|
7
7
|
* light/dark-mode inversion.
|
|
8
8
|
*/
|
|
9
|
-
export function magicLinkEmail(url, appName, expiresMin) {
|
|
9
|
+
export function magicLinkEmail(url, appName, expiresMin, iconUrl) {
|
|
10
10
|
const safeAppName = escapeHtml(appName);
|
|
11
|
+
// Only honour absolute https icons — mail clients won't load anything else,
|
|
12
|
+
// and it keeps a hostile relative/`javascript:` value out of the markup.
|
|
13
|
+
const iconImg = iconUrl && /^https:\/\//i.test(iconUrl)
|
|
14
|
+
? `<img src="${escapeHtml(iconUrl)}" alt="" width="56" height="56" style="border-radius:12px;display:block;margin:0 auto 16px">`
|
|
15
|
+
: '';
|
|
11
16
|
return {
|
|
12
17
|
subject: `Sign in to ${appName}`,
|
|
13
|
-
html: `<!doctype html><html><body style="font-family:system-ui,sans-serif;padding:24px;max-width:480px;margin:auto">
|
|
14
|
-
|
|
15
|
-
<
|
|
16
|
-
<p
|
|
17
|
-
<p style="color:#
|
|
18
|
+
html: `<!doctype html><html><body style="font-family:system-ui,sans-serif;padding:24px;max-width:480px;margin:auto;text-align:center">
|
|
19
|
+
${iconImg}
|
|
20
|
+
<h2 style="margin:0 0 12px">Sign in to ${safeAppName}</h2>
|
|
21
|
+
<p style="text-align:left">Click the button below to sign in. This link expires in ${expiresMin} minutes and can only be used once.</p>
|
|
22
|
+
<p><a href="${url}" style="background:#000;color:#fff;padding:12px 24px;text-decoration:none;border-radius:6px;display:inline-block">Sign in to ${safeAppName}</a></p>
|
|
23
|
+
<p style="color:#888;font-size:12px;text-align:left">If you didn't request this, you can safely ignore this email.</p>
|
|
18
24
|
</body></html>`,
|
|
19
25
|
text: `Sign in to ${appName}: ${url}\n\nThis link expires in ${expiresMin} minutes.`,
|
|
20
26
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"magicLinkTemplate.js","sourceRoot":"","sources":["../../../src/server/auth/magicLinkTemplate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAW,EACX,OAAe,EACf,UAAkB;
|
|
1
|
+
{"version":3,"file":"magicLinkTemplate.js","sourceRoot":"","sources":["../../../src/server/auth/magicLinkTemplate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,GAAW,EACX,OAAe,EACf,UAAkB,EAClB,OAAgB;IAEhB,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACxC,4EAA4E;IAC5E,yEAAyE;IACzE,MAAM,OAAO,GACX,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC;QACrC,CAAC,CAAC,aAAa,UAAU,CAAC,OAAO,CAAC,8FAA8F;QAChI,CAAC,CAAC,EAAE,CAAC;IACT,OAAO;QACL,OAAO,EAAE,cAAc,OAAO,EAAE;QAChC,IAAI,EAAE;QACF,OAAO;+CACgC,WAAW;2FACiC,UAAU;oBACjF,GAAG,iIAAiI,WAAW;;mBAEhJ;QACf,IAAI,EAAE,cAAc,OAAO,KAAK,GAAG,4BAA4B,UAAU,WAAW;KACrF,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,OAAO,CACd,SAAS,EACT,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAE,CACvE,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workersMagicLink.d.ts","sourceRoot":"","sources":["../../../src/server/auth/workersMagicLink.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,MAAM,CAAC;AAK1C,OAAO,EAA4B,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAI5E,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"workersMagicLink.d.ts","sourceRoot":"","sources":["../../../src/server/auth/workersMagicLink.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAW,IAAI,EAAE,MAAM,MAAM,CAAC;AAK1C,OAAO,EAA4B,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAI5E,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAkExE,MAAM,WAAW,sBAAsB;IACrC,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IAEH,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;IACjB,kEAAkE;IAClE,YAAY,EAAE,YAAY,CAAC;CAC5B;AA+DD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAA+B,GACtC,OAAO,CAAC,MAAM,CAAC,CAOjB;AAED,+EAA+E;AAC/E,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAOjB;AAYD;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAE5C,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EACf,MAAM,EAAE,sBAAsB,GAC7B,IAAI,CAqNN"}
|
|
@@ -21,6 +21,14 @@ const requestBodySchema = z.object({
|
|
|
21
21
|
* `window.location.href` so the user resumes wherever they were.
|
|
22
22
|
*/
|
|
23
23
|
returnTo: z.string().max(2000).optional(),
|
|
24
|
+
/**
|
|
25
|
+
* Optional per-request branding for the email (subject/heading + icon).
|
|
26
|
+
* Used by a central login authority (e.g. ugly.bot) to brand the sign-in
|
|
27
|
+
* email with the CHILD app that triggered the login, rather than the
|
|
28
|
+
* authority's own name. Falls back to the registration-time `appName`.
|
|
29
|
+
*/
|
|
30
|
+
appName: z.string().max(120).optional(),
|
|
31
|
+
iconUrl: z.string().url().max(2000).optional(),
|
|
24
32
|
});
|
|
25
33
|
const verifyBodySchema = z.object({
|
|
26
34
|
id: z.string().min(1).max(128),
|
|
@@ -221,7 +229,13 @@ hono, config) {
|
|
|
221
229
|
// eslint-disable-next-line no-console
|
|
222
230
|
console.log(`[Auth] DEBUG magic-link for ${email}: ${url}`);
|
|
223
231
|
}
|
|
224
|
-
|
|
232
|
+
// Per-request branding (the app that triggered the login) overrides the
|
|
233
|
+
// registration-time default; icon is honoured only if absolute https.
|
|
234
|
+
const reqAppName = parsed.data.appName?.trim() || appName;
|
|
235
|
+
const reqIconUrl = parsed.data.iconUrl && /^https:\/\//i.test(parsed.data.iconUrl)
|
|
236
|
+
? parsed.data.iconUrl
|
|
237
|
+
: undefined;
|
|
238
|
+
const tpl = magicLinkEmail(url, reqAppName, expiresMin, reqIconUrl);
|
|
225
239
|
let emailError = null;
|
|
226
240
|
try {
|
|
227
241
|
await emailSend({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workersMagicLink.js","sourceRoot":"","sources":["../../../src/server/auth/workersMagicLink.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"workersMagicLink.js","sourceRoot":"","sources":["../../../src/server/auth/workersMagicLink.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ugly-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.718",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"comment:files": "Allowlist what ships to npm. dist = runtime; src = sourcemap targets (dist/*.js.map reference ../../src/); templates = CLI scaffold. Everything else at repo root (.pgdata local Postgres, coverage, assets/icons sources, test/, test-results/) is excluded by omission. The !negations strip the scaffold's installed deps + cruft (templates/node_modules is 200MB+ and must never ship). package.json/README/LICENSE ship automatically.",
|
|
6
6
|
"files": [
|
package/src/cli/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by prebuild — do not edit manually
|
|
2
|
-
export const CLI_VERSION = "0.1.
|
|
2
|
+
export const CLI_VERSION = "0.1.718";
|
package/src/native/index.ts
CHANGED
|
@@ -67,6 +67,8 @@ export { MCP_CATALOG } from './mcp-catalog.js';
|
|
|
67
67
|
|
|
68
68
|
// ── Ugly Proxy (remote UglyNative over WebRTC) ──
|
|
69
69
|
export { createProxyClient, nativeSigner } from './proxyClient.js';
|
|
70
|
+
export { createProxyHost } from './proxyHost.js';
|
|
71
|
+
export type { ProxyHost, ProxyHostOpts } from './proxyHost.js';
|
|
70
72
|
export type {
|
|
71
73
|
ProxyClient,
|
|
72
74
|
ProxyClientOpts,
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { createProxyHost } from './proxyHost.js';
|
|
3
|
+
import type { ProxySocket } from './proxyClient.js';
|
|
4
|
+
import type { ProxySigner } from './proxyCrypto.js';
|
|
5
|
+
|
|
6
|
+
// A controllable fake socket: capture emits, fire inbound rtc:* events on demand.
|
|
7
|
+
function fakeSocket() {
|
|
8
|
+
const emits: { type: string; data: Record<string, unknown> }[] = [];
|
|
9
|
+
const handlers = new Map<string, (d: unknown) => void>();
|
|
10
|
+
const socket: ProxySocket = {
|
|
11
|
+
emit: (type, data) => emits.push({ type, data: data as Record<string, unknown> }),
|
|
12
|
+
on: (event, handler) => {
|
|
13
|
+
handlers.set(event, handler);
|
|
14
|
+
return () => handlers.delete(event);
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
return { socket, emits, fire: (event: string, d: unknown) => handlers.get(event)?.(d) };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// A fake RTCDataChannel that records sent frames and lets the test push messages.
|
|
21
|
+
function fakeChannel() {
|
|
22
|
+
const sent: string[] = [];
|
|
23
|
+
const ch = {
|
|
24
|
+
readyState: 'open',
|
|
25
|
+
send: (s: string) => sent.push(s),
|
|
26
|
+
onmessage: null as null | ((e: { data: unknown }) => void),
|
|
27
|
+
};
|
|
28
|
+
return { ch, sent, push: (frame: object) => ch.onmessage?.({ data: JSON.stringify(frame) }) };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// rtcFactory returning a fake answerer PC the test drives.
|
|
32
|
+
function fakeRtc() {
|
|
33
|
+
const pc: Record<string, unknown> = {
|
|
34
|
+
onicecandidate: null,
|
|
35
|
+
ondatachannel: null,
|
|
36
|
+
setRemoteDescription: vi.fn(async () => {}),
|
|
37
|
+
createAnswer: vi.fn(async () => ({ type: 'answer', sdp: 'answer-sdp\na=fingerprint:sha-256 AA:BB' })),
|
|
38
|
+
setLocalDescription: vi.fn(async () => {}),
|
|
39
|
+
localDescription: { sdp: 'answer-sdp\na=fingerprint:sha-256 AA:BB' },
|
|
40
|
+
addIceCandidate: vi.fn(async () => {}),
|
|
41
|
+
close: vi.fn(),
|
|
42
|
+
};
|
|
43
|
+
return { pc, factory: () => pc as unknown as RTCPeerConnection };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const okSigner: ProxySigner = {
|
|
47
|
+
sign: vi.fn(async (role: string) => `sig-${role}`),
|
|
48
|
+
verify: vi.fn(async (_role, _fp, tag: string) => tag === 'good'),
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
describe('createProxyHost', () => {
|
|
52
|
+
it('answers a fingerprint-valid offer with a host-signed answer', async () => {
|
|
53
|
+
const { socket, emits, fire } = fakeSocket();
|
|
54
|
+
const { pc, factory } = fakeRtc();
|
|
55
|
+
createProxyHost({ socket, signer: okSigner, rtcFactory: factory, onInvoke: async () => ({}) });
|
|
56
|
+
|
|
57
|
+
await fire('rtc:offer', { from: 'client-1', sdp: 'offer-sdp\na=fingerprint:sha-256 CC:DD', fpTag: 'good', origin: 'https://app.x' });
|
|
58
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
59
|
+
|
|
60
|
+
expect(okSigner.verify).toHaveBeenCalledWith('client', expect.any(String), 'good');
|
|
61
|
+
expect(pc.setRemoteDescription).toHaveBeenCalled();
|
|
62
|
+
const answer = emits.find((e) => e.type === 'rtc:answer');
|
|
63
|
+
expect(answer?.data).toMatchObject({ to: 'client-1', sdp: expect.stringContaining('answer-sdp'), fpTag: 'sig-host' });
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('rejects an offer with a bad fingerprint (no answer, emits rtc:error)', async () => {
|
|
67
|
+
const { socket, emits, fire } = fakeSocket();
|
|
68
|
+
createProxyHost({ socket, signer: okSigner, rtcFactory: fakeRtc().factory, onInvoke: async () => ({}) });
|
|
69
|
+
|
|
70
|
+
await fire('rtc:offer', { from: 'evil', sdp: 'x', fpTag: 'BAD', origin: '' });
|
|
71
|
+
await Promise.resolve();
|
|
72
|
+
|
|
73
|
+
expect(emits.find((e) => e.type === 'rtc:answer')).toBeUndefined();
|
|
74
|
+
expect(emits.find((e) => e.type === 'rtc:error')?.data).toMatchObject({ to: 'evil', reason: 'fingerprint-auth-failed' });
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('dispatches a req frame to onInvoke and replies with a res frame', async () => {
|
|
78
|
+
const { socket, fire } = fakeSocket();
|
|
79
|
+
const { pc, factory } = fakeRtc();
|
|
80
|
+
const onInvoke = vi.fn(async (channel: string) => ({ echoed: channel }));
|
|
81
|
+
createProxyHost({ socket, signer: okSigner, rtcFactory: factory, onInvoke });
|
|
82
|
+
|
|
83
|
+
await fire('rtc:offer', { from: 'c', sdp: 's\na=fingerprint:sha-256 CC', fpTag: 'good', origin: 'https://o' });
|
|
84
|
+
await Promise.resolve();
|
|
85
|
+
|
|
86
|
+
const { ch, sent, push } = fakeChannel();
|
|
87
|
+
(pc.ondatachannel as (e: { channel: unknown }) => void)({ channel: ch });
|
|
88
|
+
push({ t: 'req', id: '7', channel: 'inspect.listTargets', payload: {} });
|
|
89
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
90
|
+
|
|
91
|
+
expect(onInvoke).toHaveBeenCalledWith('inspect.listTargets', {}, 'https://o');
|
|
92
|
+
expect(JSON.parse(sent[0])).toEqual({ t: 'res', id: '7', ok: true, result: { echoed: 'inspect.listTargets' } });
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('replies with an error frame when onInvoke throws', async () => {
|
|
96
|
+
const { socket, fire } = fakeSocket();
|
|
97
|
+
const { pc, factory } = fakeRtc();
|
|
98
|
+
createProxyHost({ socket, signer: okSigner, rtcFactory: factory, onInvoke: async () => { throw new Error('boom'); } });
|
|
99
|
+
await fire('rtc:offer', { from: 'c', sdp: 's', fpTag: 'good', origin: '' });
|
|
100
|
+
await Promise.resolve();
|
|
101
|
+
const { ch, sent, push } = fakeChannel();
|
|
102
|
+
(pc.ondatachannel as (e: { channel: unknown }) => void)({ channel: ch });
|
|
103
|
+
push({ t: 'req', id: '1', channel: 'inspect.eval', payload: {} });
|
|
104
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
105
|
+
expect(JSON.parse(sent[0])).toMatchObject({ t: 'res', id: '1', ok: false, error: expect.stringContaining('boom') });
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('broadcasts evt frames to subscribed channels only', async () => {
|
|
109
|
+
const { socket, fire } = fakeSocket();
|
|
110
|
+
const { pc, factory } = fakeRtc();
|
|
111
|
+
const host = createProxyHost({ socket, signer: okSigner, rtcFactory: factory, onInvoke: async () => ({}) });
|
|
112
|
+
await fire('rtc:offer', { from: 'c', sdp: 's', fpTag: 'good', origin: '' });
|
|
113
|
+
await Promise.resolve();
|
|
114
|
+
const { ch, sent, push } = fakeChannel();
|
|
115
|
+
(pc.ondatachannel as (e: { channel: unknown }) => void)({ channel: ch });
|
|
116
|
+
|
|
117
|
+
push({ t: 'sub', id: '9', channel: 'inspect.console:self' });
|
|
118
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
119
|
+
expect(JSON.parse(sent[0])).toMatchObject({ t: 'res', id: '9', ok: true });
|
|
120
|
+
|
|
121
|
+
host.broadcast('inspect.console:self', { text: 'hello' });
|
|
122
|
+
host.broadcast('inspect.network:self', { url: 'x' }); // not subscribed → dropped
|
|
123
|
+
const evts = sent.slice(1).map((s) => JSON.parse(s));
|
|
124
|
+
expect(evts).toEqual([{ t: 'evt', event: 'inspect.console:self', data: { text: 'hello' } }]);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// Browser-side host of the Ugly Proxy: the symmetric counterpart of
|
|
2
|
+
// proxyClient. A shell with NO native host (chiefly the MOBILE SPA, where the
|
|
3
|
+
// whole proxy stack lives in the webview) registers as a proxy HOST and ANSWERS
|
|
4
|
+
// a remote inspector's WebRTC offer, then dispatches the tunneled inspect.*
|
|
5
|
+
// (or any UglyNative) calls. Signaling rides the app Socket's rtc:* messages;
|
|
6
|
+
// DTLS encrypts; the MSK-bound fingerprint check authenticates the client.
|
|
7
|
+
//
|
|
8
|
+
// NOTE: on the DESKTOP the host lives in the Electron main (ugly-studio
|
|
9
|
+
// hostHub/werift) — a desktop *renderer* host was tried + reverted. This module
|
|
10
|
+
// is for shells that have no main process, where the SPA is the only host there
|
|
11
|
+
// can be. RTCPeerConnection + Socket are injectable so it's unit-testable and
|
|
12
|
+
// can drive werift in node tests.
|
|
13
|
+
|
|
14
|
+
import { parseFingerprint, type ProxySigner } from './proxyCrypto.js';
|
|
15
|
+
import type { ProxySocket, RTCFactory } from './proxyClient.js';
|
|
16
|
+
|
|
17
|
+
export interface ProxyHostOpts {
|
|
18
|
+
socket: ProxySocket;
|
|
19
|
+
/** Verify the client's offer fingerprint + sign our answer (MSK-bound). */
|
|
20
|
+
signer?: ProxySigner;
|
|
21
|
+
iceServers?: RTCIceServer[];
|
|
22
|
+
rtcFactory?: RTCFactory;
|
|
23
|
+
/** Handle a tunneled request. `origin` is the app the client declared. Throw → error frame. */
|
|
24
|
+
onInvoke: (channel: string, payload: unknown, origin: string) => Promise<unknown>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ProxyHost {
|
|
28
|
+
stop(): void;
|
|
29
|
+
/** Push an evt frame to every client subscribed to `event` (live inspect streams). */
|
|
30
|
+
broadcast(event: string, data: unknown): void;
|
|
31
|
+
peerCount(): number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
interface Peer {
|
|
35
|
+
pc: RTCPeerConnection;
|
|
36
|
+
dc: RTCDataChannel | null;
|
|
37
|
+
origin: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface Sub {
|
|
41
|
+
dc: RTCDataChannel;
|
|
42
|
+
event: string;
|
|
43
|
+
id: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function rec(d: unknown): Record<string, unknown> {
|
|
47
|
+
return (d ?? {}) as Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function createProxyHost(opts: ProxyHostOpts): ProxyHost {
|
|
51
|
+
const rtcFactory = opts.rtcFactory ?? ((cfg: RTCConfiguration) => new RTCPeerConnection(cfg));
|
|
52
|
+
const peers = new Map<string, Peer>(); // keyed by client deviceId (`from`)
|
|
53
|
+
const subs = new Set<Sub>();
|
|
54
|
+
const offs: (() => void)[] = [];
|
|
55
|
+
|
|
56
|
+
async function onOffer(d: Record<string, unknown>): Promise<void> {
|
|
57
|
+
const from = String(d['from'] ?? '');
|
|
58
|
+
if (!from) return;
|
|
59
|
+
const sdp = String(d['sdp'] ?? '');
|
|
60
|
+
const origin = String(d['origin'] ?? '');
|
|
61
|
+
if (opts.signer) {
|
|
62
|
+
const ok = await opts.signer.verify('client', parseFingerprint(sdp) ?? '', String(d['fpTag'] ?? ''));
|
|
63
|
+
if (!ok) {
|
|
64
|
+
opts.socket.emit('rtc:error', { to: from, reason: 'fingerprint-auth-failed' });
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
peers.get(from)?.pc.close();
|
|
70
|
+
} catch {
|
|
71
|
+
/* noop */
|
|
72
|
+
}
|
|
73
|
+
const pc = rtcFactory({ iceServers: opts.iceServers ?? [] });
|
|
74
|
+
const peer: Peer = { pc, dc: null, origin };
|
|
75
|
+
peers.set(from, peer);
|
|
76
|
+
|
|
77
|
+
pc.onicecandidate = (e) => {
|
|
78
|
+
if (e.candidate) opts.socket.emit('rtc:ice', { to: from, candidate: e.candidate.toJSON() });
|
|
79
|
+
};
|
|
80
|
+
pc.ondatachannel = (e) => {
|
|
81
|
+
peer.dc = e.channel;
|
|
82
|
+
e.channel.onmessage = (m: MessageEvent) => void onFrame(peer, e.channel, m.data);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
await pc.setRemoteDescription({ type: 'offer', sdp });
|
|
86
|
+
const answer = await pc.createAnswer();
|
|
87
|
+
await pc.setLocalDescription(answer);
|
|
88
|
+
const answerSdp = pc.localDescription?.sdp ?? answer.sdp ?? '';
|
|
89
|
+
const tag = opts.signer ? await opts.signer.sign('host', parseFingerprint(answerSdp) ?? '') : undefined;
|
|
90
|
+
opts.socket.emit('rtc:answer', { to: from, sdp: answerSdp, fpTag: tag });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function onIce(d: Record<string, unknown>): Promise<void> {
|
|
94
|
+
const peer = peers.get(String(d['from'] ?? ''));
|
|
95
|
+
if (!peer) return;
|
|
96
|
+
try {
|
|
97
|
+
await peer.pc.addIceCandidate(d['candidate'] as RTCIceCandidateInit);
|
|
98
|
+
} catch {
|
|
99
|
+
/* benign — candidate races */
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function onFrame(peer: Peer, dc: RTCDataChannel, raw: unknown): Promise<void> {
|
|
104
|
+
let f: { t?: string; id?: string; channel?: string; payload?: unknown };
|
|
105
|
+
try {
|
|
106
|
+
f = JSON.parse(typeof raw === 'string' ? raw : new TextDecoder().decode(raw as ArrayBuffer));
|
|
107
|
+
} catch {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (f.t === 'req' && f.id !== undefined) {
|
|
111
|
+
try {
|
|
112
|
+
const result = await opts.onInvoke(String(f.channel), f.payload, peer.origin);
|
|
113
|
+
send(dc, { t: 'res', id: f.id, ok: true, result });
|
|
114
|
+
} catch (err) {
|
|
115
|
+
send(dc, { t: 'res', id: f.id, ok: false, error: String((err as Error)?.message ?? err) });
|
|
116
|
+
}
|
|
117
|
+
} else if (f.t === 'sub' && f.id !== undefined) {
|
|
118
|
+
// Register the live subscription; broadcast() fans matching events out.
|
|
119
|
+
// Snapshot is null — the client's panels also pull the current buffer via req.
|
|
120
|
+
subs.add({ dc, event: String(f.channel ?? ''), id: f.id });
|
|
121
|
+
send(dc, { t: 'res', id: f.id, ok: true, result: { snapshot: null } });
|
|
122
|
+
} else if (f.t === 'unsub' && f.id !== undefined) {
|
|
123
|
+
for (const s of [...subs]) if (s.dc === dc && s.id === f.id) subs.delete(s);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function send(dc: RTCDataChannel, frame: object): void {
|
|
128
|
+
try {
|
|
129
|
+
if (dc.readyState === 'open') dc.send(JSON.stringify(frame));
|
|
130
|
+
} catch {
|
|
131
|
+
/* channel gone */
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
offs.push(opts.socket.on('rtc:offer', (d) => void onOffer(rec(d))));
|
|
136
|
+
offs.push(opts.socket.on('rtc:ice', (d) => void onIce(rec(d))));
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
stop(): void {
|
|
140
|
+
for (const off of offs) {
|
|
141
|
+
try {
|
|
142
|
+
off();
|
|
143
|
+
} catch {
|
|
144
|
+
/* noop */
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
for (const peer of peers.values()) {
|
|
148
|
+
try {
|
|
149
|
+
peer.pc.close();
|
|
150
|
+
} catch {
|
|
151
|
+
/* noop */
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
peers.clear();
|
|
155
|
+
subs.clear();
|
|
156
|
+
},
|
|
157
|
+
broadcast(event: string, data: unknown): void {
|
|
158
|
+
for (const s of subs) if (s.event === event) send(s.dc, { t: 'evt', event, data });
|
|
159
|
+
},
|
|
160
|
+
peerCount: () => peers.size,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -10,15 +10,23 @@ export function magicLinkEmail(
|
|
|
10
10
|
url: string,
|
|
11
11
|
appName: string,
|
|
12
12
|
expiresMin: number,
|
|
13
|
+
iconUrl?: string,
|
|
13
14
|
): { subject: string; html: string; text: string } {
|
|
14
15
|
const safeAppName = escapeHtml(appName);
|
|
16
|
+
// Only honour absolute https icons — mail clients won't load anything else,
|
|
17
|
+
// and it keeps a hostile relative/`javascript:` value out of the markup.
|
|
18
|
+
const iconImg =
|
|
19
|
+
iconUrl && /^https:\/\//i.test(iconUrl)
|
|
20
|
+
? `<img src="${escapeHtml(iconUrl)}" alt="" width="56" height="56" style="border-radius:12px;display:block;margin:0 auto 16px">`
|
|
21
|
+
: '';
|
|
15
22
|
return {
|
|
16
23
|
subject: `Sign in to ${appName}`,
|
|
17
|
-
html: `<!doctype html><html><body style="font-family:system-ui,sans-serif;padding:24px;max-width:480px;margin:auto">
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
<p
|
|
21
|
-
<p style="color:#
|
|
24
|
+
html: `<!doctype html><html><body style="font-family:system-ui,sans-serif;padding:24px;max-width:480px;margin:auto;text-align:center">
|
|
25
|
+
${iconImg}
|
|
26
|
+
<h2 style="margin:0 0 12px">Sign in to ${safeAppName}</h2>
|
|
27
|
+
<p style="text-align:left">Click the button below to sign in. This link expires in ${expiresMin} minutes and can only be used once.</p>
|
|
28
|
+
<p><a href="${url}" style="background:#000;color:#fff;padding:12px 24px;text-decoration:none;border-radius:6px;display:inline-block">Sign in to ${safeAppName}</a></p>
|
|
29
|
+
<p style="color:#888;font-size:12px;text-align:left">If you didn't request this, you can safely ignore this email.</p>
|
|
22
30
|
</body></html>`,
|
|
23
31
|
text: `Sign in to ${appName}: ${url}\n\nThis link expires in ${expiresMin} minutes.`,
|
|
24
32
|
};
|
|
@@ -38,6 +38,14 @@ const requestBodySchema = z.object({
|
|
|
38
38
|
* `window.location.href` so the user resumes wherever they were.
|
|
39
39
|
*/
|
|
40
40
|
returnTo: z.string().max(2000).optional(),
|
|
41
|
+
/**
|
|
42
|
+
* Optional per-request branding for the email (subject/heading + icon).
|
|
43
|
+
* Used by a central login authority (e.g. ugly.bot) to brand the sign-in
|
|
44
|
+
* email with the CHILD app that triggered the login, rather than the
|
|
45
|
+
* authority's own name. Falls back to the registration-time `appName`.
|
|
46
|
+
*/
|
|
47
|
+
appName: z.string().max(120).optional(),
|
|
48
|
+
iconUrl: z.string().url().max(2000).optional(),
|
|
41
49
|
});
|
|
42
50
|
|
|
43
51
|
const verifyBodySchema = z.object({
|
|
@@ -292,7 +300,14 @@ export function registerWorkersMagicLinkRoutes(
|
|
|
292
300
|
);
|
|
293
301
|
}
|
|
294
302
|
|
|
295
|
-
|
|
303
|
+
// Per-request branding (the app that triggered the login) overrides the
|
|
304
|
+
// registration-time default; icon is honoured only if absolute https.
|
|
305
|
+
const reqAppName = parsed.data.appName?.trim() || appName;
|
|
306
|
+
const reqIconUrl =
|
|
307
|
+
parsed.data.iconUrl && /^https:\/\//i.test(parsed.data.iconUrl)
|
|
308
|
+
? parsed.data.iconUrl
|
|
309
|
+
: undefined;
|
|
310
|
+
const tpl = magicLinkEmail(url, reqAppName, expiresMin, reqIconUrl);
|
|
296
311
|
let emailError: unknown = null;
|
|
297
312
|
try {
|
|
298
313
|
await emailSend({
|