@vasanthcambium/vite-plugin-nbi-proxy 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.
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Configurable defaults for the NBI proxy plugin.
3
+ * Override via NbiProxyOptions where marked optional.
4
+ */
5
+ export declare const PROXY_DEFAULTS: {
6
+ /** Path intercepted by the dev server middleware. */
7
+ readonly INTERCEPT_PREFIX: "/api/";
8
+ /** Cookie name the BFF sets after a successful login. */
9
+ readonly SESSION_COOKIE_NAME: "apps.sid";
10
+ /** Whether to automatically re-login and retry on a 401 from the BFF. */
11
+ readonly RETRY_ON_401: true;
12
+ /** Milliseconds to wait before the retry after a 401. */
13
+ readonly RETRY_DELAY_MS: 500;
14
+ /** Per-request timeout in milliseconds. */
15
+ readonly REQUEST_TIMEOUT_MS: 15000;
16
+ /** Headers forwarded from the browser request to the BFF. */
17
+ readonly FORWARDED_HEADERS: readonly string[];
18
+ };
19
+ /**
20
+ * Allowlist of upstream response headers forwarded to the browser.
21
+ * Using an allowlist rather than a blocklist prevents set-cookie and other
22
+ * sensitive headers from leaking if new headers are added upstream.
23
+ */
24
+ export declare const FORWARDED_RESPONSE_HEADERS: Set<string>;
25
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,cAAc;IACzB,qDAAqD;;IAGrD,yDAAyD;;IAGzD,yEAAyE;;IAGzE,yDAAyD;;IAGzD,2CAA2C;;IAG3C,6DAA6D;gCACO,SAAS,MAAM,EAAE;CAC7E,CAAC;AAEX;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,aAQrC,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Configurable defaults for the NBI proxy plugin.
3
+ * Override via NbiProxyOptions where marked optional.
4
+ */
5
+ export const PROXY_DEFAULTS = {
6
+ /** Path intercepted by the dev server middleware. */
7
+ INTERCEPT_PREFIX: '/api/',
8
+ /** Cookie name the BFF sets after a successful login. */
9
+ SESSION_COOKIE_NAME: 'apps.sid',
10
+ /** Whether to automatically re-login and retry on a 401 from the BFF. */
11
+ RETRY_ON_401: true,
12
+ /** Milliseconds to wait before the retry after a 401. */
13
+ RETRY_DELAY_MS: 500,
14
+ /** Per-request timeout in milliseconds. */
15
+ REQUEST_TIMEOUT_MS: 15_000,
16
+ /** Headers forwarded from the browser request to the BFF. */
17
+ FORWARDED_HEADERS: ['content-type', 'accept', 'accept-language'],
18
+ };
19
+ /**
20
+ * Allowlist of upstream response headers forwarded to the browser.
21
+ * Using an allowlist rather than a blocklist prevents set-cookie and other
22
+ * sensitive headers from leaking if new headers are added upstream.
23
+ */
24
+ export const FORWARDED_RESPONSE_HEADERS = new Set([
25
+ 'content-type',
26
+ 'content-length',
27
+ 'content-encoding',
28
+ 'cache-control',
29
+ 'last-modified',
30
+ 'etag',
31
+ 'vary',
32
+ ]);
33
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,qDAAqD;IACrD,gBAAgB,EAAE,OAAO;IAEzB,yDAAyD;IACzD,mBAAmB,EAAE,UAAU;IAE/B,yEAAyE;IACzE,YAAY,EAAE,IAAI;IAElB,yDAAyD;IACzD,cAAc,EAAE,GAAG;IAEnB,2CAA2C;IAC3C,kBAAkB,EAAE,MAAM;IAE1B,6DAA6D;IAC7D,iBAAiB,EAAE,CAAC,cAAc,EAAE,QAAQ,EAAE,iBAAiB,CAAsB;CAC7E,CAAC;AAEX;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAC;IAChD,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,eAAe;IACf,eAAe;IACf,MAAM;IACN,MAAM;CACP,CAAC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @cmbmwifi/vite-plugin-nbi-proxy
3
+ *
4
+ * Dev-only Vite plugin. Intercepts every /api/* request from the browser,
5
+ * logs in to the MarketApps BFF once using NBI_CLIENT_ID / NBI_CLIENT_SECRET
6
+ * from the process environment (never from import.meta.env), stores the
7
+ * resulting apps.sid session cookie in plugin memory, and forwards subsequent
8
+ * requests to the BFF at the configured CloudFront domain.
9
+ *
10
+ * In production the SPA is served by CloudFront and the BFF session comes
11
+ * from the SSO flow initiated by cnMaestro — this plugin is never involved.
12
+ */
13
+ import type { Plugin } from 'vite';
14
+ export interface NbiProxyOptions {
15
+ /** CloudFront domain for the target environment, e.g. https://dev.test-easy-apps.cloud.cambiumnetworks.com */
16
+ cfDomain: string;
17
+ /** app_category from apps-platform-entry.yaml, e.g. "enterprise" */
18
+ appCategory: string;
19
+ /** app_type from apps-platform-entry.yaml, e.g. "network-survey" */
20
+ appType: string;
21
+ }
22
+ export declare function nbiProxy(options: NbiProxyOptions): Plugin;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAIlD,MAAM,WAAW,eAAe;IAC9B,8GAA8G;IAC9G,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CA4IzD"}
package/dist/index.js ADDED
@@ -0,0 +1,130 @@
1
+ /**
2
+ * @cmbmwifi/vite-plugin-nbi-proxy
3
+ *
4
+ * Dev-only Vite plugin. Intercepts every /api/* request from the browser,
5
+ * logs in to the MarketApps BFF once using NBI_CLIENT_ID / NBI_CLIENT_SECRET
6
+ * from the process environment (never from import.meta.env), stores the
7
+ * resulting apps.sid session cookie in plugin memory, and forwards subsequent
8
+ * requests to the BFF at the configured CloudFront domain.
9
+ *
10
+ * In production the SPA is served by CloudFront and the BFF session comes
11
+ * from the SSO flow initiated by cnMaestro — this plugin is never involved.
12
+ */
13
+ import { PROXY_DEFAULTS, FORWARDED_RESPONSE_HEADERS } from './constants.js';
14
+ export function nbiProxy(options) {
15
+ const { cfDomain, appCategory, appType } = options;
16
+ const loginUrl = `${cfDomain}/${appCategory}/${appType}/api/v2/login`;
17
+ const apiBase = `${cfDomain}/${appCategory}/${appType}/api`;
18
+ let sessionCookie = null;
19
+ async function doLogin() {
20
+ const clientId = process.env['NBI_CLIENT_ID'] ?? '';
21
+ const clientSecret = process.env['NBI_CLIENT_SECRET'] ?? '';
22
+ if (!clientId || !clientSecret) {
23
+ throw new Error('[nbi-proxy] NBI_CLIENT_ID and NBI_CLIENT_SECRET must be set in .env.development');
24
+ }
25
+ const res = await fetch(loginUrl, {
26
+ method: 'POST',
27
+ headers: { 'content-type': 'application/json' },
28
+ body: JSON.stringify({ client_id: clientId, client_secret: clientSecret }),
29
+ signal: AbortSignal.timeout(PROXY_DEFAULTS.REQUEST_TIMEOUT_MS),
30
+ });
31
+ if (!res.ok) {
32
+ const body = await res.text().catch(() => '');
33
+ throw new Error(`[nbi-proxy] Login failed (${res.status}): ${body}`);
34
+ }
35
+ // Use getSetCookie() to safely iterate individual set-cookie headers
36
+ // without the ambiguity of comma-splitting a raw header string.
37
+ const sessionHeader = res.headers.getSetCookie().find((h) => h.startsWith(`${PROXY_DEFAULTS.SESSION_COOKIE_NAME}=`));
38
+ if (!sessionHeader) {
39
+ throw new Error('[nbi-proxy] Login succeeded but no session cookie in response');
40
+ }
41
+ // Cookie value is everything between "name=" and the first ";"
42
+ const value = sessionHeader.split(';')[0]?.split('=').slice(1).join('=') ?? '';
43
+ if (!value) {
44
+ throw new Error('[nbi-proxy] Login succeeded but session cookie value is empty');
45
+ }
46
+ return value;
47
+ }
48
+ async function doForward(method, url, reqHeaders, body, cookie) {
49
+ // Reject path-traversal attempts before forwarding.
50
+ const normalised = new URL(url, 'http://localhost').pathname;
51
+ if (!normalised.startsWith(PROXY_DEFAULTS.INTERCEPT_PREFIX)) {
52
+ throw new Error(`[nbi-proxy] Rejected request with unexpected path: ${url}`);
53
+ }
54
+ const target = `${apiBase}${url}`;
55
+ const headers = {
56
+ cookie: `${PROXY_DEFAULTS.SESSION_COOKIE_NAME}=${cookie}`,
57
+ };
58
+ for (const name of PROXY_DEFAULTS.FORWARDED_HEADERS) {
59
+ const val = reqHeaders[name];
60
+ if (typeof val === 'string')
61
+ headers[name] = val;
62
+ }
63
+ const upstream = await fetch(target, {
64
+ method,
65
+ headers,
66
+ ...(body.length > 0 ? { body } : {}),
67
+ signal: AbortSignal.timeout(PROXY_DEFAULTS.REQUEST_TIMEOUT_MS),
68
+ });
69
+ return {
70
+ status: upstream.status,
71
+ headers: upstream.headers,
72
+ body: await upstream.arrayBuffer(),
73
+ };
74
+ }
75
+ function delay(ms) {
76
+ return new Promise((r) => setTimeout(r, ms));
77
+ }
78
+ return {
79
+ name: 'vite-plugin-nbi-proxy',
80
+ apply: 'serve',
81
+ configureServer(server) {
82
+ server.middlewares.use(async (req, res, next) => {
83
+ if (!req.url?.startsWith(PROXY_DEFAULTS.INTERCEPT_PREFIX)) {
84
+ next();
85
+ return;
86
+ }
87
+ try {
88
+ // Buffer the request body once so it can be replayed on retry.
89
+ const chunks = [];
90
+ for await (const chunk of req) {
91
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
92
+ }
93
+ const bodyBuf = Buffer.concat(chunks);
94
+ if (!sessionCookie) {
95
+ sessionCookie = await doLogin();
96
+ }
97
+ let result = await doForward(req.method ?? 'GET', req.url, req.headers, bodyBuf, sessionCookie);
98
+ // Transparent re-login on session expiry — single retry for idempotent methods only.
99
+ // POST/PATCH are excluded: the BFF may have already acted on the request.
100
+ const method = (req.method ?? 'GET').toUpperCase();
101
+ const safeToRetry = ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE'].includes(method);
102
+ if (result.status === 401 && PROXY_DEFAULTS.RETRY_ON_401 && safeToRetry) {
103
+ sessionCookie = null;
104
+ await delay(PROXY_DEFAULTS.RETRY_DELAY_MS);
105
+ sessionCookie = await doLogin();
106
+ result = await doForward(req.method ?? 'GET', req.url, req.headers, bodyBuf, sessionCookie);
107
+ }
108
+ res.statusCode = result.status;
109
+ // Allowlist response headers forwarded to the browser.
110
+ // set-cookie is intentionally excluded — the session cookie stays
111
+ // in the plugin's memory, never reaches the browser.
112
+ result.headers.forEach((value, key) => {
113
+ if (FORWARDED_RESPONSE_HEADERS.has(key.toLowerCase())) {
114
+ res.setHeader(key, value);
115
+ }
116
+ });
117
+ res.end(Buffer.from(result.body));
118
+ }
119
+ catch (err) {
120
+ if (!res.headersSent) {
121
+ res.statusCode = 502;
122
+ res.setHeader('content-type', 'application/json');
123
+ res.end(JSON.stringify({ error: String(err) }));
124
+ }
125
+ }
126
+ });
127
+ },
128
+ };
129
+ }
130
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@vasanthcambium/vite-plugin-nbi-proxy",
3
+ "version": "0.1.0",
4
+ "description": "Vite dev-server plugin that proxies /api/* to the MarketApps BFF. Dev-only — not included in production builds.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/vasanthcambium/marketapps-developer-platform.git",
9
+ "directory": "vite-plugin/packages/nbi-proxy"
10
+ },
11
+ "type": "module",
12
+ "main": "./dist/index.js",
13
+ "types": "./dist/index.d.ts",
14
+ "exports": {
15
+ ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" }
16
+ },
17
+ "files": ["dist", "README.md"],
18
+ "publishConfig": {
19
+ "registry": "https://registry.npmjs.org",
20
+ "access": "public"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc -p tsconfig.build.json",
24
+ "typecheck": "tsc --noEmit"
25
+ },
26
+ "peerDependencies": {
27
+ "vite": "^5.0.0 || ^6.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^22.0.0",
31
+ "typescript": "~6.0.0",
32
+ "vite": "^5.4.0"
33
+ },
34
+ "engines": { "node": ">=22.0" },
35
+ "sideEffects": false,
36
+ "keywords": ["vite", "plugin", "cnmaestro", "cambium", "marketapps", "proxy", "nbi"]
37
+ }