opentunnel-cli 1.0.22 → 1.0.25
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/README.md +69 -864
- package/dist/cli/index.js +712 -84
- package/dist/cli/index.js.map +1 -1
- package/dist/client/CloudflareTunnelClient.d.ts +110 -0
- package/dist/client/CloudflareTunnelClient.d.ts.map +1 -0
- package/dist/client/CloudflareTunnelClient.js +531 -0
- package/dist/client/CloudflareTunnelClient.js.map +1 -0
- package/dist/client/NgrokClient.d.ts +18 -1
- package/dist/client/NgrokClient.d.ts.map +1 -1
- package/dist/client/NgrokClient.js +130 -4
- package/dist/client/NgrokClient.js.map +1 -1
- package/dist/client/TunnelClient.d.ts +0 -1
- package/dist/client/TunnelClient.d.ts.map +1 -1
- package/dist/client/TunnelClient.js +2 -96
- package/dist/client/TunnelClient.js.map +1 -1
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +18 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/pages/index.d.ts +2 -0
- package/dist/lib/pages/index.d.ts.map +1 -0
- package/dist/lib/pages/index.js +6 -0
- package/dist/lib/pages/index.js.map +1 -0
- package/dist/lib/pages/not-running.d.ts +10 -0
- package/dist/lib/pages/not-running.d.ts.map +1 -0
- package/dist/lib/pages/not-running.js +117 -0
- package/dist/lib/pages/not-running.js.map +1 -0
- package/dist/server/TunnelServer.d.ts +7 -3
- package/dist/server/TunnelServer.d.ts.map +1 -1
- package/dist/server/TunnelServer.js +164 -51
- package/dist/server/TunnelServer.js.map +1 -1
- package/dist/shared/credentials.d.ts +101 -0
- package/dist/shared/credentials.d.ts.map +1 -0
- package/dist/shared/credentials.js +302 -0
- package/dist/shared/credentials.js.map +1 -0
- package/dist/shared/ip-filter.d.ts +75 -0
- package/dist/shared/ip-filter.d.ts.map +1 -0
- package/dist/shared/ip-filter.js +203 -0
- package/dist/shared/ip-filter.js.map +1 -0
- package/dist/shared/types.d.ts +46 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +7 -3
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { CloudflareCredentials, NgrokCredentials, GlobalCredentials } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Credentials Manager
|
|
4
|
+
*
|
|
5
|
+
* Handles secure storage and retrieval of provider credentials.
|
|
6
|
+
* Credential resolution priority: CLI > ENV > YAML > credentials.json
|
|
7
|
+
*/
|
|
8
|
+
export declare class CredentialsManager {
|
|
9
|
+
private credentials;
|
|
10
|
+
constructor();
|
|
11
|
+
/**
|
|
12
|
+
* Get the credentials directory path
|
|
13
|
+
*/
|
|
14
|
+
static getCredentialsDir(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Get the credentials file path
|
|
17
|
+
*/
|
|
18
|
+
static getCredentialsFile(): string;
|
|
19
|
+
/**
|
|
20
|
+
* Ensure the credentials directory exists with secure permissions
|
|
21
|
+
*/
|
|
22
|
+
private ensureDir;
|
|
23
|
+
/**
|
|
24
|
+
* Load credentials from file
|
|
25
|
+
*/
|
|
26
|
+
load(): GlobalCredentials;
|
|
27
|
+
/**
|
|
28
|
+
* Save credentials to file with secure permissions (0600)
|
|
29
|
+
*/
|
|
30
|
+
save(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Get all credentials
|
|
33
|
+
*/
|
|
34
|
+
getAll(): GlobalCredentials;
|
|
35
|
+
/**
|
|
36
|
+
* Get ngrok credentials
|
|
37
|
+
*/
|
|
38
|
+
getNgrok(): NgrokCredentials | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Set ngrok credentials
|
|
41
|
+
*/
|
|
42
|
+
setNgrok(creds: NgrokCredentials): void;
|
|
43
|
+
/**
|
|
44
|
+
* Remove ngrok credentials
|
|
45
|
+
*/
|
|
46
|
+
removeNgrok(): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Get Cloudflare credentials
|
|
49
|
+
*/
|
|
50
|
+
getCloudflare(): CloudflareCredentials | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Set Cloudflare credentials
|
|
53
|
+
*/
|
|
54
|
+
setCloudflare(creds: CloudflareCredentials): void;
|
|
55
|
+
/**
|
|
56
|
+
* Remove Cloudflare credentials
|
|
57
|
+
*/
|
|
58
|
+
removeCloudflare(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Remove all credentials for a provider
|
|
61
|
+
*/
|
|
62
|
+
removeProvider(provider: "ngrok" | "cloudflare"): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Set a specific credential value using dot notation
|
|
65
|
+
* e.g., "ngrok.token", "cloudflare.accountId"
|
|
66
|
+
*/
|
|
67
|
+
set(key: string, value: string): void;
|
|
68
|
+
/**
|
|
69
|
+
* Get a specific credential value using dot notation
|
|
70
|
+
* e.g., "ngrok.token", "cloudflare.accountId"
|
|
71
|
+
*/
|
|
72
|
+
get(key: string): string | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* List all stored credential keys (not values for security)
|
|
75
|
+
*/
|
|
76
|
+
listKeys(): string[];
|
|
77
|
+
/**
|
|
78
|
+
* Clear all credentials
|
|
79
|
+
*/
|
|
80
|
+
clear(): void;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Resolve ngrok token with priority: CLI > ENV > YAML > credentials.json
|
|
84
|
+
*/
|
|
85
|
+
export declare function resolveNgrokToken(options: {
|
|
86
|
+
cliToken?: string;
|
|
87
|
+
yamlToken?: string;
|
|
88
|
+
}): string | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Resolve Cloudflare credentials with priority: CLI > ENV > YAML > credentials.json
|
|
91
|
+
*/
|
|
92
|
+
export declare function resolveCloudflareCredentials(options: {
|
|
93
|
+
cliAccountId?: string;
|
|
94
|
+
cliTunnelToken?: string;
|
|
95
|
+
cliCertPath?: string;
|
|
96
|
+
yamlAccountId?: string;
|
|
97
|
+
yamlTunnelToken?: string;
|
|
98
|
+
yamlCertPath?: string;
|
|
99
|
+
}): CloudflareCredentials;
|
|
100
|
+
export declare function getCredentialsManager(): CredentialsManager;
|
|
101
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/shared/credentials.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAMrF;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,WAAW,CAAyB;;IAM5C;;OAEG;IACH,MAAM,CAAC,iBAAiB,IAAI,MAAM;IAIlC;;OAEG;IACH,MAAM,CAAC,kBAAkB,IAAI,MAAM;IAInC;;OAEG;IACH,OAAO,CAAC,SAAS;IAMjB;;OAEG;IACH,IAAI,IAAI,iBAAiB;IAYzB;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,MAAM,IAAI,iBAAiB;IAI3B;;OAEG;IACH,QAAQ,IAAI,gBAAgB,GAAG,SAAS;IAIxC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAKvC;;OAEG;IACH,WAAW,IAAI,OAAO;IAStB;;OAEG;IACH,aAAa,IAAI,qBAAqB,GAAG,SAAS;IAIlD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI;IAQjD;;OAEG;IACH,gBAAgB,IAAI,OAAO;IAS3B;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,OAAO,GAAG,YAAY,GAAG,OAAO;IASzD;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IA0BrC;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAoBpC;;OAEG;IACH,QAAQ,IAAI,MAAM,EAAE;IAgBpB;;OAEG;IACH,KAAK,IAAI,IAAI;CAIhB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,MAAM,GAAG,SAAS,CAoBrB;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB,GAAG,qBAAqB,CAkBxB;AAKD,wBAAgB,qBAAqB,IAAI,kBAAkB,CAK1D"}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CredentialsManager = void 0;
|
|
37
|
+
exports.resolveNgrokToken = resolveNgrokToken;
|
|
38
|
+
exports.resolveCloudflareCredentials = resolveCloudflareCredentials;
|
|
39
|
+
exports.getCredentialsManager = getCredentialsManager;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
43
|
+
// Credentials file location
|
|
44
|
+
const OPENTUNNEL_DIR = path.join(os.homedir(), ".opentunnel");
|
|
45
|
+
const CREDENTIALS_FILE = path.join(OPENTUNNEL_DIR, "credentials.json");
|
|
46
|
+
/**
|
|
47
|
+
* Credentials Manager
|
|
48
|
+
*
|
|
49
|
+
* Handles secure storage and retrieval of provider credentials.
|
|
50
|
+
* Credential resolution priority: CLI > ENV > YAML > credentials.json
|
|
51
|
+
*/
|
|
52
|
+
class CredentialsManager {
|
|
53
|
+
constructor() {
|
|
54
|
+
this.credentials = {};
|
|
55
|
+
this.load();
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the credentials directory path
|
|
59
|
+
*/
|
|
60
|
+
static getCredentialsDir() {
|
|
61
|
+
return OPENTUNNEL_DIR;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the credentials file path
|
|
65
|
+
*/
|
|
66
|
+
static getCredentialsFile() {
|
|
67
|
+
return CREDENTIALS_FILE;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Ensure the credentials directory exists with secure permissions
|
|
71
|
+
*/
|
|
72
|
+
ensureDir() {
|
|
73
|
+
if (!fs.existsSync(OPENTUNNEL_DIR)) {
|
|
74
|
+
fs.mkdirSync(OPENTUNNEL_DIR, { recursive: true, mode: 0o700 });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Load credentials from file
|
|
79
|
+
*/
|
|
80
|
+
load() {
|
|
81
|
+
try {
|
|
82
|
+
if (fs.existsSync(CREDENTIALS_FILE)) {
|
|
83
|
+
const content = fs.readFileSync(CREDENTIALS_FILE, "utf-8");
|
|
84
|
+
this.credentials = JSON.parse(content);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
this.credentials = {};
|
|
89
|
+
}
|
|
90
|
+
return this.credentials;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Save credentials to file with secure permissions (0600)
|
|
94
|
+
*/
|
|
95
|
+
save() {
|
|
96
|
+
this.ensureDir();
|
|
97
|
+
fs.writeFileSync(CREDENTIALS_FILE, JSON.stringify(this.credentials, null, 2), {
|
|
98
|
+
mode: 0o600,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get all credentials
|
|
103
|
+
*/
|
|
104
|
+
getAll() {
|
|
105
|
+
return this.credentials;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get ngrok credentials
|
|
109
|
+
*/
|
|
110
|
+
getNgrok() {
|
|
111
|
+
return this.credentials.ngrok;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Set ngrok credentials
|
|
115
|
+
*/
|
|
116
|
+
setNgrok(creds) {
|
|
117
|
+
this.credentials.ngrok = creds;
|
|
118
|
+
this.save();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Remove ngrok credentials
|
|
122
|
+
*/
|
|
123
|
+
removeNgrok() {
|
|
124
|
+
if (this.credentials.ngrok) {
|
|
125
|
+
delete this.credentials.ngrok;
|
|
126
|
+
this.save();
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Get Cloudflare credentials
|
|
133
|
+
*/
|
|
134
|
+
getCloudflare() {
|
|
135
|
+
return this.credentials.cloudflare;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Set Cloudflare credentials
|
|
139
|
+
*/
|
|
140
|
+
setCloudflare(creds) {
|
|
141
|
+
this.credentials.cloudflare = {
|
|
142
|
+
...this.credentials.cloudflare,
|
|
143
|
+
...creds,
|
|
144
|
+
};
|
|
145
|
+
this.save();
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Remove Cloudflare credentials
|
|
149
|
+
*/
|
|
150
|
+
removeCloudflare() {
|
|
151
|
+
if (this.credentials.cloudflare) {
|
|
152
|
+
delete this.credentials.cloudflare;
|
|
153
|
+
this.save();
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Remove all credentials for a provider
|
|
160
|
+
*/
|
|
161
|
+
removeProvider(provider) {
|
|
162
|
+
if (provider === "ngrok") {
|
|
163
|
+
return this.removeNgrok();
|
|
164
|
+
}
|
|
165
|
+
else if (provider === "cloudflare") {
|
|
166
|
+
return this.removeCloudflare();
|
|
167
|
+
}
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Set a specific credential value using dot notation
|
|
172
|
+
* e.g., "ngrok.token", "cloudflare.accountId"
|
|
173
|
+
*/
|
|
174
|
+
set(key, value) {
|
|
175
|
+
const [provider, field] = key.split(".");
|
|
176
|
+
if (provider === "ngrok") {
|
|
177
|
+
if (!this.credentials.ngrok) {
|
|
178
|
+
this.credentials.ngrok = { token: "" };
|
|
179
|
+
}
|
|
180
|
+
if (field === "token") {
|
|
181
|
+
this.credentials.ngrok.token = value;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else if (provider === "cloudflare") {
|
|
185
|
+
if (!this.credentials.cloudflare) {
|
|
186
|
+
this.credentials.cloudflare = {};
|
|
187
|
+
}
|
|
188
|
+
if (field === "accountId") {
|
|
189
|
+
this.credentials.cloudflare.accountId = value;
|
|
190
|
+
}
|
|
191
|
+
else if (field === "tunnelToken") {
|
|
192
|
+
this.credentials.cloudflare.tunnelToken = value;
|
|
193
|
+
}
|
|
194
|
+
else if (field === "certPath") {
|
|
195
|
+
this.credentials.cloudflare.certPath = value;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
this.save();
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Get a specific credential value using dot notation
|
|
202
|
+
* e.g., "ngrok.token", "cloudflare.accountId"
|
|
203
|
+
*/
|
|
204
|
+
get(key) {
|
|
205
|
+
const [provider, field] = key.split(".");
|
|
206
|
+
if (provider === "ngrok" && this.credentials.ngrok) {
|
|
207
|
+
if (field === "token") {
|
|
208
|
+
return this.credentials.ngrok.token;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else if (provider === "cloudflare" && this.credentials.cloudflare) {
|
|
212
|
+
if (field === "accountId") {
|
|
213
|
+
return this.credentials.cloudflare.accountId;
|
|
214
|
+
}
|
|
215
|
+
else if (field === "tunnelToken") {
|
|
216
|
+
return this.credentials.cloudflare.tunnelToken;
|
|
217
|
+
}
|
|
218
|
+
else if (field === "certPath") {
|
|
219
|
+
return this.credentials.cloudflare.certPath;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* List all stored credential keys (not values for security)
|
|
226
|
+
*/
|
|
227
|
+
listKeys() {
|
|
228
|
+
const keys = [];
|
|
229
|
+
if (this.credentials.ngrok) {
|
|
230
|
+
if (this.credentials.ngrok.token)
|
|
231
|
+
keys.push("ngrok.token");
|
|
232
|
+
}
|
|
233
|
+
if (this.credentials.cloudflare) {
|
|
234
|
+
if (this.credentials.cloudflare.accountId)
|
|
235
|
+
keys.push("cloudflare.accountId");
|
|
236
|
+
if (this.credentials.cloudflare.tunnelToken)
|
|
237
|
+
keys.push("cloudflare.tunnelToken");
|
|
238
|
+
if (this.credentials.cloudflare.certPath)
|
|
239
|
+
keys.push("cloudflare.certPath");
|
|
240
|
+
}
|
|
241
|
+
return keys;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Clear all credentials
|
|
245
|
+
*/
|
|
246
|
+
clear() {
|
|
247
|
+
this.credentials = {};
|
|
248
|
+
this.save();
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
exports.CredentialsManager = CredentialsManager;
|
|
252
|
+
/**
|
|
253
|
+
* Resolve ngrok token with priority: CLI > ENV > YAML > credentials.json
|
|
254
|
+
*/
|
|
255
|
+
function resolveNgrokToken(options) {
|
|
256
|
+
// 1. CLI flag (highest priority)
|
|
257
|
+
if (options.cliToken) {
|
|
258
|
+
return options.cliToken;
|
|
259
|
+
}
|
|
260
|
+
// 2. Environment variable
|
|
261
|
+
const envToken = process.env.NGROK_TOKEN || process.env.NGROK_AUTHTOKEN;
|
|
262
|
+
if (envToken) {
|
|
263
|
+
return envToken;
|
|
264
|
+
}
|
|
265
|
+
// 3. YAML config
|
|
266
|
+
if (options.yamlToken) {
|
|
267
|
+
return options.yamlToken;
|
|
268
|
+
}
|
|
269
|
+
// 4. Stored credentials (lowest priority)
|
|
270
|
+
const manager = new CredentialsManager();
|
|
271
|
+
return manager.getNgrok()?.token;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Resolve Cloudflare credentials with priority: CLI > ENV > YAML > credentials.json
|
|
275
|
+
*/
|
|
276
|
+
function resolveCloudflareCredentials(options) {
|
|
277
|
+
const manager = new CredentialsManager();
|
|
278
|
+
const stored = manager.getCloudflare() || {};
|
|
279
|
+
return {
|
|
280
|
+
accountId: options.cliAccountId
|
|
281
|
+
|| process.env.CLOUDFLARE_ACCOUNT_ID
|
|
282
|
+
|| options.yamlAccountId
|
|
283
|
+
|| stored.accountId,
|
|
284
|
+
tunnelToken: options.cliTunnelToken
|
|
285
|
+
|| process.env.CLOUDFLARE_TUNNEL_TOKEN
|
|
286
|
+
|| options.yamlTunnelToken
|
|
287
|
+
|| stored.tunnelToken,
|
|
288
|
+
certPath: options.cliCertPath
|
|
289
|
+
|| process.env.CLOUDFLARE_CERT_PATH
|
|
290
|
+
|| options.yamlCertPath
|
|
291
|
+
|| stored.certPath,
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
// Singleton instance for convenience
|
|
295
|
+
let _instance = null;
|
|
296
|
+
function getCredentialsManager() {
|
|
297
|
+
if (!_instance) {
|
|
298
|
+
_instance = new CredentialsManager();
|
|
299
|
+
}
|
|
300
|
+
return _instance;
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/shared/credentials.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { IncomingMessage } from "http";
|
|
2
|
+
import { IpAccessConfig } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Result of an IP access check
|
|
5
|
+
*/
|
|
6
|
+
export interface IpCheckResult {
|
|
7
|
+
allowed: boolean;
|
|
8
|
+
reason?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Shared IP filtering class for cross-provider security
|
|
12
|
+
*
|
|
13
|
+
* Supports:
|
|
14
|
+
* - Allowlist mode: Only IPs in the list are allowed
|
|
15
|
+
* - Denylist mode: IPs in the list are denied, others allowed
|
|
16
|
+
* - CIDR notation (e.g., 192.168.0.0/16)
|
|
17
|
+
* - IPv6-mapped IPv4 normalization
|
|
18
|
+
* - X-Forwarded-For / CF-Connecting-IP header extraction
|
|
19
|
+
*/
|
|
20
|
+
export declare class IpFilter {
|
|
21
|
+
private config;
|
|
22
|
+
constructor(config?: IpAccessConfig);
|
|
23
|
+
/**
|
|
24
|
+
* Update the filter configuration
|
|
25
|
+
*/
|
|
26
|
+
setConfig(config: IpAccessConfig): void;
|
|
27
|
+
/**
|
|
28
|
+
* Get the current configuration
|
|
29
|
+
*/
|
|
30
|
+
getConfig(): IpAccessConfig;
|
|
31
|
+
/**
|
|
32
|
+
* Check if an IP matches a CIDR range or single IP
|
|
33
|
+
*/
|
|
34
|
+
ipMatchesCidr(ip: string, cidr: string): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Check if an IP is in a list (supports CIDR notation)
|
|
37
|
+
*/
|
|
38
|
+
ipInList(ip: string, list: string[]): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Check if an IP is allowed based on the access config
|
|
41
|
+
*/
|
|
42
|
+
isAllowed(ip: string): IpCheckResult;
|
|
43
|
+
/**
|
|
44
|
+
* Normalize an IP address (removes IPv6-mapped IPv4 prefix)
|
|
45
|
+
*/
|
|
46
|
+
static normalizeIp(ip: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Extract client IP from various headers and socket
|
|
49
|
+
*
|
|
50
|
+
* Priority:
|
|
51
|
+
* 1. CF-Connecting-IP (Cloudflare)
|
|
52
|
+
* 2. X-Real-IP (nginx, common proxies)
|
|
53
|
+
* 3. X-Forwarded-For (first IP, standard proxy header)
|
|
54
|
+
* 4. Socket remoteAddress (direct connection)
|
|
55
|
+
*/
|
|
56
|
+
static extractClientIp(req: IncomingMessage): string;
|
|
57
|
+
/**
|
|
58
|
+
* Extract client IP from headers object (for use without IncomingMessage)
|
|
59
|
+
*/
|
|
60
|
+
static extractClientIpFromHeaders(headers: Record<string, string | string[] | undefined>, socketAddress?: string): string;
|
|
61
|
+
/**
|
|
62
|
+
* Merge two IP access configs, with the second one taking priority for non-undefined values
|
|
63
|
+
* Useful for per-tunnel config overriding global config
|
|
64
|
+
*/
|
|
65
|
+
static mergeConfigs(base?: IpAccessConfig, override?: IpAccessConfig): IpAccessConfig | undefined;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create a filter middleware function for HTTP servers
|
|
69
|
+
*
|
|
70
|
+
* @param config IP access configuration
|
|
71
|
+
* @param onDenied Optional callback when access is denied
|
|
72
|
+
* @returns Middleware function that returns true if allowed, false if denied
|
|
73
|
+
*/
|
|
74
|
+
export declare function createIpFilterMiddleware(config?: IpAccessConfig, onDenied?: (ip: string, reason: string) => void): (req: IncomingMessage) => IpCheckResult;
|
|
75
|
+
//# sourceMappingURL=ip-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ip-filter.d.ts","sourceRoot":"","sources":["../../src/shared/ip-filter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,qBAAa,QAAQ;IACjB,OAAO,CAAC,MAAM,CAAiB;gBAEnB,MAAM,CAAC,EAAE,cAAc;IAInC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAIvC;;OAEG;IACH,SAAS,IAAI,cAAc;IAI3B;;OAEG;IACH,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IA6BhD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO;IAI7C;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa;IA4BpC;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAItC;;;;;;;;OAQG;IACH,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM;IAkCpD;;OAEG;IACH,MAAM,CAAC,0BAA0B,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM;IAiCzH;;;OAGG;IACH,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,cAAc,GAAG,cAAc,GAAG,SAAS;CAmBpG;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACpC,MAAM,CAAC,EAAE,cAAc,EACvB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAChD,CAAC,GAAG,EAAE,eAAe,KAAK,aAAa,CAazC"}
|