@floegence/flowersec-core 2.3.6 → 2.3.7

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 (58) hide show
  1. package/README.md +31 -42
  2. package/THIRD_PARTY_NOTICES.md +4 -79
  3. package/dist/cli.js +31 -31
  4. package/dist/connector/adapters/rawQuicCandidate.d.ts +5 -0
  5. package/dist/connector/adapters/rawQuicCandidate.js +71 -0
  6. package/dist/connector/sessionAcceptor.d.ts +22 -2
  7. package/dist/connector/sessionAcceptor.js +51 -21
  8. package/dist/connector/sessionConnector.d.ts +2 -0
  9. package/dist/connector/sessionConnector.js +4 -1
  10. package/dist/interop/proxyServerPeer.d.ts +1 -0
  11. package/dist/interop/proxyServerPeer.js +83 -0
  12. package/dist/interop/serverParityPeer.d.ts +1 -0
  13. package/dist/interop/serverParityPeer.js +608 -0
  14. package/dist/node/acceptor.d.ts +31 -19
  15. package/dist/node/acceptor.js +353 -72
  16. package/dist/node/connectSession.d.ts +2 -1
  17. package/dist/node/connectSession.js +22 -12
  18. package/dist/node/controlplane.d.ts +137 -0
  19. package/dist/node/controlplane.js +439 -0
  20. package/dist/node/index.d.ts +8 -2
  21. package/dist/node/index.js +4 -1
  22. package/dist/node/nativeTransportAddon.d.ts +94 -0
  23. package/dist/node/nativeTransportAddon.js +166 -0
  24. package/dist/node/proxyServer.d.ts +31 -0
  25. package/dist/node/proxyServer.js +572 -0
  26. package/dist/node/rawQuicAdapter.d.ts +9 -0
  27. package/dist/node/rawQuicAdapter.js +107 -0
  28. package/dist/node/rawQuicServer.d.ts +24 -0
  29. package/dist/node/rawQuicServer.js +37 -0
  30. package/dist/node/runtimeCapability.d.ts +8 -1
  31. package/dist/node/runtimeCapability.js +20 -6
  32. package/dist/node/tunnelRuntime.d.ts +42 -0
  33. package/dist/node/tunnelRuntime.js +552 -0
  34. package/dist/node/webSocketServer.d.ts +24 -0
  35. package/dist/node/webSocketServer.js +135 -0
  36. package/dist/public/contract.d.ts +4 -3
  37. package/dist/transport/webSocketAdapter.d.ts +7 -0
  38. package/dist/transport/webSocketAdapter.js +136 -0
  39. package/dist/v2/artifact.js +1 -1
  40. package/dist/v2/capability.js +1 -1
  41. package/dist/v2/carrier.d.ts +4 -1
  42. package/dist/v2/carrier.js +2 -2
  43. package/dist/v2/handshake.js +7 -7
  44. package/dist/v2/protocol.js +5 -5
  45. package/dist/v2/publicSession.js +25 -7
  46. package/dist/v2/session.d.ts +2 -2
  47. package/dist/v2/session.js +3 -3
  48. package/dist/v2/unreliableMessage.js +4 -4
  49. package/dist/vendor/tr46.js +11 -6
  50. package/dist/ws-client/binaryTransport.d.ts +3 -0
  51. package/dist/ws-client/binaryTransport.js +14 -0
  52. package/package.json +19 -16
  53. package/sbom/cyclonedx.json +52 -2585
  54. package/sbom/spdx.json +56 -1826
  55. package/dist/node/webTransportClient.d.ts +0 -9
  56. package/dist/node/webTransportClient.js +0 -56
  57. package/dist/node/webTransportServer.d.ts +0 -22
  58. package/dist/node/webTransportServer.js +0 -100
@@ -0,0 +1,94 @@
1
+ import { type NativeCarrierSessionV2 } from "../v2/carrier.js";
2
+ import type { PathKind } from "../v2/contract.js";
3
+ export declare const NATIVE_TRANSPORT_CONTRACT_VERSION = 1;
4
+ export type NativeRawQuicConnectOptions = Readonly<{
5
+ host: string;
6
+ port: number;
7
+ serverName: string;
8
+ path: PathKind;
9
+ trustRootsDer: readonly Uint8Array[];
10
+ inboundBidirectionalStreamCapacity: number;
11
+ handshakeTimeoutMs: number;
12
+ }>;
13
+ export type NativeRawQuicBindOptions = Readonly<{
14
+ host: string;
15
+ port: number;
16
+ path: PathKind;
17
+ certificateChainDer: readonly Uint8Array[];
18
+ privateKeyDer: Uint8Array;
19
+ inboundBidirectionalStreamCapacity: number;
20
+ handshakeTimeoutMs?: number;
21
+ }>;
22
+ export type NativeRawQuicListener = Readonly<{
23
+ address(): Readonly<{
24
+ host: string;
25
+ port: number;
26
+ }>;
27
+ accept(options?: Readonly<{
28
+ signal?: AbortSignal;
29
+ }>): Promise<NativeCarrierSessionV2>;
30
+ close(): Promise<void>;
31
+ }>;
32
+ export type NativeRawQuicDriver = Readonly<{
33
+ connectRawQuic(options: NativeRawQuicConnectOptions, operation?: Readonly<{
34
+ signal?: AbortSignal;
35
+ }>): Promise<NativeCarrierSessionV2>;
36
+ bindRawQuic(options: NativeRawQuicBindOptions): Promise<NativeRawQuicListener>;
37
+ }>;
38
+ type NativeOperation<T> = Readonly<{
39
+ result(): Promise<T>;
40
+ cancel(): void;
41
+ }>;
42
+ type NativeRawQuicStreamBinding = Readonly<{
43
+ read(): Promise<Uint8Array | null>;
44
+ write(data: Uint8Array): Promise<number>;
45
+ closeWrite(): Promise<void>;
46
+ stopSending(): Promise<void>;
47
+ reset(): Promise<void>;
48
+ abort(): void;
49
+ }>;
50
+ type NativeRawQuicSessionBinding = Readonly<{
51
+ kind: "raw_quic";
52
+ path: PathKind;
53
+ inboundBidirectionalStreamCapacity: number;
54
+ maxDatagramSize?: number;
55
+ localAddress(): Readonly<{
56
+ host: string;
57
+ port: number;
58
+ }>;
59
+ peerAddress(): Readonly<{
60
+ host: string;
61
+ port: number;
62
+ }>;
63
+ openStream(): NativeOperation<NativeRawQuicStreamBinding>;
64
+ acceptStream(): NativeOperation<NativeRawQuicStreamBinding>;
65
+ sendDatagram(data: Uint8Array): "accepted" | "dropped_budget" | "dropped_carrier" | "too_large" | "unavailable";
66
+ receiveDatagram(): NativeOperation<Uint8Array>;
67
+ waitTermination(): Promise<void>;
68
+ close(code?: number, reason?: string): Promise<void>;
69
+ abort(): void;
70
+ }>;
71
+ type NativeRawQuicListenerBinding = Readonly<{
72
+ address(): Readonly<{
73
+ host: string;
74
+ port: number;
75
+ }>;
76
+ accept(): NativeOperation<NativeRawQuicSessionBinding>;
77
+ close(): Promise<void>;
78
+ abort(): void;
79
+ }>;
80
+ export type NativeTransportAddonBinding = Readonly<{
81
+ contractVersion(): number;
82
+ connectRawQuic(options: NativeRawQuicConnectOptions): NativeOperation<NativeRawQuicSessionBinding>;
83
+ bindRawQuic(options: NativeRawQuicBindOptions): Promise<NativeRawQuicListenerBinding>;
84
+ }>;
85
+ export type NativeTransportAddon = NativeTransportAddonBinding;
86
+ export declare class NativeTransportUnavailableError extends Error {
87
+ readonly code = "native_transport_unavailable";
88
+ constructor();
89
+ }
90
+ type RequireFunction = (specifier: string) => unknown;
91
+ export declare function loadNativeTransportAddon(requireFunction?: RequireFunction): NativeTransportAddonBinding;
92
+ export declare function tryLoadNativeTransportAddon(requireFunction?: RequireFunction): NativeTransportAddonBinding | undefined;
93
+ export declare function createNativeRawQuicDriver(addon?: NativeTransportAddonBinding): NativeRawQuicDriver;
94
+ export {};
@@ -0,0 +1,166 @@
1
+ import { createRequire } from "node:module";
2
+ import { CarrierError, } from "../v2/carrier.js";
3
+ export const NATIVE_TRANSPORT_CONTRACT_VERSION = 1;
4
+ const NATIVE_PACKAGE = "@floegence/flowersec-node-native";
5
+ export class NativeTransportUnavailableError extends Error {
6
+ code = "native_transport_unavailable";
7
+ constructor() {
8
+ super("Flowersec native transport is unavailable on this platform");
9
+ this.name = "NativeTransportUnavailableError";
10
+ }
11
+ }
12
+ export function loadNativeTransportAddon(requireFunction = createRequire(import.meta.url)) {
13
+ let candidate;
14
+ try {
15
+ candidate = requireFunction(NATIVE_PACKAGE);
16
+ }
17
+ catch {
18
+ throw new NativeTransportUnavailableError();
19
+ }
20
+ if (!isNativeTransportAddon(candidate)) {
21
+ throw new NativeTransportUnavailableError();
22
+ }
23
+ return candidate;
24
+ }
25
+ export function tryLoadNativeTransportAddon(requireFunction = createRequire(import.meta.url)) {
26
+ try {
27
+ return loadNativeTransportAddon(requireFunction);
28
+ }
29
+ catch (error) {
30
+ if (error instanceof NativeTransportUnavailableError)
31
+ return undefined;
32
+ throw error;
33
+ }
34
+ }
35
+ export function createNativeRawQuicDriver(addon = loadNativeTransportAddon()) {
36
+ return Object.freeze({
37
+ async connectRawQuic(options, operation = {}) {
38
+ const native = await settle(addon.connectRawQuic(options), operation.signal);
39
+ return wrapSession(native);
40
+ },
41
+ async bindRawQuic(options) {
42
+ const native = await addon.bindRawQuic(options);
43
+ return Object.freeze({
44
+ address: () => native.address(),
45
+ accept: async (operation = {}) => wrapSession(await settle(native.accept(), operation.signal)),
46
+ async close() {
47
+ await native.close();
48
+ },
49
+ });
50
+ },
51
+ });
52
+ }
53
+ function isNativeTransportAddon(value) {
54
+ if (typeof value !== "object" || value === null)
55
+ return false;
56
+ const candidate = value;
57
+ let contractVersion;
58
+ try {
59
+ contractVersion = typeof candidate.contractVersion === "function"
60
+ ? candidate.contractVersion()
61
+ : -1;
62
+ }
63
+ catch {
64
+ return false;
65
+ }
66
+ return contractVersion === NATIVE_TRANSPORT_CONTRACT_VERSION &&
67
+ typeof candidate.connectRawQuic === "function" &&
68
+ typeof candidate.bindRawQuic === "function";
69
+ }
70
+ function wrapSession(native) {
71
+ const unreliableDatagrams = native.maxDatagramSize === undefined
72
+ ? undefined
73
+ : Object.freeze({
74
+ maxDatagramSize: native.maxDatagramSize,
75
+ async send(data, options = {}) {
76
+ throwIfAborted(options.signal);
77
+ if (options.expiresAt !== undefined && options.expiresAt <= Date.now()) {
78
+ return "dropped_expired";
79
+ }
80
+ const outcome = native.sendDatagram(data);
81
+ switch (outcome) {
82
+ case "accepted":
83
+ case "dropped_budget":
84
+ case "dropped_carrier":
85
+ return outcome;
86
+ case "too_large":
87
+ throw new CarrierError("datagram_unavailable", "raw QUIC datagram exceeds the negotiated payload limit");
88
+ case "unavailable":
89
+ throw new CarrierError("datagram_unavailable", "raw QUIC datagrams are unavailable");
90
+ }
91
+ },
92
+ async receive(options = {}) {
93
+ return await settle(native.receiveDatagram(), options.signal);
94
+ },
95
+ });
96
+ return Object.freeze({
97
+ kind: native.kind,
98
+ path: native.path,
99
+ inboundBidirectionalStreamCapacity: native.inboundBidirectionalStreamCapacity,
100
+ ...(unreliableDatagrams === undefined ? {} : { unreliableDatagrams }),
101
+ async openStream(options = {}) {
102
+ return wrapStream(await settle(native.openStream(), options.signal));
103
+ },
104
+ async acceptStream(options = {}) {
105
+ return wrapStream(await settle(native.acceptStream(), options.signal));
106
+ },
107
+ async waitTermination() {
108
+ await native.waitTermination();
109
+ },
110
+ async close(error) {
111
+ await native.close(error?.code, error?.reason);
112
+ },
113
+ abort() {
114
+ native.abort();
115
+ },
116
+ });
117
+ }
118
+ function wrapStream(native) {
119
+ return Object.freeze({
120
+ read: async () => await native.read(),
121
+ write: async (data) => await native.write(data),
122
+ closeWrite: async () => await native.closeWrite(),
123
+ stopSending: async () => await native.stopSending(),
124
+ reset: async () => await native.reset(),
125
+ abort: () => native.abort(),
126
+ });
127
+ }
128
+ async function settle(operation, signal) {
129
+ if (signal?.aborted === true) {
130
+ operation.cancel();
131
+ throw new CarrierError("aborted", "native transport operation aborted");
132
+ }
133
+ if (signal === undefined)
134
+ return await operation.result();
135
+ return await new Promise((resolve, reject) => {
136
+ let settled = false;
137
+ const cleanup = () => signal.removeEventListener("abort", abort);
138
+ const abort = () => {
139
+ if (settled)
140
+ return;
141
+ settled = true;
142
+ cleanup();
143
+ operation.cancel();
144
+ reject(new CarrierError("aborted", "native transport operation aborted"));
145
+ };
146
+ signal.addEventListener("abort", abort, { once: true });
147
+ void operation.result().then((value) => {
148
+ if (settled)
149
+ return;
150
+ settled = true;
151
+ cleanup();
152
+ resolve(value);
153
+ }, (error) => {
154
+ if (settled)
155
+ return;
156
+ settled = true;
157
+ cleanup();
158
+ reject(error);
159
+ });
160
+ });
161
+ }
162
+ function throwIfAborted(signal) {
163
+ if (signal?.aborted === true) {
164
+ throw new CarrierError("aborted", "native transport operation aborted");
165
+ }
166
+ }
@@ -0,0 +1,31 @@
1
+ import { SessionHandlers } from "./acceptor.js";
2
+ export type ProxyServerOptions = Readonly<{
3
+ upstream: string;
4
+ upstreamOrigin: string;
5
+ allowedUpstreamHosts?: readonly string[];
6
+ allowedOrigins?: readonly string[];
7
+ maxConcurrentStreams?: number;
8
+ maxJsonFrameBytes?: number;
9
+ maxChunkBytes?: number;
10
+ maxBodyBytes?: number;
11
+ maxWebSocketFrameBytes?: number;
12
+ defaultHTTPRequestTimeoutMs?: number;
13
+ maxHTTPRequestTimeoutMs?: number;
14
+ extraRequestHeaders?: readonly string[];
15
+ extraResponseHeaders?: readonly string[];
16
+ blockedResponseHeaders?: readonly string[];
17
+ extraWebSocketHeaders?: readonly string[];
18
+ forbiddenCookieNames?: readonly string[];
19
+ forbiddenCookieNamePrefixes?: readonly string[];
20
+ onError?: (error: unknown) => void;
21
+ }>;
22
+ export declare class ProxyServerError extends Error {
23
+ readonly code: "invalid_options" | "handler_registration" | "closed";
24
+ constructor(code: "invalid_options" | "handler_registration" | "closed");
25
+ }
26
+ export declare class ProxyServer {
27
+ #private;
28
+ constructor(options: ProxyServerOptions);
29
+ register(handlers: SessionHandlers): void;
30
+ close(): Promise<void>;
31
+ }