openlimiter 0.1.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.
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +30 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +28 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +45 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +355 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +53 -0
- package/dist/config.js.map +1 -0
- package/dist/credentials.d.ts +19 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +21 -0
- package/dist/credentials.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest.d.ts +51 -0
- package/dist/ingest.d.ts.map +1 -0
- package/dist/ingest.js +114 -0
- package/dist/ingest.js.map +1 -0
- package/dist/qr.d.ts +64 -0
- package/dist/qr.d.ts.map +1 -0
- package/dist/qr.js +494 -0
- package/dist/qr.js.map +1 -0
- package/dist/serve.d.ts +137 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +441 -0
- package/dist/serve.js.map +1 -0
- package/package.json +60 -0
package/dist/qr.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qr.js","sourceRoot":"","sources":["../src/qr.ts"],"names":[],"mappings":"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"}
|
package/dist/serve.d.ts
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { type Advice } from "@openlimiter/core";
|
|
2
|
+
/**
|
|
3
|
+
* The local quota server.
|
|
4
|
+
*
|
|
5
|
+
* This is the one place OpenLimiter opens a socket, and it is a listener, never
|
|
6
|
+
* a client. It answers on your own network so a phone in your hand can read the
|
|
7
|
+
* same numbers the statusline shows on the machine that is actually doing the
|
|
8
|
+
* work. Nothing is uploaded, no account exists, and no provider is contacted.
|
|
9
|
+
*
|
|
10
|
+
* It is read only by construction. There is no route that writes, deletes, or
|
|
11
|
+
* mutates anything, and the whole server never touches a credential store, a
|
|
12
|
+
* provider authentication file, or a raw provider payload. The only thing it
|
|
13
|
+
* can say is the bounded set of fields the agent context already carries:
|
|
14
|
+
* provider codes, freshness states, a percentage, and a reset instant.
|
|
15
|
+
*
|
|
16
|
+
* Four gates stand between the socket and that payload:
|
|
17
|
+
*
|
|
18
|
+
* 1. A random token is generated on every start and is required on every
|
|
19
|
+
* route. It lives only in memory, is never written to disk, and is void
|
|
20
|
+
* the moment the command stops.
|
|
21
|
+
* 2. The Host header must be an address literal or localhost, which is what
|
|
22
|
+
* closes a DNS rebinding attack from a page on an attacker's domain.
|
|
23
|
+
* 3. Cross origin requests are refused outright. The page this server hands
|
|
24
|
+
* out is same origin, so nothing legitimate needs a relaxation.
|
|
25
|
+
* 4. Only GET and HEAD are answered. Every other method is refused before
|
|
26
|
+
* the token is even looked at.
|
|
27
|
+
*
|
|
28
|
+
* It is meant for a trusted home or office network. It is not exposed to the
|
|
29
|
+
* internet, it opens no ports on a router, and it should not be reachable from
|
|
30
|
+
* one. Anyone already on your network who also has the token can read your
|
|
31
|
+
* quota state, which is the whole point and also the whole risk.
|
|
32
|
+
*/
|
|
33
|
+
/** Default listening port. Unassigned by IANA, and easy to type. */
|
|
34
|
+
export declare const DEFAULT_SERVE_PORT = 7317;
|
|
35
|
+
/** Default binding. Every interface, so a phone on the same network reaches it. */
|
|
36
|
+
export declare const DEFAULT_SERVE_HOST = "0.0.0.0";
|
|
37
|
+
/** Payload schema version. Bumped only on a breaking shape change. */
|
|
38
|
+
export declare const SERVE_SCHEMA = 1;
|
|
39
|
+
/** Query parameter carrying the token. Short, because it goes in a QR symbol. */
|
|
40
|
+
export declare const TOKEN_PARAMETER = "t";
|
|
41
|
+
/**
|
|
42
|
+
* One provider line, carrying exactly the fields the agent context carries.
|
|
43
|
+
*
|
|
44
|
+
* Nothing else from the snapshot is exposed. No source, no labels, no meter
|
|
45
|
+
* name, and above all nothing that came out of a provider as text.
|
|
46
|
+
*/
|
|
47
|
+
export interface ServedProvider {
|
|
48
|
+
provider: string;
|
|
49
|
+
state: "fresh" | "stale";
|
|
50
|
+
usagePercent: number;
|
|
51
|
+
resetAt: string | null;
|
|
52
|
+
}
|
|
53
|
+
export interface QuotaDocument {
|
|
54
|
+
schema: typeof SERVE_SCHEMA;
|
|
55
|
+
generatedAt: string;
|
|
56
|
+
reason: Advice["reason"];
|
|
57
|
+
providers: readonly ServedProvider[];
|
|
58
|
+
unknown: readonly string[];
|
|
59
|
+
}
|
|
60
|
+
export interface QuotaServerOptions {
|
|
61
|
+
host?: string;
|
|
62
|
+
/** Port to listen on. Zero asks the operating system for a free one. */
|
|
63
|
+
port?: number;
|
|
64
|
+
/** Token to require. One is generated when this is left out. */
|
|
65
|
+
token?: string;
|
|
66
|
+
stateDirectory?: string | undefined;
|
|
67
|
+
now?: () => string;
|
|
68
|
+
}
|
|
69
|
+
export interface QuotaServerHandle {
|
|
70
|
+
readonly host: string;
|
|
71
|
+
readonly port: number;
|
|
72
|
+
readonly token: string;
|
|
73
|
+
/** The address to open on another device, token included. */
|
|
74
|
+
readonly url: string;
|
|
75
|
+
/** The address on this machine, token included. */
|
|
76
|
+
readonly localUrl: string;
|
|
77
|
+
close(): Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The address another device on the same network should open.
|
|
81
|
+
*
|
|
82
|
+
* A bound address of every interface tells a phone nothing, so the first non
|
|
83
|
+
* internal IPv4 address is what gets printed. IPv6 is skipped deliberately: a
|
|
84
|
+
* link local address needs a zone identifier that does not survive a QR symbol.
|
|
85
|
+
*/
|
|
86
|
+
export declare function lanAddress(): string | null;
|
|
87
|
+
/**
|
|
88
|
+
* Decide whether the Host header may be served.
|
|
89
|
+
*
|
|
90
|
+
* A DNS rebinding attack works by pointing a name the attacker controls at an
|
|
91
|
+
* address on your network and letting a page on that name talk to a server
|
|
92
|
+
* there. The name always arrives in the Host header, so refusing every name
|
|
93
|
+
* except localhost closes it. Address literals are accepted because they
|
|
94
|
+
* cannot be rebound.
|
|
95
|
+
*/
|
|
96
|
+
export declare function isAllowedHostHeader(header: string | undefined, boundPort: number): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Build the document served on the quota route.
|
|
99
|
+
*
|
|
100
|
+
* The advice engine in the core does the work, exactly as it does for the
|
|
101
|
+
* statusline and the hook, so a phone can never see a number the agent would
|
|
102
|
+
* not have seen. A cache that cannot be read becomes an empty document with
|
|
103
|
+
* every provider unknown, never a zero and never a cap.
|
|
104
|
+
*/
|
|
105
|
+
export declare function quotaDocument(stateDirectory: string | undefined, now: string): Promise<QuotaDocument>;
|
|
106
|
+
/**
|
|
107
|
+
* The mobile page.
|
|
108
|
+
*
|
|
109
|
+
* One file, no build step, no external request of any kind. It reads the same
|
|
110
|
+
* JSON route a script would, on the same origin, carrying the same token that
|
|
111
|
+
* is already in the address bar. The colours mirror the design tokens on the
|
|
112
|
+
* site, and the whole thing follows the reader's own light or dark setting.
|
|
113
|
+
*/
|
|
114
|
+
export declare function mobilePage(): string;
|
|
115
|
+
/**
|
|
116
|
+
* Start the local quota server.
|
|
117
|
+
*
|
|
118
|
+
* The returned handle carries the port that was actually bound, which matters
|
|
119
|
+
* when port zero was asked for, and closes every connection on shutdown so a
|
|
120
|
+
* caller is never left waiting on a keep alive socket.
|
|
121
|
+
*/
|
|
122
|
+
export declare function startQuotaServer(options?: QuotaServerOptions): Promise<QuotaServerHandle>;
|
|
123
|
+
export interface ServeBannerOptions {
|
|
124
|
+
/** Paint the QR symbol, which a dark themed terminal needs. */
|
|
125
|
+
color?: boolean;
|
|
126
|
+
/** Leave the QR symbol out entirely. */
|
|
127
|
+
withoutQr?: boolean;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The text printed when the server starts.
|
|
131
|
+
*
|
|
132
|
+
* The address is printed before the symbol and again after it, because a
|
|
133
|
+
* terminal that cannot draw the symbol still has to be usable, and because the
|
|
134
|
+
* address is the thing a person types when a camera will not focus.
|
|
135
|
+
*/
|
|
136
|
+
export declare function serveBanner(handle: QuotaServerHandle, options?: ServeBannerOptions): string;
|
|
137
|
+
//# sourceMappingURL=serve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AASA,OAAO,EAML,KAAK,MAAM,EACZ,MAAM,mBAAmB,CAAC;AAG3B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,oEAAoE;AACpE,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,mFAAmF;AACnF,eAAO,MAAM,kBAAkB,YAAY,CAAC;AAE5C,sEAAsE;AACtE,eAAO,MAAM,YAAY,IAAI,CAAC;AAE9B,iFAAiF;AACjF,eAAO,MAAM,eAAe,MAAM,CAAC;AAcnC;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,YAAY,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzB,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IACrC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,6DAA6D;IAC7D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAO1C;AAOD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,SAAS,EAAE,MAAM,GAChB,OAAO,CAkBT;AAaD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,aAAa,CAAC,CAmBxB;AAsDD;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAsHnC;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,iBAAiB,CAAC,CAgH5B;AAED,MAAM,WAAW,kBAAkB;IACjC,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wCAAwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CA6BR"}
|
package/dist/serve.js
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
import { isIP } from "node:net";
|
|
4
|
+
import { networkInterfaces } from "node:os";
|
|
5
|
+
import { PROVIDER_CODES, buildAdvice, canonicalJson, floorFixed, readSnapshotCache } from "@openlimiter/core";
|
|
6
|
+
import { encodeQr, renderQr } from "./qr.js";
|
|
7
|
+
/**
|
|
8
|
+
* The local quota server.
|
|
9
|
+
*
|
|
10
|
+
* This is the one place OpenLimiter opens a socket, and it is a listener, never
|
|
11
|
+
* a client. It answers on your own network so a phone in your hand can read the
|
|
12
|
+
* same numbers the statusline shows on the machine that is actually doing the
|
|
13
|
+
* work. Nothing is uploaded, no account exists, and no provider is contacted.
|
|
14
|
+
*
|
|
15
|
+
* It is read only by construction. There is no route that writes, deletes, or
|
|
16
|
+
* mutates anything, and the whole server never touches a credential store, a
|
|
17
|
+
* provider authentication file, or a raw provider payload. The only thing it
|
|
18
|
+
* can say is the bounded set of fields the agent context already carries:
|
|
19
|
+
* provider codes, freshness states, a percentage, and a reset instant.
|
|
20
|
+
*
|
|
21
|
+
* Four gates stand between the socket and that payload:
|
|
22
|
+
*
|
|
23
|
+
* 1. A random token is generated on every start and is required on every
|
|
24
|
+
* route. It lives only in memory, is never written to disk, and is void
|
|
25
|
+
* the moment the command stops.
|
|
26
|
+
* 2. The Host header must be an address literal or localhost, which is what
|
|
27
|
+
* closes a DNS rebinding attack from a page on an attacker's domain.
|
|
28
|
+
* 3. Cross origin requests are refused outright. The page this server hands
|
|
29
|
+
* out is same origin, so nothing legitimate needs a relaxation.
|
|
30
|
+
* 4. Only GET and HEAD are answered. Every other method is refused before
|
|
31
|
+
* the token is even looked at.
|
|
32
|
+
*
|
|
33
|
+
* It is meant for a trusted home or office network. It is not exposed to the
|
|
34
|
+
* internet, it opens no ports on a router, and it should not be reachable from
|
|
35
|
+
* one. Anyone already on your network who also has the token can read your
|
|
36
|
+
* quota state, which is the whole point and also the whole risk.
|
|
37
|
+
*/
|
|
38
|
+
/** Default listening port. Unassigned by IANA, and easy to type. */
|
|
39
|
+
export const DEFAULT_SERVE_PORT = 7317;
|
|
40
|
+
/** Default binding. Every interface, so a phone on the same network reaches it. */
|
|
41
|
+
export const DEFAULT_SERVE_HOST = "0.0.0.0";
|
|
42
|
+
/** Payload schema version. Bumped only on a breaking shape change. */
|
|
43
|
+
export const SERVE_SCHEMA = 1;
|
|
44
|
+
/** Query parameter carrying the token. Short, because it goes in a QR symbol. */
|
|
45
|
+
export const TOKEN_PARAMETER = "t";
|
|
46
|
+
/** Longest request target this server will look at. */
|
|
47
|
+
const MAX_TARGET_LENGTH = 512;
|
|
48
|
+
/** Bounds on the socket, so a stalled client cannot hold a slot forever. */
|
|
49
|
+
const HEADERS_TIMEOUT_MILLISECONDS = 5_000;
|
|
50
|
+
const REQUEST_TIMEOUT_MILLISECONDS = 10_000;
|
|
51
|
+
const KEEP_ALIVE_TIMEOUT_MILLISECONDS = 5_000;
|
|
52
|
+
const MAX_CONNECTIONS = 32;
|
|
53
|
+
/** Bytes of entropy in the token. */
|
|
54
|
+
const TOKEN_BYTES = 16;
|
|
55
|
+
/**
|
|
56
|
+
* The address another device on the same network should open.
|
|
57
|
+
*
|
|
58
|
+
* A bound address of every interface tells a phone nothing, so the first non
|
|
59
|
+
* internal IPv4 address is what gets printed. IPv6 is skipped deliberately: a
|
|
60
|
+
* link local address needs a zone identifier that does not survive a QR symbol.
|
|
61
|
+
*/
|
|
62
|
+
export function lanAddress() {
|
|
63
|
+
for (const entries of Object.values(networkInterfaces())) {
|
|
64
|
+
for (const entry of entries ?? []) {
|
|
65
|
+
if (entry.family === "IPv4" && !entry.internal)
|
|
66
|
+
return entry.address;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
function authority(host, port) {
|
|
72
|
+
const wrapped = isIP(host) === 6 ? "[" + host + "]" : host;
|
|
73
|
+
return wrapped + ":" + String(port);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Decide whether the Host header may be served.
|
|
77
|
+
*
|
|
78
|
+
* A DNS rebinding attack works by pointing a name the attacker controls at an
|
|
79
|
+
* address on your network and letting a page on that name talk to a server
|
|
80
|
+
* there. The name always arrives in the Host header, so refusing every name
|
|
81
|
+
* except localhost closes it. Address literals are accepted because they
|
|
82
|
+
* cannot be rebound.
|
|
83
|
+
*/
|
|
84
|
+
export function isAllowedHostHeader(header, boundPort) {
|
|
85
|
+
if (header === undefined || header === "")
|
|
86
|
+
return false;
|
|
87
|
+
let parsed;
|
|
88
|
+
try {
|
|
89
|
+
parsed = new URL("http://" + header);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
if (parsed.pathname !== "/" || parsed.search !== "" || parsed.username !== "") {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const port = parsed.port === "" ? 80 : Number(parsed.port);
|
|
98
|
+
if (port !== boundPort)
|
|
99
|
+
return false;
|
|
100
|
+
const hostname = parsed.hostname;
|
|
101
|
+
if (hostname === "localhost")
|
|
102
|
+
return true;
|
|
103
|
+
/* A bracketed IPv6 literal loses its brackets through the URL parser. */
|
|
104
|
+
const literal = hostname.startsWith("[") ? hostname.slice(1, -1) : hostname;
|
|
105
|
+
return isIP(literal) !== 0;
|
|
106
|
+
}
|
|
107
|
+
function constantTimeEquals(left, right) {
|
|
108
|
+
const a = Buffer.from(left, "utf8");
|
|
109
|
+
const b = Buffer.from(right, "utf8");
|
|
110
|
+
if (a.length !== b.length) {
|
|
111
|
+
/* Compare against itself so the work done does not leak the length. */
|
|
112
|
+
timingSafeEqual(a, a);
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
return timingSafeEqual(a, b);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Build the document served on the quota route.
|
|
119
|
+
*
|
|
120
|
+
* The advice engine in the core does the work, exactly as it does for the
|
|
121
|
+
* statusline and the hook, so a phone can never see a number the agent would
|
|
122
|
+
* not have seen. A cache that cannot be read becomes an empty document with
|
|
123
|
+
* every provider unknown, never a zero and never a cap.
|
|
124
|
+
*/
|
|
125
|
+
export async function quotaDocument(stateDirectory, now) {
|
|
126
|
+
const cached = await readSnapshotCache(stateDirectory);
|
|
127
|
+
const advice = buildAdvice(cached.ok ? cached.snapshots : [], now, PROVIDER_CODES);
|
|
128
|
+
return {
|
|
129
|
+
schema: SERVE_SCHEMA,
|
|
130
|
+
generatedAt: now,
|
|
131
|
+
reason: advice.reason,
|
|
132
|
+
providers: advice.providers.map((entry) => ({
|
|
133
|
+
provider: entry.provider,
|
|
134
|
+
state: entry.state,
|
|
135
|
+
usagePercent: Number(floorFixed(entry.usagePercent, 2)),
|
|
136
|
+
resetAt: entry.resetAt
|
|
137
|
+
})),
|
|
138
|
+
unknown: [...advice.unknownProviders]
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function securityHeaders() {
|
|
142
|
+
return {
|
|
143
|
+
"cache-control": "no-store",
|
|
144
|
+
"referrer-policy": "no-referrer",
|
|
145
|
+
"x-content-type-options": "nosniff",
|
|
146
|
+
"x-frame-options": "DENY",
|
|
147
|
+
/* No Access-Control-Allow-Origin is ever sent. The page is same origin. */
|
|
148
|
+
vary: "Origin"
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function sendJson(request, response, status, body) {
|
|
152
|
+
const text = canonicalJson(body);
|
|
153
|
+
response.writeHead(status, {
|
|
154
|
+
...securityHeaders(),
|
|
155
|
+
"content-security-policy": "default-src 'none'",
|
|
156
|
+
"content-type": "application/json; charset=utf-8",
|
|
157
|
+
"content-length": String(Buffer.byteLength(text, "utf8"))
|
|
158
|
+
});
|
|
159
|
+
/* A HEAD response carries the headers of the GET and none of its body. */
|
|
160
|
+
response.end(request.method === "HEAD" ? undefined : text);
|
|
161
|
+
}
|
|
162
|
+
function sendHtml(request, response, status, html) {
|
|
163
|
+
response.writeHead(status, {
|
|
164
|
+
...securityHeaders(),
|
|
165
|
+
"content-security-policy": [
|
|
166
|
+
"default-src 'none'",
|
|
167
|
+
"style-src 'unsafe-inline'",
|
|
168
|
+
"script-src 'unsafe-inline'",
|
|
169
|
+
"connect-src 'self'",
|
|
170
|
+
"base-uri 'none'",
|
|
171
|
+
"form-action 'none'"
|
|
172
|
+
].join("; "),
|
|
173
|
+
"content-type": "text/html; charset=utf-8",
|
|
174
|
+
"content-length": String(Buffer.byteLength(html, "utf8"))
|
|
175
|
+
});
|
|
176
|
+
response.end(request.method === "HEAD" ? undefined : html);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The mobile page.
|
|
180
|
+
*
|
|
181
|
+
* One file, no build step, no external request of any kind. It reads the same
|
|
182
|
+
* JSON route a script would, on the same origin, carrying the same token that
|
|
183
|
+
* is already in the address bar. The colours mirror the design tokens on the
|
|
184
|
+
* site, and the whole thing follows the reader's own light or dark setting.
|
|
185
|
+
*/
|
|
186
|
+
export function mobilePage() {
|
|
187
|
+
return `<!doctype html>
|
|
188
|
+
<html lang="en">
|
|
189
|
+
<head>
|
|
190
|
+
<meta charset="utf-8">
|
|
191
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
192
|
+
<meta name="robots" content="noindex, nofollow">
|
|
193
|
+
<meta name="color-scheme" content="light dark">
|
|
194
|
+
<title>OpenLimiter quota</title>
|
|
195
|
+
<style>
|
|
196
|
+
:root{color-scheme:light dark;--canvas:#fff;--surface:#f6f6f7;--track:#e2e2e6;--hairline:#e5e5e8;--heading:#0d0d0f;--body:#53535c;--muted:#62626c;--accent:#0866ff;--warn:#b45309;--stop:#b42318}
|
|
197
|
+
@media (prefers-color-scheme:dark){:root{--canvas:#0a0a0b;--surface:#121214;--track:#26262b;--hairline:#232327;--heading:#f2f2f3;--body:#adadb6;--muted:#94949e;--accent:#6ba6ff;--warn:#f0b429;--stop:#ff6b6b}}
|
|
198
|
+
*{box-sizing:border-box}
|
|
199
|
+
body{margin:0;padding:20px 16px 48px;background:var(--canvas);color:var(--body);font:15px/1.5 ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif;-webkit-font-smoothing:antialiased}
|
|
200
|
+
main{max-width:520px;margin:0 auto}
|
|
201
|
+
h1{margin:0 0 2px;font-size:19px;font-weight:600;letter-spacing:-.01em;color:var(--heading)}
|
|
202
|
+
.sub{margin:0 0 20px;font:12px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--muted)}
|
|
203
|
+
.state{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--hairline);border-radius:8px;padding:5px 10px;font:11px/1 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);background:var(--surface)}
|
|
204
|
+
.dot{width:7px;height:7px;border-radius:50%;background:var(--accent)}
|
|
205
|
+
.card{border:1px solid var(--hairline);border-radius:14px;background:var(--surface);padding:14px 16px;margin-top:10px}
|
|
206
|
+
.row{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
|
|
207
|
+
.name{font-size:14px;font-weight:600;color:var(--heading);letter-spacing:.01em}
|
|
208
|
+
.pct{font:600 20px/1 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--heading);font-variant-numeric:tabular-nums}
|
|
209
|
+
.bar{margin-top:10px;height:6px;border-radius:999px;background:var(--track);overflow:hidden}
|
|
210
|
+
.fill{height:100%;border-radius:999px;background:var(--accent);transition:width .3s ease}
|
|
211
|
+
.fill.near{background:var(--warn)}
|
|
212
|
+
.fill.at{background:var(--stop)}
|
|
213
|
+
.meta{margin-top:8px;display:flex;gap:10px;flex-wrap:wrap;font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;color:var(--muted)}
|
|
214
|
+
.note{margin-top:22px;font-size:12px;line-height:1.6;color:var(--muted)}
|
|
215
|
+
.err{color:var(--stop)}
|
|
216
|
+
</style>
|
|
217
|
+
</head>
|
|
218
|
+
<body>
|
|
219
|
+
<main>
|
|
220
|
+
<h1>OpenLimiter</h1>
|
|
221
|
+
<p class="sub" id="stamp">Loading quota from this machine.</p>
|
|
222
|
+
<p><span class="state"><span class="dot" id="dot"></span><span id="reason">reading</span></span></p>
|
|
223
|
+
<div id="cards"></div>
|
|
224
|
+
<p class="note" id="unknown"></p>
|
|
225
|
+
<p class="note">
|
|
226
|
+
Served from the machine running OpenLimiter, over your own network. Nothing here
|
|
227
|
+
left that machine, nothing was uploaded, and this page can only read.
|
|
228
|
+
</p>
|
|
229
|
+
</main>
|
|
230
|
+
<script>
|
|
231
|
+
(function(){
|
|
232
|
+
var token = new URLSearchParams(location.search).get(${JSON.stringify(TOKEN_PARAMETER)});
|
|
233
|
+
var cards = document.getElementById("cards");
|
|
234
|
+
var stamp = document.getElementById("stamp");
|
|
235
|
+
var reason = document.getElementById("reason");
|
|
236
|
+
var dot = document.getElementById("dot");
|
|
237
|
+
var unknown = document.getElementById("unknown");
|
|
238
|
+
function tone(value){ return value >= 100 ? "at" : value >= 80 ? "near" : ""; }
|
|
239
|
+
function clock(value){
|
|
240
|
+
if (value === null) return "no reset";
|
|
241
|
+
var when = new Date(value);
|
|
242
|
+
return isNaN(when.getTime()) ? "no reset" : "resets " + when.toLocaleString();
|
|
243
|
+
}
|
|
244
|
+
function draw(document_){
|
|
245
|
+
reason.textContent = document_.reason.toLowerCase().replace("_"," ");
|
|
246
|
+
dot.style.background = document_.reason === "AT_CAP" ? "var(--stop)"
|
|
247
|
+
: document_.reason === "NEAR_CAP" ? "var(--warn)" : "var(--accent)";
|
|
248
|
+
stamp.textContent = "Updated " + new Date(document_.generatedAt).toLocaleTimeString();
|
|
249
|
+
stamp.className = "sub";
|
|
250
|
+
cards.textContent = "";
|
|
251
|
+
document_.providers.forEach(function(entry){
|
|
252
|
+
var card = document.createElement("div");
|
|
253
|
+
card.className = "card";
|
|
254
|
+
var row = document.createElement("div");
|
|
255
|
+
row.className = "row";
|
|
256
|
+
var name = document.createElement("span");
|
|
257
|
+
name.className = "name";
|
|
258
|
+
name.textContent = entry.provider;
|
|
259
|
+
var pct = document.createElement("span");
|
|
260
|
+
pct.className = "pct";
|
|
261
|
+
pct.textContent = entry.usagePercent.toFixed(1) + "%";
|
|
262
|
+
row.appendChild(name); row.appendChild(pct);
|
|
263
|
+
var bar = document.createElement("div");
|
|
264
|
+
bar.className = "bar";
|
|
265
|
+
var fill = document.createElement("div");
|
|
266
|
+
fill.className = "fill " + tone(entry.usagePercent);
|
|
267
|
+
fill.style.width = Math.min(100, Math.max(0, entry.usagePercent)) + "%";
|
|
268
|
+
bar.appendChild(fill);
|
|
269
|
+
var meta = document.createElement("div");
|
|
270
|
+
meta.className = "meta";
|
|
271
|
+
var state = document.createElement("span");
|
|
272
|
+
state.textContent = entry.state;
|
|
273
|
+
var reset = document.createElement("span");
|
|
274
|
+
reset.textContent = clock(entry.resetAt);
|
|
275
|
+
meta.appendChild(state); meta.appendChild(reset);
|
|
276
|
+
card.appendChild(row); card.appendChild(bar); card.appendChild(meta);
|
|
277
|
+
cards.appendChild(card);
|
|
278
|
+
});
|
|
279
|
+
unknown.textContent = document_.unknown.length === 0
|
|
280
|
+
? ""
|
|
281
|
+
: "Unknown, so nothing is claimed for them: " + document_.unknown.join(", ") + ".";
|
|
282
|
+
}
|
|
283
|
+
function load(){
|
|
284
|
+
fetch("/quota.json?${TOKEN_PARAMETER}=" + encodeURIComponent(token || ""), { cache: "no-store" })
|
|
285
|
+
.then(function(response){
|
|
286
|
+
if (!response.ok) throw new Error(String(response.status));
|
|
287
|
+
return response.json();
|
|
288
|
+
})
|
|
289
|
+
.then(draw)
|
|
290
|
+
.catch(function(error){
|
|
291
|
+
stamp.className = "sub err";
|
|
292
|
+
stamp.textContent = error.message === "401"
|
|
293
|
+
? "The token in this address is not valid. Scan the code again."
|
|
294
|
+
: "Cannot reach the machine running OpenLimiter.";
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
load();
|
|
298
|
+
setInterval(load, 15000);
|
|
299
|
+
})();
|
|
300
|
+
</script>
|
|
301
|
+
</body>
|
|
302
|
+
</html>
|
|
303
|
+
`;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Start the local quota server.
|
|
307
|
+
*
|
|
308
|
+
* The returned handle carries the port that was actually bound, which matters
|
|
309
|
+
* when port zero was asked for, and closes every connection on shutdown so a
|
|
310
|
+
* caller is never left waiting on a keep alive socket.
|
|
311
|
+
*/
|
|
312
|
+
export async function startQuotaServer(options = {}) {
|
|
313
|
+
const host = options.host ?? DEFAULT_SERVE_HOST;
|
|
314
|
+
const port = options.port ?? DEFAULT_SERVE_PORT;
|
|
315
|
+
const token = options.token ?? randomBytes(TOKEN_BYTES).toString("base64url");
|
|
316
|
+
const clock = options.now ?? (() => new Date().toISOString());
|
|
317
|
+
const stateDirectory = options.stateDirectory;
|
|
318
|
+
/* Rewritten once the socket is bound, which is what port zero needs. */
|
|
319
|
+
let listeningPort = port;
|
|
320
|
+
async function handle(request, response) {
|
|
321
|
+
const method = request.method ?? "GET";
|
|
322
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
323
|
+
response.writeHead(405, { ...securityHeaders(), allow: "GET, HEAD" });
|
|
324
|
+
response.end();
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const rawTarget = request.url ?? "/";
|
|
328
|
+
if (rawTarget.length > MAX_TARGET_LENGTH) {
|
|
329
|
+
sendJson(request, response, 414, { error: "target_too_long" });
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
if (!isAllowedHostHeader(request.headers.host, listeningPort)) {
|
|
333
|
+
sendJson(request, response, 403, { error: "host_not_allowed" });
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
/* No cross origin caller is ever wanted, so any origin at all is refused. */
|
|
337
|
+
if (typeof request.headers.origin === "string") {
|
|
338
|
+
sendJson(request, response, 403, { error: "cross_origin_refused" });
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
let target;
|
|
342
|
+
try {
|
|
343
|
+
target = new URL(rawTarget, "http://localhost");
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
sendJson(request, response, 400, { error: "bad_request" });
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
const presented = target.searchParams.get(TOKEN_PARAMETER);
|
|
350
|
+
if (presented === null || !constantTimeEquals(presented, token)) {
|
|
351
|
+
sendJson(request, response, 401, { error: "token_required" });
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (target.pathname === "/") {
|
|
355
|
+
sendHtml(request, response, 200, mobilePage());
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (target.pathname === "/quota.json") {
|
|
359
|
+
sendJson(request, response, 200, await quotaDocument(stateDirectory, clock()));
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
sendJson(request, response, 404, { error: "not_found" });
|
|
363
|
+
}
|
|
364
|
+
const server = createServer((request, response) => {
|
|
365
|
+
/* Nothing here consumes a body. Draining keeps the socket reusable. */
|
|
366
|
+
request.resume();
|
|
367
|
+
handle(request, response).catch(() => {
|
|
368
|
+
if (!response.headersSent) {
|
|
369
|
+
sendJson(request, response, 500, { error: "internal" });
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
response.end();
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
server.headersTimeout = HEADERS_TIMEOUT_MILLISECONDS;
|
|
376
|
+
server.requestTimeout = REQUEST_TIMEOUT_MILLISECONDS;
|
|
377
|
+
server.keepAliveTimeout = KEEP_ALIVE_TIMEOUT_MILLISECONDS;
|
|
378
|
+
server.maxConnections = MAX_CONNECTIONS;
|
|
379
|
+
await new Promise((resolve, reject) => {
|
|
380
|
+
const onError = (error) => {
|
|
381
|
+
server.off("listening", onListening);
|
|
382
|
+
reject(error instanceof Error ? error : new Error("listen failed"));
|
|
383
|
+
};
|
|
384
|
+
const onListening = () => {
|
|
385
|
+
server.off("error", onError);
|
|
386
|
+
const address = server.address();
|
|
387
|
+
if (address !== null && typeof address === "object") {
|
|
388
|
+
listeningPort = address.port;
|
|
389
|
+
}
|
|
390
|
+
resolve();
|
|
391
|
+
};
|
|
392
|
+
server.once("error", onError);
|
|
393
|
+
server.once("listening", onListening);
|
|
394
|
+
server.listen(port, host);
|
|
395
|
+
});
|
|
396
|
+
const query = "/?" + TOKEN_PARAMETER + "=" + token;
|
|
397
|
+
const advertised = host === "0.0.0.0" || host === "::"
|
|
398
|
+
? lanAddress() ?? "127.0.0.1"
|
|
399
|
+
: host;
|
|
400
|
+
return {
|
|
401
|
+
host,
|
|
402
|
+
port: listeningPort,
|
|
403
|
+
token,
|
|
404
|
+
url: "http://" + authority(advertised, listeningPort) + query,
|
|
405
|
+
localUrl: "http://" + authority("127.0.0.1", listeningPort) + query,
|
|
406
|
+
close: async () => {
|
|
407
|
+
await new Promise((resolve) => {
|
|
408
|
+
server.close(() => {
|
|
409
|
+
resolve();
|
|
410
|
+
});
|
|
411
|
+
server.closeAllConnections();
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* The text printed when the server starts.
|
|
418
|
+
*
|
|
419
|
+
* The address is printed before the symbol and again after it, because a
|
|
420
|
+
* terminal that cannot draw the symbol still has to be usable, and because the
|
|
421
|
+
* address is the thing a person types when a camera will not focus.
|
|
422
|
+
*/
|
|
423
|
+
export function serveBanner(handle, options = {}) {
|
|
424
|
+
const lines = [
|
|
425
|
+
"OpenLimiter is serving read only quota on your local network.",
|
|
426
|
+
"",
|
|
427
|
+
" " + handle.url,
|
|
428
|
+
""
|
|
429
|
+
];
|
|
430
|
+
if (options.withoutQr !== true) {
|
|
431
|
+
try {
|
|
432
|
+
lines.push(renderQr(encodeQr(handle.url), { color: options.color ?? false }), "");
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
lines.push("The address is too long to draw as a scannable code.", "");
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
lines.push("On this machine: " + handle.localUrl, "", "Scan the code with a phone on the same network, or type the address.", "The token changes every time this command starts, and nothing answers without it.", "Read only: no route here can change anything on this machine, and no", "credential, provider payload, or account detail is ever served.", "Meant for a trusted home or office network. Do not expose this port to the internet.", "", "Press Ctrl C to stop.");
|
|
439
|
+
return lines.join("\n");
|
|
440
|
+
}
|
|
441
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
|