@tapflowio/relay 0.8.1-next.0 → 0.8.2
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/RelayServer.d.ts +4 -0
- package/dist/RelayServer.d.ts.map +1 -1
- package/dist/RelayServer.js +62 -17
- package/dist/RelayServer.js.map +1 -1
- package/dist/api/auth.d.ts +3 -2
- package/dist/api/auth.d.ts.map +1 -1
- package/dist/api/auth.js +37 -3
- package/dist/api/auth.js.map +1 -1
- package/dist/api/tokens.d.ts.map +1 -1
- package/dist/api/tokens.js +12 -1
- package/dist/api/tokens.js.map +1 -1
- package/dist/lib/clientAddress.d.ts +12 -0
- package/dist/lib/clientAddress.d.ts.map +1 -0
- package/dist/lib/clientAddress.js +46 -0
- package/dist/lib/clientAddress.js.map +1 -0
- package/dist/lib/config.d.ts +3 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +30 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/connectionAuth.d.ts +22 -0
- package/dist/lib/connectionAuth.d.ts.map +1 -0
- package/dist/lib/connectionAuth.js +18 -0
- package/dist/lib/connectionAuth.js.map +1 -0
- package/dist/lib/lanAddress.d.ts +3 -0
- package/dist/lib/lanAddress.d.ts.map +1 -0
- package/dist/lib/lanAddress.js +25 -0
- package/dist/lib/lanAddress.js.map +1 -0
- package/dist/middleware/rateLimit.d.ts +18 -0
- package/dist/middleware/rateLimit.d.ts.map +1 -0
- package/dist/middleware/rateLimit.js +55 -0
- package/dist/middleware/rateLimit.js.map +1 -0
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
- package/public/assets/{index-CkqVcM-z.js → index-Bhoumejm.js} +70 -70
- package/public/index.html +1 -1
package/dist/lib/config.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
+
import crypto from 'crypto';
|
|
3
4
|
import { z } from 'zod';
|
|
4
5
|
import { createLogger } from '@tapflowio/agent-core';
|
|
6
|
+
import { parseTrustedProxies } from './clientAddress.js';
|
|
5
7
|
const logger = createLogger('relay:config');
|
|
6
|
-
const DEV_DEFAULT_SECRET = 'tapflow-dev-secret-change-in-production';
|
|
7
8
|
const tunnelSshSchema = z.object({
|
|
8
9
|
host: z.string().min(1),
|
|
9
10
|
user: z.string().min(1),
|
|
@@ -25,6 +26,7 @@ const configSchema = z.object({
|
|
|
25
26
|
port: z.number().int().min(1).max(65535),
|
|
26
27
|
dataDir: z.string().min(1),
|
|
27
28
|
wsBackpressureBytes: z.number().int().min(1),
|
|
29
|
+
trustedProxies: z.array(z.string()),
|
|
28
30
|
}),
|
|
29
31
|
relay: z.object({
|
|
30
32
|
url: z.string().nullable(),
|
|
@@ -44,6 +46,7 @@ const DEFAULTS = {
|
|
|
44
46
|
port: 4000,
|
|
45
47
|
dataDir: '.tapflow-data',
|
|
46
48
|
wsBackpressureBytes: 1_048_576,
|
|
49
|
+
trustedProxies: [],
|
|
47
50
|
},
|
|
48
51
|
relay: {
|
|
49
52
|
url: null,
|
|
@@ -80,6 +83,7 @@ function load() {
|
|
|
80
83
|
port: file.local?.port ?? DEFAULTS.local.port,
|
|
81
84
|
dataDir: resolveDataDir(file.local?.dataDir ?? DEFAULTS.local.dataDir),
|
|
82
85
|
wsBackpressureBytes: DEFAULTS.local.wsBackpressureBytes,
|
|
86
|
+
trustedProxies: parseTrustedProxies(process.env.TAPFLOW_TRUSTED_PROXIES),
|
|
83
87
|
},
|
|
84
88
|
relay: {
|
|
85
89
|
url: file.relay?.url || null,
|
|
@@ -143,6 +147,30 @@ function load() {
|
|
|
143
147
|
}
|
|
144
148
|
return result.data;
|
|
145
149
|
}
|
|
150
|
+
// JWT_SECRET 미설정 시: 공개된 공유 기본값 대신 per-install 시크릿을 생성·영속화한다.
|
|
151
|
+
// dataDir에 0600으로 저장하고 재시작 시 재사용 → 설정 없이도 위조 불가, 온보딩 friction 없음.
|
|
152
|
+
export function loadOrCreatePersistedSecret(dataDir) {
|
|
153
|
+
const secretPath = path.join(dataDir, 'jwt-secret');
|
|
154
|
+
try {
|
|
155
|
+
const existing = fs.readFileSync(secretPath, 'utf-8').trim();
|
|
156
|
+
if (existing.length >= 32)
|
|
157
|
+
return existing;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// not yet created
|
|
161
|
+
}
|
|
162
|
+
const secret = crypto.randomBytes(48).toString('base64url');
|
|
163
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
164
|
+
fs.writeFileSync(secretPath, secret, { mode: 0o600 });
|
|
165
|
+
try {
|
|
166
|
+
fs.chmodSync(secretPath, 0o600);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
// best-effort on platforms without POSIX permissions
|
|
170
|
+
}
|
|
171
|
+
logger.info(`Generated a per-install JWT secret at ${secretPath} (set JWT_SECRET to override)`);
|
|
172
|
+
return secret;
|
|
173
|
+
}
|
|
146
174
|
function loadJwtSecret() {
|
|
147
175
|
if (process.env.JWT_SECRET !== undefined) {
|
|
148
176
|
if (process.env.JWT_SECRET.length < 32) {
|
|
@@ -151,8 +179,7 @@ function loadJwtSecret() {
|
|
|
151
179
|
}
|
|
152
180
|
return process.env.JWT_SECRET;
|
|
153
181
|
}
|
|
154
|
-
|
|
155
|
-
return DEV_DEFAULT_SECRET;
|
|
182
|
+
return loadOrCreatePersistedSecret(config.local.dataDir);
|
|
156
183
|
}
|
|
157
184
|
export const config = load();
|
|
158
185
|
export const jwtSecret = loadJwtSecret();
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAExD,MAAM,MAAM,GAAG,YAAY,CAAC,cAAc,CAAC,CAAA;AAE3C,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAA;AAEF,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC;IAC9B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,GAAG,EAAE,eAAe,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAA;AAEF,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;IAChC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAA;AAEF,MAAM,YAAY,GAAG,CAAC,CAAC,kBAAkB,CAAC,UAAU,EAAE,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,CAAC,CAAA;AAEnG,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QACxC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC1B,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5C,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;KACpC,CAAC;IACF,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC3B,CAAC;IACF,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE;IAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACb,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;QACxC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE;QACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;KACjB,CAAC;CACH,CAAC,CAAA;AAMF,MAAM,QAAQ,GAAG;IACf,KAAK,EAAE;QACL,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,eAAe;QACxB,mBAAmB,EAAE,SAAS;QAC9B,cAAc,EAAE,EAAE;KACnB;IACD,KAAK,EAAE;QACL,GAAG,EAAE,IAAI;KACV;IACD,MAAM,EAAE,IAAI;IACZ,IAAI,EAAE;QACJ,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,iCAAiC;KACxC;CACsB,CAAA;AAEzB,SAAS,cAAc,CAAC,GAAW;IACjC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAA;AACnE,CAAC;AAED,SAAS,IAAI;IACX,IAAI,IAAI,GAAqE,EAAE,CAAA;IAE/E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,qBAAqB,CAAC,CAAA;IAClE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAgB,CAAA;QACxE,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAA;QACrE,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,IAAI,WAAW,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAA;IACtG,CAAC;IAED,MAAM,GAAG,GAAkB;QACzB,KAAK,EAAE;YACL,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI;YAC7C,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC;YACtE,mBAAmB,EAAE,QAAQ,CAAC,KAAK,CAAC,mBAAmB;YACvD,cAAc,EAAE,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;SACzE;QACD,KAAK,EAAE;YACL,GAAG,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI;SAC7B;QACD,MAAM,EAAE,CAAC,GAAG,EAAE;YACZ,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI;gBAAE,OAAO,IAAI,CAAA;YACpC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAyI,CAAA;YACxJ,IAAI,CAAC,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;gBAC/B,OAAO,EAAE,QAAQ,EAAE,WAAoB,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAA;YACnE,CAAC;YACD,qFAAqF;YACrF,OAAO;gBACL,QAAQ,EAAE,CAAC,CAAC,QAAqB;gBACjC,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,EAAE;gBAC9B,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE;gBAC5B,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI;oBAChB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE;oBAC5E,CAAC,CAAC,IAAI;aACT,CAAA;QACH,CAAC,CAAC,EAAE;QACJ,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI;YAC3C,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI;YAC3C,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM;YACjD,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI;YAC3C,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI;YAC3C,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI;SAC5C;KACF,CAAA;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;IAC/E,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAAE,GAAG,CAAC,KAAK,CAAC,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;IAClG,IAAI,OAAO,CAAC,GAAG,CAAC,6BAA6B;QAAE,GAAG,CAAC,KAAK,CAAC,mBAAmB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAA;IAChI,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAAE,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAA;IACxF,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS;QAAE,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAA;IAChE,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS;QAAE,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACxE,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW;QAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,MAAM,CAAA;IACjF,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS;QAAE,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAA;IAChE,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS;QAAE,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAA;IAChE,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS;QAAE,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAA;IAEhE,qFAAqF;IACrF,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QAC1F,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,YAAY,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAA;IAC9C,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAC1C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACxC,MAAM,CAAC,KAAK,CAAC,iBAAiB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;QAC1E,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAA;AACpB,CAAC;AAED,6DAA6D;AAC7D,kEAAkE;AAClE,MAAM,UAAU,2BAA2B,CAAC,OAAe;IACzD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IACnD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAA;QAC5D,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE;YAAE,OAAO,QAAQ,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;IAC3D,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC1C,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACrD,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,yCAAyC,UAAU,+BAA+B,CAAC,CAAA;IAC/F,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,aAAa;IACpB,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACvC,MAAM,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAA;YACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,CAAA;IAC/B,CAAC;IACD,OAAO,2BAA2B,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;AAC1D,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,EAAE,CAAA;AAC5B,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,EAAE,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const AGENT_SCOPE = "agent";
|
|
2
|
+
export declare const WS_REJECT_REASON = "Unauthorized: agents need a PAT with 'agent' scope (--token / TAPFLOW_AGENT_TOKEN); browsers must sign in";
|
|
3
|
+
export interface ConnectionAuthInput {
|
|
4
|
+
isLocal: boolean;
|
|
5
|
+
hasCookieAuth: boolean;
|
|
6
|
+
/** Scopes of a valid PAT on the upgrade request, or null when none was presented. */
|
|
7
|
+
patScopes: string[] | null;
|
|
8
|
+
}
|
|
9
|
+
export type ConnectionDecision = {
|
|
10
|
+
action: 'reject';
|
|
11
|
+
reason: string;
|
|
12
|
+
} | {
|
|
13
|
+
action: 'accept';
|
|
14
|
+
role: 'browser';
|
|
15
|
+
}
|
|
16
|
+
/** 첫 메시지(agent:register / stream:register)가 역할을 결정한다. */
|
|
17
|
+
| {
|
|
18
|
+
action: 'accept';
|
|
19
|
+
role: 'first-message';
|
|
20
|
+
};
|
|
21
|
+
export declare function classifyConnection({ isLocal, hasCookieAuth, patScopes }: ConnectionAuthInput): ConnectionDecision;
|
|
22
|
+
//# sourceMappingURL=connectionAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectionAuth.d.ts","sourceRoot":"","sources":["../../src/lib/connectionAuth.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,UAAU,CAAA;AAGlC,eAAO,MAAM,gBAAgB,8GACgF,CAAA;AAE7G,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;IACtB,qFAAqF;IACrF,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE;AACvC,yDAAyD;GACvD;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,CAAA;AAI/C,wBAAgB,kBAAkB,CAChC,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,EAAE,mBAAmB,GACzD,kBAAkB,CAOpB"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const AGENT_SCOPE = 'agent';
|
|
2
|
+
// ws close reason은 123바이트 한도 (RFC 6455 §5.5.1).
|
|
3
|
+
export const WS_REJECT_REASON = "Unauthorized: agents need a PAT with 'agent' scope (--token / TAPFLOW_AGENT_TOKEN); browsers must sign in";
|
|
4
|
+
// 새 WebSocket 연결을 첫 메시지 도착 전에 분류한다. (주소 × 자격) 매트릭스를
|
|
5
|
+
// 단위 테스트할 수 있도록 순수 함수로 분리 (#271).
|
|
6
|
+
export function classifyConnection({ isLocal, hasCookieAuth, patScopes }) {
|
|
7
|
+
// 명시적 에이전트 자격은 떠돌이 쿠키보다 우선한다 — 원격 에이전트의 인증 경로.
|
|
8
|
+
if (!isLocal && patScopes?.includes(AGENT_SCOPE))
|
|
9
|
+
return { action: 'accept', role: 'first-message' };
|
|
10
|
+
if (hasCookieAuth)
|
|
11
|
+
return { action: 'accept', role: 'browser' };
|
|
12
|
+
if (isLocal)
|
|
13
|
+
return { action: 'accept', role: 'first-message' };
|
|
14
|
+
if (patScopes)
|
|
15
|
+
return { action: 'accept', role: 'browser' };
|
|
16
|
+
return { action: 'reject', reason: WS_REJECT_REASON };
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=connectionAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectionAuth.js","sourceRoot":"","sources":["../../src/lib/connectionAuth.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAA;AAElC,gDAAgD;AAChD,MAAM,CAAC,MAAM,gBAAgB,GAC3B,2GAA2G,CAAA;AAe7G,oDAAoD;AACpD,kCAAkC;AAClC,MAAM,UAAU,kBAAkB,CAChC,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAuB;IAE1D,+CAA+C;IAC/C,IAAI,CAAC,OAAO,IAAI,SAAS,EAAE,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,CAAA;IACpG,IAAI,aAAa;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC/D,IAAI,OAAO;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,CAAA;IAC/D,IAAI,SAAS;QAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAC3D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAA;AACvD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lanAddress.d.ts","sourceRoot":"","sources":["../../src/lib/lanAddress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AAexB,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,GAAG,MAAM,GAAG,IAAI,CAc5F"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const isPrivate = (a) => a.startsWith('192.168.') ||
|
|
2
|
+
a.startsWith('10.') ||
|
|
3
|
+
/^172\.(1[6-9]|2\d|3[01])\./.test(a);
|
|
4
|
+
// CGNAT 100.64.0.0/10 — Tailscale 등 VPN 인터페이스. 물리 LAN보다 후순위.
|
|
5
|
+
const isCgnat = (a) => {
|
|
6
|
+
const m = /^100\.(\d+)\./.exec(a);
|
|
7
|
+
return m !== null && Number(m[1]) >= 64 && Number(m[1]) <= 127;
|
|
8
|
+
};
|
|
9
|
+
// 대시보드가 "에이전트 Mac에서 실행할 커맨드"에 박을 릴레이 LAN 주소를 고른다.
|
|
10
|
+
// 사설 IPv4 > 기타 비-internal IPv4 > CGNAT 순. 없으면 null (호출부가 폴백).
|
|
11
|
+
export function pickLanAddress(ifaces) {
|
|
12
|
+
const candidates = [];
|
|
13
|
+
for (const list of Object.values(ifaces)) {
|
|
14
|
+
for (const info of list ?? []) {
|
|
15
|
+
if (info.internal || info.family !== 'IPv4')
|
|
16
|
+
continue;
|
|
17
|
+
candidates.push(info.address);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return (candidates.find((a) => isPrivate(a)) ??
|
|
21
|
+
candidates.find((a) => !isCgnat(a)) ??
|
|
22
|
+
candidates[0] ??
|
|
23
|
+
null);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=lanAddress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lanAddress.js","sourceRoot":"","sources":["../../src/lib/lanAddress.ts"],"names":[],"mappings":"AAEA,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,EAAE,CAC9B,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxB,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;IACnB,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAEtC,6DAA6D;AAC7D,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,EAAE;IAC5B,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjC,OAAO,CAAC,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAA;AAChE,CAAC,CAAA;AAED,kDAAkD;AAClD,8DAA8D;AAC9D,MAAM,UAAU,cAAc,CAAC,MAA8C;IAC3E,MAAM,UAAU,GAAa,EAAE,CAAA;IAC/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACzC,KAAK,MAAM,IAAI,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM;gBAAE,SAAQ;YACrD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/B,CAAC;IACH,CAAC;IACD,OAAO,CACL,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACpC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnC,UAAU,CAAC,CAAC,CAAC;QACb,IAAI,CACL,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface RateLimitDecision {
|
|
2
|
+
allowed: boolean;
|
|
3
|
+
retryAfterMs: number;
|
|
4
|
+
}
|
|
5
|
+
export interface RateLimiter {
|
|
6
|
+
check(key: string, now?: number): RateLimitDecision;
|
|
7
|
+
recordFailure(key: string, now?: number): void;
|
|
8
|
+
reset(key: string): void;
|
|
9
|
+
}
|
|
10
|
+
export interface RateLimiterOptions {
|
|
11
|
+
maxAttempts?: number;
|
|
12
|
+
baseDelayMs?: number;
|
|
13
|
+
maxDelayMs?: number;
|
|
14
|
+
retentionMs?: number;
|
|
15
|
+
maxEntries?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function createRateLimiter(opts?: RateLimiterOptions): RateLimiter;
|
|
18
|
+
//# sourceMappingURL=rateLimit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.d.ts","sourceRoot":"","sources":["../../src/middleware/rateLimit.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAAA;IACnD,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9C,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,kBAAkB;IAEjC,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,kBAAuB,GAAG,WAAW,CAkD5E"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// P0-1 — 인증 엔드포인트의 무차별 대입 방어. 인메모리 IP+계정 실패 카운터 + 지수 백오프.
|
|
2
|
+
// 단일 인스턴스(t3.small) 전제이므로 영속화 없이 프로세스 메모리에 둔다.
|
|
3
|
+
export function createRateLimiter(opts = {}) {
|
|
4
|
+
const maxAttempts = opts.maxAttempts ?? 5;
|
|
5
|
+
const baseDelayMs = opts.baseDelayMs ?? 1_000;
|
|
6
|
+
const maxDelayMs = opts.maxDelayMs ?? 15 * 60 * 1_000;
|
|
7
|
+
const retentionMs = opts.retentionMs ?? maxDelayMs;
|
|
8
|
+
const maxEntries = opts.maxEntries ?? 10_000;
|
|
9
|
+
const store = new Map();
|
|
10
|
+
function check(key, now = Date.now()) {
|
|
11
|
+
const a = store.get(key);
|
|
12
|
+
if (!a)
|
|
13
|
+
return { allowed: true, retryAfterMs: 0 };
|
|
14
|
+
if (a.expiresAt <= now) {
|
|
15
|
+
store.delete(key);
|
|
16
|
+
return { allowed: true, retryAfterMs: 0 };
|
|
17
|
+
}
|
|
18
|
+
if (a.lockedUntil > now)
|
|
19
|
+
return { allowed: false, retryAfterMs: a.lockedUntil - now };
|
|
20
|
+
return { allowed: true, retryAfterMs: 0 };
|
|
21
|
+
}
|
|
22
|
+
function evictIfNeeded(now) {
|
|
23
|
+
if (store.size <= maxEntries)
|
|
24
|
+
return;
|
|
25
|
+
for (const [k, v] of store)
|
|
26
|
+
if (v.expiresAt <= now)
|
|
27
|
+
store.delete(k);
|
|
28
|
+
// 만료만으로 부족하면 삽입 순서상 가장 오래된 항목부터 폐기.
|
|
29
|
+
while (store.size > maxEntries) {
|
|
30
|
+
const oldest = store.keys().next().value;
|
|
31
|
+
if (oldest === undefined)
|
|
32
|
+
break;
|
|
33
|
+
store.delete(oldest);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function recordFailure(key, now = Date.now()) {
|
|
37
|
+
const a = store.get(key) ?? { failures: 0, lockedUntil: 0, expiresAt: 0 };
|
|
38
|
+
a.failures += 1;
|
|
39
|
+
if (a.failures >= maxAttempts) {
|
|
40
|
+
const over = a.failures - maxAttempts;
|
|
41
|
+
a.lockedUntil = now + Math.min(baseDelayMs * 2 ** over, maxDelayMs);
|
|
42
|
+
}
|
|
43
|
+
a.expiresAt = now + retentionMs;
|
|
44
|
+
// delete 후 set으로 갱신된 키를 삽입 순서 맨 뒤로 보낸다(LRU). overflow eviction은 삽입
|
|
45
|
+
// 순서상 가장 오래된 것부터 폐기하므로, 활발한 키가 정크에 밀려 리셋되는 우회를 막는다.
|
|
46
|
+
store.delete(key);
|
|
47
|
+
store.set(key, a);
|
|
48
|
+
evictIfNeeded(now);
|
|
49
|
+
}
|
|
50
|
+
function reset(key) {
|
|
51
|
+
store.delete(key);
|
|
52
|
+
}
|
|
53
|
+
return { check, recordFailure, reset };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=rateLimit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../src/middleware/rateLimit.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -8,7 +8,7 @@ const { port, dataDir } = config.local;
|
|
|
8
8
|
const dbPath = path.join(dataDir, 'tapflow.db');
|
|
9
9
|
const uploadsDir = path.join(dataDir, 'uploads');
|
|
10
10
|
initDb(dbPath);
|
|
11
|
-
const server = new RelayServer({ port, uploadsDir, wsBackpressureBytes: config.local.wsBackpressureBytes });
|
|
11
|
+
const server = new RelayServer({ port, uploadsDir, wsBackpressureBytes: config.local.wsBackpressureBytes, trustedProxies: config.local.trustedProxies });
|
|
12
12
|
void server.start().then(() => {
|
|
13
13
|
logger.info(`tapflow relay running on port ${port}`);
|
|
14
14
|
});
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;AAEpC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,KAAK,CAAA;AACtC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;AAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;AAEhD,MAAM,CAAC,MAAM,CAAC,CAAA;AAEd,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpD,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;AAEpC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,KAAK,CAAA;AACtC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;AAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;AAEhD,MAAM,CAAC,MAAM,CAAC,CAAA;AAEd,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,cAAc,EAAE,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC,CAAA;AAExJ,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;IAC5B,MAAM,CAAC,IAAI,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAA;AACtD,CAAC,CAAC,CAAA;AAEF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACtE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tapflowio/relay",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "WebSocket relay server for tapflow — NAT traversal, session routing, JWT auth, bundled dashboard",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tapflow",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"nodemailer": "^8.0.7",
|
|
52
52
|
"ws": "^8.0.0",
|
|
53
53
|
"zod": "^4.4.3",
|
|
54
|
-
"@tapflowio/agent-core": "0.8.
|
|
54
|
+
"@tapflowio/agent-core": "0.8.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/better-sqlite3": "^7.6.13",
|