@botiverse/porthole 0.1.7 → 0.2.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.
Files changed (59) hide show
  1. package/dist/conformance/clipboard.js +5 -2
  2. package/dist/conformance/entry.d.ts +37 -0
  3. package/dist/conformance/entry.js +120 -0
  4. package/dist/conformance/harness/page.d.ts +32 -0
  5. package/dist/conformance/harness/page.js +215 -0
  6. package/dist/conformance/harness.js +1662 -0
  7. package/dist/conformance/host-kit.d.ts +85 -0
  8. package/dist/conformance/host-kit.js +341 -0
  9. package/dist/conformance/index.d.ts +2 -0
  10. package/dist/conformance/index.js +4 -0
  11. package/dist/conformance/limits.js +16 -1
  12. package/dist/conformance/served.js +13 -3
  13. package/dist/guide/limits.js +9 -1
  14. package/dist/host/locator.d.ts +39 -0
  15. package/dist/host/locator.js +72 -0
  16. package/dist/host/outcome.js +1 -0
  17. package/dist/host/types.d.ts +2 -0
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.js +1 -0
  20. package/dist/node/index.d.ts +41 -0
  21. package/dist/node/index.js +160 -0
  22. package/dist/platform/web.js +12 -1
  23. package/dist/server/domain.d.ts +43 -0
  24. package/dist/server/domain.js +100 -0
  25. package/dist/server/host.d.ts +158 -0
  26. package/dist/server/host.js +416 -0
  27. package/dist/server/index.d.ts +9 -2
  28. package/dist/server/index.js +7 -0
  29. package/dist/server/naming.d.ts +12 -1
  30. package/dist/server/naming.js +9 -8
  31. package/dist/server/pages.d.ts +9 -0
  32. package/dist/server/pages.js +32 -0
  33. package/dist/server/server.js +287 -50
  34. package/dist/server/types.d.ts +37 -0
  35. package/dist/transport/post-message.d.ts +9 -1
  36. package/dist/transport/post-message.js +11 -2
  37. package/package.json +6 -2
  38. package/src/conformance/clipboard.ts +5 -2
  39. package/src/conformance/entry.ts +206 -0
  40. package/src/conformance/harness/page.ts +267 -0
  41. package/src/conformance/host-kit.ts +466 -0
  42. package/src/conformance/index.ts +12 -0
  43. package/src/conformance/limits.ts +21 -1
  44. package/src/conformance/served.ts +14 -3
  45. package/src/guide/limits.ts +9 -1
  46. package/src/host/locator.ts +111 -0
  47. package/src/host/outcome.ts +1 -0
  48. package/src/host/types.ts +2 -0
  49. package/src/index.ts +7 -0
  50. package/src/node/index.ts +221 -0
  51. package/src/platform/web.ts +19 -1
  52. package/src/server/domain.ts +158 -0
  53. package/src/server/host.ts +706 -0
  54. package/src/server/index.ts +27 -1
  55. package/src/server/naming.ts +22 -2
  56. package/src/server/pages.ts +44 -0
  57. package/src/server/server.ts +355 -63
  58. package/src/server/types.ts +33 -0
  59. package/src/transport/post-message.ts +12 -1
@@ -72,6 +72,11 @@ export interface TicketRecord {
72
72
  readonly expiresAt: number;
73
73
  /** The grant's `sessionSeconds`, if it set one. */
74
74
  readonly sessionSeconds?: number;
75
+ /**
76
+ * An entry code's (P068): the clean path it returns to, and the nonce of the browser that asked
77
+ * (its cookie must come with the code). A ticket from `issue` has none.
78
+ */
79
+ readonly entry?: { readonly path: string; readonly nonce: string };
75
80
  }
76
81
 
77
82
  /** Where tickets live between `issue` and their one use. Default: in memory (one process). */
@@ -158,6 +163,25 @@ export interface ServerOptions {
158
163
  readonly upstream?: Upstream;
159
164
  /** The host's per-request check (P050). Absent: a good cookie is enough until it ends. */
160
165
  readonly authorize?: Authorizer;
166
+ /**
167
+ * Redirect entry (P068): a request on a clean address (`urlOf`) without a cookie for it is sent
168
+ * to the host's authorize route, on a host origin, which decides and sends it back with a
169
+ * one-time code (`enterBy`). Absent: a clean address without a cookie is refused, as before.
170
+ */
171
+ readonly entry?: { readonly authorizeUrl: string };
172
+ }
173
+
174
+ /** A redirect entry's state, as the host's authorize route reads it (`PortholeServer.entryState`). */
175
+ export interface EntryState {
176
+ /** The label the clean address is on. */
177
+ readonly label: string;
178
+ /** The path (and query) it asked for. */
179
+ readonly path: string;
180
+ /** Whether it was asked from a frame. */
181
+ readonly framed: boolean;
182
+ /** Older than five minutes: start again from the clean address. */
183
+ readonly expired: boolean;
184
+ readonly nonce: string;
161
185
  }
162
186
 
163
187
  export interface PortholeServer {
@@ -181,4 +205,13 @@ export interface PortholeServer {
181
205
  access(request: Request): Promise<Access | null>;
182
206
  /** The frame source every content origin matches (`https://*.example-usercontent.com`). */
183
207
  readonly contentSource: string;
208
+ /** A clean address on a scope's origin (P068): what a tab, a link, a bookmark opens. */
209
+ urlOf(scope: string, path?: string): string;
210
+ /** A redirect entry's state, signature checked; null for one this server didn't make. */
211
+ entryState(token: string): EntryState | null;
212
+ /**
213
+ * Once the host decided (its authorize route): a one-time code for `instance`, which must be
214
+ * served on the state's label, and the URL that redeems it there (`/__porthole/entry`).
215
+ */
216
+ enterBy(state: EntryState, instance: InstanceRef, grant: Grant): Promise<string>;
184
217
  }
@@ -12,12 +12,23 @@ export function postMessageTransport(
12
12
  frameWindow: () => Window | null,
13
13
  expectedOrigin: string,
14
14
  host: Window = window,
15
+ /**
16
+ * Another origin the frame's window may say some things from: the host's own, whose pages a
17
+ * served frame passes through on a redirect entry (P068), for their frame status only.
18
+ */
19
+ also?: { readonly origin: string; readonly accept: (data: unknown) => boolean },
15
20
  ): Transport {
16
21
  const listeners = new Set<(message: unknown) => void>();
17
22
  let closed = false;
18
23
  const onMessage = (event: MessageEvent) => {
19
24
  const source = frameWindow();
20
- if (closed || source === null || event.source !== source || event.origin !== expectedOrigin) {
25
+ if (closed || source === null || event.source !== source) {
26
+ return;
27
+ }
28
+ if (
29
+ event.origin !== expectedOrigin &&
30
+ (also === undefined || event.origin !== also.origin || !also.accept(event.data))
31
+ ) {
21
32
  return;
22
33
  }
23
34
  for (const listener of listeners) {