@viasoftbr/shared-ui 0.0.5 → 0.0.7-1
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/components/index.d.ts +2 -2
- package/dist/components/network/index.d.ts +5 -4
- package/dist/components.cjs +71 -6
- package/dist/components.js +68 -3
- package/dist/context.cjs +1 -1
- package/dist/index.cjs +70 -5
- package/dist/index.js +67 -2
- package/dist/services/api.d.ts +2 -1
- package/dist/services.cjs +51 -2
- package/dist/services.js +51 -2
- package/dist/types/index.d.ts +6 -6
- package/dist/types/websocket.d.ts +7 -0
- package/package.json +18 -38
|
@@ -4,7 +4,7 @@ import { AudioGroup, FilterGroup, MiddlewareAuthGroup, MiddlewareChannelsGroup,
|
|
|
4
4
|
import { DvB, Livecast, ViewLog } from './encoder';
|
|
5
5
|
import { CheckboxField, ColorField, DatePicker, EditInPlaceField, InputField, Protocol, RangeField, SelectField, SliderField, SwitchField } from './input';
|
|
6
6
|
import { Footer, Header, PageHeader, SaveDiscard, Sidebar } from './main';
|
|
7
|
-
import { AddNetwork, InterfacesTable, InterfacesTimeseries } from './network';
|
|
7
|
+
import { AddNetwork, InterfacesTable, InterfacesTimeseries, isValidIPv4, isValidIPv6 } from './network';
|
|
8
8
|
import { ConfigWizard, RequireAuth } from './system';
|
|
9
9
|
import { Fflog, MetricBar, Panel, Preview, StreamControl, VideoPlayer, VUBar } from './xcoder';
|
|
10
|
-
export { Accordion, AddNetwork, AudioGroup, CheckboxField, ConfigWizard, Copy2Clipboard, ColorField, getGridLabel, GridSelectionModal, DatePicker, DvB, EditInPlaceField, Fflog, FilterGroup, Footer, Header, InputField, InterfacesTable, InterfacesTimeseries, SwitchField, Livecast, MetricBar, MiddlewareAuthGroup, MiddlewareChannelsGroup, MiddlewareMOSGroup, MiddlewareServiceGroup, Modal, PageHeader, Panel, Preview, PreviewGroup, ProtocolGroup, Protocol, RangeField, RequireAuth, SaveDiscard, Section, SelectField, Sidebar, SliderField, StreamControl, ValidationItem, VideoGroup, VideoPlayer, ViewLog, VUBar };
|
|
10
|
+
export { Accordion, AddNetwork, AudioGroup, CheckboxField, ConfigWizard, Copy2Clipboard, ColorField, getGridLabel, GridSelectionModal, DatePicker, DvB, EditInPlaceField, Fflog, FilterGroup, Footer, Header, InputField, InterfacesTable, InterfacesTimeseries, isValidIPv4, isValidIPv6, SwitchField, Livecast, MetricBar, MiddlewareAuthGroup, MiddlewareChannelsGroup, MiddlewareMOSGroup, MiddlewareServiceGroup, Modal, PageHeader, Panel, Preview, PreviewGroup, ProtocolGroup, Protocol, RangeField, RequireAuth, SaveDiscard, Section, SelectField, Sidebar, SliderField, StreamControl, ValidationItem, VideoGroup, VideoPlayer, ViewLog, VUBar };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import AddNetwork from "./AddNetwork
|
|
2
|
-
import InterfacesTable from "./InterfacesTable
|
|
3
|
-
import InterfacesTimeseries from "./InterfacesTimeseries
|
|
4
|
-
|
|
1
|
+
import AddNetwork from "./AddNetwork";
|
|
2
|
+
import InterfacesTable from "./InterfacesTable";
|
|
3
|
+
import InterfacesTimeseries from "./InterfacesTimeseries";
|
|
4
|
+
import { isValidIPv4, isValidIPv6 } from "./validators";
|
|
5
|
+
export { AddNetwork, InterfacesTable, InterfacesTimeseries, isValidIPv4, isValidIPv6, };
|
package/dist/components.cjs
CHANGED
|
@@ -165,7 +165,9 @@ __export(components_exports, {
|
|
|
165
165
|
VideoGroup: () => VideoGroup_default,
|
|
166
166
|
VideoPlayer: () => VideoPlayer_default,
|
|
167
167
|
ViewLog: () => ViewLog_default,
|
|
168
|
-
getGridLabel: () => getGridLabel
|
|
168
|
+
getGridLabel: () => getGridLabel,
|
|
169
|
+
isValidIPv4: () => isValidIPv4,
|
|
170
|
+
isValidIPv6: () => isValidIPv6
|
|
169
171
|
});
|
|
170
172
|
module.exports = __toCommonJS(components_exports);
|
|
171
173
|
|
|
@@ -25626,12 +25628,61 @@ function buildWsUrl(path = "/") {
|
|
|
25626
25628
|
return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
|
|
25627
25629
|
}
|
|
25628
25630
|
}
|
|
25631
|
+
function extractBearerToken(headers, explicitToken) {
|
|
25632
|
+
if (explicitToken)
|
|
25633
|
+
return explicitToken;
|
|
25634
|
+
if (!headers)
|
|
25635
|
+
return null;
|
|
25636
|
+
const authHeader = headers.Authorization || headers.authorization;
|
|
25637
|
+
if (!authHeader)
|
|
25638
|
+
return null;
|
|
25639
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
25640
|
+
return match ? match[1] : null;
|
|
25641
|
+
}
|
|
25642
|
+
function appendWsQueryParam(url, key, value) {
|
|
25643
|
+
try {
|
|
25644
|
+
const parsed = new URL(
|
|
25645
|
+
url,
|
|
25646
|
+
typeof window !== "undefined" ? window.location.href : void 0
|
|
25647
|
+
);
|
|
25648
|
+
parsed.searchParams.set(key, value);
|
|
25649
|
+
return parsed.toString();
|
|
25650
|
+
} catch {
|
|
25651
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
25652
|
+
return `${url}${separator}${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
25653
|
+
}
|
|
25654
|
+
}
|
|
25655
|
+
function normalizeProtocols(protocols) {
|
|
25656
|
+
if (!protocols)
|
|
25657
|
+
return void 0;
|
|
25658
|
+
return Array.isArray(protocols) ? protocols.filter(Boolean) : [protocols];
|
|
25659
|
+
}
|
|
25629
25660
|
async function decodeFfurl(ffurl) {
|
|
25630
25661
|
const { settings } = await fetchApi.postJson("/auth/protocols/ffurl/decode", { ffurl });
|
|
25631
25662
|
return settings;
|
|
25632
25663
|
}
|
|
25633
|
-
function subscribeToWebsocket(url, onMessage) {
|
|
25634
|
-
const
|
|
25664
|
+
function subscribeToWebsocket(url, onMessage, options = {}) {
|
|
25665
|
+
const bearerToken = extractBearerToken(options.headers, options.bearerToken);
|
|
25666
|
+
const bearerStrategy = options.bearerStrategy ?? "query";
|
|
25667
|
+
let resolvedUrl = url;
|
|
25668
|
+
const protocols = normalizeProtocols(options.protocols) ?? [];
|
|
25669
|
+
if (options.headers && Object.keys(options.headers).length > 0) {
|
|
25670
|
+
console.warn(
|
|
25671
|
+
"WebSocket connections in browsers do not support custom HTTP headers. shared-ui will derive bearer auth from Authorization and forward it using query string or subprotocol."
|
|
25672
|
+
);
|
|
25673
|
+
}
|
|
25674
|
+
if (bearerToken) {
|
|
25675
|
+
if (bearerStrategy === "protocol") {
|
|
25676
|
+
protocols.push("bearer", bearerToken);
|
|
25677
|
+
} else {
|
|
25678
|
+
resolvedUrl = appendWsQueryParam(
|
|
25679
|
+
url,
|
|
25680
|
+
options.bearerQueryParam ?? "access_token",
|
|
25681
|
+
bearerToken
|
|
25682
|
+
);
|
|
25683
|
+
}
|
|
25684
|
+
}
|
|
25685
|
+
const socket = protocols.length > 0 ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
|
|
25635
25686
|
socket.onmessage = (event) => {
|
|
25636
25687
|
try {
|
|
25637
25688
|
const data = JSON.parse(event.data);
|
|
@@ -35286,7 +35337,7 @@ var Footer = () => {
|
|
|
35286
35337
|
var Footer_default = Footer;
|
|
35287
35338
|
|
|
35288
35339
|
// src/components/main/Header.tsx
|
|
35289
|
-
var import_react86 = __toESM(require("react")
|
|
35340
|
+
var import_react86 = __toESM(require("react"));
|
|
35290
35341
|
var import_react_router_dom = require("react-router-dom");
|
|
35291
35342
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
35292
35343
|
function classNames(...classes) {
|
|
@@ -35656,7 +35707,7 @@ var Header = ({ isSidebarOpen, setSidebarOpen, onNavigate }) => {
|
|
|
35656
35707
|
var Header_default = Header;
|
|
35657
35708
|
|
|
35658
35709
|
// src/components/main/PageHeader.tsx
|
|
35659
|
-
var import_react88 = __toESM(require("react")
|
|
35710
|
+
var import_react88 = __toESM(require("react"));
|
|
35660
35711
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
35661
35712
|
var PageHeader = ({
|
|
35662
35713
|
icon,
|
|
@@ -36546,6 +36597,20 @@ var InterfacesTimeseries = ({
|
|
|
36546
36597
|
};
|
|
36547
36598
|
var InterfacesTimeseries_default = InterfacesTimeseries;
|
|
36548
36599
|
|
|
36600
|
+
// src/components/network/validators.ts
|
|
36601
|
+
var isValidIPv4 = (ip) => {
|
|
36602
|
+
if (!ip)
|
|
36603
|
+
return false;
|
|
36604
|
+
const ipv4Regex = /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/;
|
|
36605
|
+
return ipv4Regex.test(ip.trim());
|
|
36606
|
+
};
|
|
36607
|
+
var isValidIPv6 = (ip) => {
|
|
36608
|
+
if (!ip)
|
|
36609
|
+
return false;
|
|
36610
|
+
const ipv6Regex = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$|^((?:[A-F0-9]{1,4}(?::|$)){1,8})$/i;
|
|
36611
|
+
return ipv6Regex.test(ip.trim());
|
|
36612
|
+
};
|
|
36613
|
+
|
|
36549
36614
|
// src/components/system/RequireAuth.tsx
|
|
36550
36615
|
var import_react_router_dom3 = require("react-router-dom");
|
|
36551
36616
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
@@ -40019,7 +40084,7 @@ instance.use(initReactI18next).init({
|
|
|
40019
40084
|
var i18n_default = instance;
|
|
40020
40085
|
|
|
40021
40086
|
// src/context/SharedUiProvider.tsx
|
|
40022
|
-
var import_react104 = __toESM(require("react")
|
|
40087
|
+
var import_react104 = __toESM(require("react"));
|
|
40023
40088
|
var import_react_query2 = require("@tanstack/react-query");
|
|
40024
40089
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
40025
40090
|
|
package/dist/components.js
CHANGED
|
@@ -25571,12 +25571,61 @@ function buildWsUrl(path = "/") {
|
|
|
25571
25571
|
return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
|
|
25572
25572
|
}
|
|
25573
25573
|
}
|
|
25574
|
+
function extractBearerToken(headers, explicitToken) {
|
|
25575
|
+
if (explicitToken)
|
|
25576
|
+
return explicitToken;
|
|
25577
|
+
if (!headers)
|
|
25578
|
+
return null;
|
|
25579
|
+
const authHeader = headers.Authorization || headers.authorization;
|
|
25580
|
+
if (!authHeader)
|
|
25581
|
+
return null;
|
|
25582
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
25583
|
+
return match ? match[1] : null;
|
|
25584
|
+
}
|
|
25585
|
+
function appendWsQueryParam(url, key, value) {
|
|
25586
|
+
try {
|
|
25587
|
+
const parsed = new URL(
|
|
25588
|
+
url,
|
|
25589
|
+
typeof window !== "undefined" ? window.location.href : void 0
|
|
25590
|
+
);
|
|
25591
|
+
parsed.searchParams.set(key, value);
|
|
25592
|
+
return parsed.toString();
|
|
25593
|
+
} catch {
|
|
25594
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
25595
|
+
return `${url}${separator}${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
25596
|
+
}
|
|
25597
|
+
}
|
|
25598
|
+
function normalizeProtocols(protocols) {
|
|
25599
|
+
if (!protocols)
|
|
25600
|
+
return void 0;
|
|
25601
|
+
return Array.isArray(protocols) ? protocols.filter(Boolean) : [protocols];
|
|
25602
|
+
}
|
|
25574
25603
|
async function decodeFfurl(ffurl) {
|
|
25575
25604
|
const { settings } = await fetchApi.postJson("/auth/protocols/ffurl/decode", { ffurl });
|
|
25576
25605
|
return settings;
|
|
25577
25606
|
}
|
|
25578
|
-
function subscribeToWebsocket(url, onMessage) {
|
|
25579
|
-
const
|
|
25607
|
+
function subscribeToWebsocket(url, onMessage, options = {}) {
|
|
25608
|
+
const bearerToken = extractBearerToken(options.headers, options.bearerToken);
|
|
25609
|
+
const bearerStrategy = options.bearerStrategy ?? "query";
|
|
25610
|
+
let resolvedUrl = url;
|
|
25611
|
+
const protocols = normalizeProtocols(options.protocols) ?? [];
|
|
25612
|
+
if (options.headers && Object.keys(options.headers).length > 0) {
|
|
25613
|
+
console.warn(
|
|
25614
|
+
"WebSocket connections in browsers do not support custom HTTP headers. shared-ui will derive bearer auth from Authorization and forward it using query string or subprotocol."
|
|
25615
|
+
);
|
|
25616
|
+
}
|
|
25617
|
+
if (bearerToken) {
|
|
25618
|
+
if (bearerStrategy === "protocol") {
|
|
25619
|
+
protocols.push("bearer", bearerToken);
|
|
25620
|
+
} else {
|
|
25621
|
+
resolvedUrl = appendWsQueryParam(
|
|
25622
|
+
url,
|
|
25623
|
+
options.bearerQueryParam ?? "access_token",
|
|
25624
|
+
bearerToken
|
|
25625
|
+
);
|
|
25626
|
+
}
|
|
25627
|
+
}
|
|
25628
|
+
const socket = protocols.length > 0 ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
|
|
25580
25629
|
socket.onmessage = (event) => {
|
|
25581
25630
|
try {
|
|
25582
25631
|
const data = JSON.parse(event.data);
|
|
@@ -36491,6 +36540,20 @@ var InterfacesTimeseries = ({
|
|
|
36491
36540
|
};
|
|
36492
36541
|
var InterfacesTimeseries_default = InterfacesTimeseries;
|
|
36493
36542
|
|
|
36543
|
+
// src/components/network/validators.ts
|
|
36544
|
+
var isValidIPv4 = (ip) => {
|
|
36545
|
+
if (!ip)
|
|
36546
|
+
return false;
|
|
36547
|
+
const ipv4Regex = /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/;
|
|
36548
|
+
return ipv4Regex.test(ip.trim());
|
|
36549
|
+
};
|
|
36550
|
+
var isValidIPv6 = (ip) => {
|
|
36551
|
+
if (!ip)
|
|
36552
|
+
return false;
|
|
36553
|
+
const ipv6Regex = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$|^((?:[A-F0-9]{1,4}(?::|$)){1,8})$/i;
|
|
36554
|
+
return ipv6Regex.test(ip.trim());
|
|
36555
|
+
};
|
|
36556
|
+
|
|
36494
36557
|
// src/components/system/RequireAuth.tsx
|
|
36495
36558
|
import { Navigate } from "react-router-dom";
|
|
36496
36559
|
import { jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
@@ -40891,7 +40954,9 @@ export {
|
|
|
40891
40954
|
VideoGroup_default as VideoGroup,
|
|
40892
40955
|
VideoPlayer_default as VideoPlayer,
|
|
40893
40956
|
ViewLog_default as ViewLog,
|
|
40894
|
-
getGridLabel
|
|
40957
|
+
getGridLabel,
|
|
40958
|
+
isValidIPv4,
|
|
40959
|
+
isValidIPv6
|
|
40895
40960
|
};
|
|
40896
40961
|
/*! Bundled license information:
|
|
40897
40962
|
|
package/dist/context.cjs
CHANGED
|
@@ -3027,7 +3027,7 @@ function useAuth() {
|
|
|
3027
3027
|
}
|
|
3028
3028
|
|
|
3029
3029
|
// src/context/SharedUiProvider.tsx
|
|
3030
|
-
var import_react3 = __toESM(require("react")
|
|
3030
|
+
var import_react3 = __toESM(require("react"));
|
|
3031
3031
|
var import_react_query = require("@tanstack/react-query");
|
|
3032
3032
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
3033
3033
|
function SharedUiProvider({ children, client }) {
|
package/dist/index.cjs
CHANGED
|
@@ -186,6 +186,8 @@ __export(src_exports, {
|
|
|
186
186
|
getRefreshToken: () => getRefreshToken,
|
|
187
187
|
hostConfigLoader: () => hostConfigLoader,
|
|
188
188
|
isFirstRun: () => isFirstRun,
|
|
189
|
+
isValidIPv4: () => isValidIPv4,
|
|
190
|
+
isValidIPv6: () => isValidIPv6,
|
|
189
191
|
registry: () => registry,
|
|
190
192
|
saveConfig: () => saveConfig,
|
|
191
193
|
setAccessToken: () => setAccessToken,
|
|
@@ -3038,6 +3040,35 @@ function buildWsUrl(path = "/") {
|
|
|
3038
3040
|
return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
|
|
3039
3041
|
}
|
|
3040
3042
|
}
|
|
3043
|
+
function extractBearerToken(headers, explicitToken) {
|
|
3044
|
+
if (explicitToken)
|
|
3045
|
+
return explicitToken;
|
|
3046
|
+
if (!headers)
|
|
3047
|
+
return null;
|
|
3048
|
+
const authHeader = headers.Authorization || headers.authorization;
|
|
3049
|
+
if (!authHeader)
|
|
3050
|
+
return null;
|
|
3051
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
3052
|
+
return match ? match[1] : null;
|
|
3053
|
+
}
|
|
3054
|
+
function appendWsQueryParam(url, key, value) {
|
|
3055
|
+
try {
|
|
3056
|
+
const parsed = new URL(
|
|
3057
|
+
url,
|
|
3058
|
+
typeof window !== "undefined" ? window.location.href : void 0
|
|
3059
|
+
);
|
|
3060
|
+
parsed.searchParams.set(key, value);
|
|
3061
|
+
return parsed.toString();
|
|
3062
|
+
} catch {
|
|
3063
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
3064
|
+
return `${url}${separator}${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
function normalizeProtocols(protocols) {
|
|
3068
|
+
if (!protocols)
|
|
3069
|
+
return void 0;
|
|
3070
|
+
return Array.isArray(protocols) ? protocols.filter(Boolean) : [protocols];
|
|
3071
|
+
}
|
|
3041
3072
|
async function encodeFfurl(settings) {
|
|
3042
3073
|
const { ffurl } = await fetchApi.postJson("/auth/protocols/ffurl/encode", settings);
|
|
3043
3074
|
return ffurl;
|
|
@@ -3046,8 +3077,28 @@ async function decodeFfurl(ffurl) {
|
|
|
3046
3077
|
const { settings } = await fetchApi.postJson("/auth/protocols/ffurl/decode", { ffurl });
|
|
3047
3078
|
return settings;
|
|
3048
3079
|
}
|
|
3049
|
-
function subscribeToWebsocket(url, onMessage) {
|
|
3050
|
-
const
|
|
3080
|
+
function subscribeToWebsocket(url, onMessage, options = {}) {
|
|
3081
|
+
const bearerToken = extractBearerToken(options.headers, options.bearerToken);
|
|
3082
|
+
const bearerStrategy = options.bearerStrategy ?? "query";
|
|
3083
|
+
let resolvedUrl = url;
|
|
3084
|
+
const protocols = normalizeProtocols(options.protocols) ?? [];
|
|
3085
|
+
if (options.headers && Object.keys(options.headers).length > 0) {
|
|
3086
|
+
console.warn(
|
|
3087
|
+
"WebSocket connections in browsers do not support custom HTTP headers. shared-ui will derive bearer auth from Authorization and forward it using query string or subprotocol."
|
|
3088
|
+
);
|
|
3089
|
+
}
|
|
3090
|
+
if (bearerToken) {
|
|
3091
|
+
if (bearerStrategy === "protocol") {
|
|
3092
|
+
protocols.push("bearer", bearerToken);
|
|
3093
|
+
} else {
|
|
3094
|
+
resolvedUrl = appendWsQueryParam(
|
|
3095
|
+
url,
|
|
3096
|
+
options.bearerQueryParam ?? "access_token",
|
|
3097
|
+
bearerToken
|
|
3098
|
+
);
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
3101
|
+
const socket = protocols.length > 0 ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
|
|
3051
3102
|
socket.onmessage = (event) => {
|
|
3052
3103
|
try {
|
|
3053
3104
|
const data = JSON.parse(event.data);
|
|
@@ -35545,7 +35596,7 @@ var Footer = () => {
|
|
|
35545
35596
|
var Footer_default = Footer;
|
|
35546
35597
|
|
|
35547
35598
|
// src/components/main/Header.tsx
|
|
35548
|
-
var import_react86 = __toESM(require("react")
|
|
35599
|
+
var import_react86 = __toESM(require("react"));
|
|
35549
35600
|
var import_react_router_dom = require("react-router-dom");
|
|
35550
35601
|
var import_jsx_runtime33 = require("react/jsx-runtime");
|
|
35551
35602
|
function classNames(...classes) {
|
|
@@ -35915,7 +35966,7 @@ var Header = ({ isSidebarOpen, setSidebarOpen, onNavigate }) => {
|
|
|
35915
35966
|
var Header_default = Header;
|
|
35916
35967
|
|
|
35917
35968
|
// src/components/main/PageHeader.tsx
|
|
35918
|
-
var import_react88 = __toESM(require("react")
|
|
35969
|
+
var import_react88 = __toESM(require("react"));
|
|
35919
35970
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
35920
35971
|
var PageHeader = ({
|
|
35921
35972
|
icon,
|
|
@@ -36805,6 +36856,20 @@ var InterfacesTimeseries = ({
|
|
|
36805
36856
|
};
|
|
36806
36857
|
var InterfacesTimeseries_default = InterfacesTimeseries;
|
|
36807
36858
|
|
|
36859
|
+
// src/components/network/validators.ts
|
|
36860
|
+
var isValidIPv4 = (ip) => {
|
|
36861
|
+
if (!ip)
|
|
36862
|
+
return false;
|
|
36863
|
+
const ipv4Regex = /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/;
|
|
36864
|
+
return ipv4Regex.test(ip.trim());
|
|
36865
|
+
};
|
|
36866
|
+
var isValidIPv6 = (ip) => {
|
|
36867
|
+
if (!ip)
|
|
36868
|
+
return false;
|
|
36869
|
+
const ipv6Regex = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$|^((?:[A-F0-9]{1,4}(?::|$)){1,8})$/i;
|
|
36870
|
+
return ipv6Regex.test(ip.trim());
|
|
36871
|
+
};
|
|
36872
|
+
|
|
36808
36873
|
// src/components/system/RequireAuth.tsx
|
|
36809
36874
|
var import_react_router_dom3 = require("react-router-dom");
|
|
36810
36875
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
@@ -40278,7 +40343,7 @@ instance.use(initReactI18next).init({
|
|
|
40278
40343
|
var i18n_default = instance;
|
|
40279
40344
|
|
|
40280
40345
|
// src/context/SharedUiProvider.tsx
|
|
40281
|
-
var import_react104 = __toESM(require("react")
|
|
40346
|
+
var import_react104 = __toESM(require("react"));
|
|
40282
40347
|
var import_react_query2 = require("@tanstack/react-query");
|
|
40283
40348
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
40284
40349
|
function SharedUiProvider({ children, client }) {
|
package/dist/index.js
CHANGED
|
@@ -2953,6 +2953,35 @@ function buildWsUrl(path = "/") {
|
|
|
2953
2953
|
return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
|
|
2954
2954
|
}
|
|
2955
2955
|
}
|
|
2956
|
+
function extractBearerToken(headers, explicitToken) {
|
|
2957
|
+
if (explicitToken)
|
|
2958
|
+
return explicitToken;
|
|
2959
|
+
if (!headers)
|
|
2960
|
+
return null;
|
|
2961
|
+
const authHeader = headers.Authorization || headers.authorization;
|
|
2962
|
+
if (!authHeader)
|
|
2963
|
+
return null;
|
|
2964
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
2965
|
+
return match ? match[1] : null;
|
|
2966
|
+
}
|
|
2967
|
+
function appendWsQueryParam(url, key, value) {
|
|
2968
|
+
try {
|
|
2969
|
+
const parsed = new URL(
|
|
2970
|
+
url,
|
|
2971
|
+
typeof window !== "undefined" ? window.location.href : void 0
|
|
2972
|
+
);
|
|
2973
|
+
parsed.searchParams.set(key, value);
|
|
2974
|
+
return parsed.toString();
|
|
2975
|
+
} catch {
|
|
2976
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
2977
|
+
return `${url}${separator}${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
function normalizeProtocols(protocols) {
|
|
2981
|
+
if (!protocols)
|
|
2982
|
+
return void 0;
|
|
2983
|
+
return Array.isArray(protocols) ? protocols.filter(Boolean) : [protocols];
|
|
2984
|
+
}
|
|
2956
2985
|
async function encodeFfurl(settings) {
|
|
2957
2986
|
const { ffurl } = await fetchApi.postJson("/auth/protocols/ffurl/encode", settings);
|
|
2958
2987
|
return ffurl;
|
|
@@ -2961,8 +2990,28 @@ async function decodeFfurl(ffurl) {
|
|
|
2961
2990
|
const { settings } = await fetchApi.postJson("/auth/protocols/ffurl/decode", { ffurl });
|
|
2962
2991
|
return settings;
|
|
2963
2992
|
}
|
|
2964
|
-
function subscribeToWebsocket(url, onMessage) {
|
|
2965
|
-
const
|
|
2993
|
+
function subscribeToWebsocket(url, onMessage, options = {}) {
|
|
2994
|
+
const bearerToken = extractBearerToken(options.headers, options.bearerToken);
|
|
2995
|
+
const bearerStrategy = options.bearerStrategy ?? "query";
|
|
2996
|
+
let resolvedUrl = url;
|
|
2997
|
+
const protocols = normalizeProtocols(options.protocols) ?? [];
|
|
2998
|
+
if (options.headers && Object.keys(options.headers).length > 0) {
|
|
2999
|
+
console.warn(
|
|
3000
|
+
"WebSocket connections in browsers do not support custom HTTP headers. shared-ui will derive bearer auth from Authorization and forward it using query string or subprotocol."
|
|
3001
|
+
);
|
|
3002
|
+
}
|
|
3003
|
+
if (bearerToken) {
|
|
3004
|
+
if (bearerStrategy === "protocol") {
|
|
3005
|
+
protocols.push("bearer", bearerToken);
|
|
3006
|
+
} else {
|
|
3007
|
+
resolvedUrl = appendWsQueryParam(
|
|
3008
|
+
url,
|
|
3009
|
+
options.bearerQueryParam ?? "access_token",
|
|
3010
|
+
bearerToken
|
|
3011
|
+
);
|
|
3012
|
+
}
|
|
3013
|
+
}
|
|
3014
|
+
const socket = protocols.length > 0 ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
|
|
2966
3015
|
socket.onmessage = (event) => {
|
|
2967
3016
|
try {
|
|
2968
3017
|
const data = JSON.parse(event.data);
|
|
@@ -36720,6 +36769,20 @@ var InterfacesTimeseries = ({
|
|
|
36720
36769
|
};
|
|
36721
36770
|
var InterfacesTimeseries_default = InterfacesTimeseries;
|
|
36722
36771
|
|
|
36772
|
+
// src/components/network/validators.ts
|
|
36773
|
+
var isValidIPv4 = (ip) => {
|
|
36774
|
+
if (!ip)
|
|
36775
|
+
return false;
|
|
36776
|
+
const ipv4Regex = /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/;
|
|
36777
|
+
return ipv4Regex.test(ip.trim());
|
|
36778
|
+
};
|
|
36779
|
+
var isValidIPv6 = (ip) => {
|
|
36780
|
+
if (!ip)
|
|
36781
|
+
return false;
|
|
36782
|
+
const ipv6Regex = /^(?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4}$|^((?:[A-F0-9]{1,4}(?::|$)){1,8})$/i;
|
|
36783
|
+
return ipv6Regex.test(ip.trim());
|
|
36784
|
+
};
|
|
36785
|
+
|
|
36723
36786
|
// src/components/system/RequireAuth.tsx
|
|
36724
36787
|
import { Navigate } from "react-router-dom";
|
|
36725
36788
|
import { jsx as jsx40, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
@@ -41279,6 +41342,8 @@ export {
|
|
|
41279
41342
|
getRefreshToken,
|
|
41280
41343
|
hostConfigLoader,
|
|
41281
41344
|
isFirstRun,
|
|
41345
|
+
isValidIPv4,
|
|
41346
|
+
isValidIPv6,
|
|
41282
41347
|
registry,
|
|
41283
41348
|
saveConfig,
|
|
41284
41349
|
setAccessToken,
|
package/dist/services/api.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ProtocolSettings } from '../types/protocol';
|
|
2
|
+
import { WebSocketSubscribeOptions } from '../types/websocket';
|
|
2
3
|
export declare const api: import("axios").AxiosInstance;
|
|
3
4
|
export declare const authApi: import("axios").AxiosInstance;
|
|
4
5
|
export declare function getAccessToken(): string | null;
|
|
@@ -19,4 +20,4 @@ export declare const fetchApi: {
|
|
|
19
20
|
export declare function buildWsUrl(path?: string): string;
|
|
20
21
|
export declare function encodeFfurl(settings: ProtocolSettings): Promise<string>;
|
|
21
22
|
export declare function decodeFfurl(ffurl: string): Promise<ProtocolSettings>;
|
|
22
|
-
export declare function subscribeToWebsocket(url: string, onMessage: (data: any) => void): () => void;
|
|
23
|
+
export declare function subscribeToWebsocket(url: string, onMessage: (data: any) => void, options?: WebSocketSubscribeOptions): () => void;
|
package/dist/services.cjs
CHANGED
|
@@ -2887,6 +2887,35 @@ function buildWsUrl(path = "/") {
|
|
|
2887
2887
|
return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
|
|
2888
2888
|
}
|
|
2889
2889
|
}
|
|
2890
|
+
function extractBearerToken(headers, explicitToken) {
|
|
2891
|
+
if (explicitToken)
|
|
2892
|
+
return explicitToken;
|
|
2893
|
+
if (!headers)
|
|
2894
|
+
return null;
|
|
2895
|
+
const authHeader = headers.Authorization || headers.authorization;
|
|
2896
|
+
if (!authHeader)
|
|
2897
|
+
return null;
|
|
2898
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
2899
|
+
return match ? match[1] : null;
|
|
2900
|
+
}
|
|
2901
|
+
function appendWsQueryParam(url, key, value) {
|
|
2902
|
+
try {
|
|
2903
|
+
const parsed = new URL(
|
|
2904
|
+
url,
|
|
2905
|
+
typeof window !== "undefined" ? window.location.href : void 0
|
|
2906
|
+
);
|
|
2907
|
+
parsed.searchParams.set(key, value);
|
|
2908
|
+
return parsed.toString();
|
|
2909
|
+
} catch {
|
|
2910
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
2911
|
+
return `${url}${separator}${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
function normalizeProtocols(protocols) {
|
|
2915
|
+
if (!protocols)
|
|
2916
|
+
return void 0;
|
|
2917
|
+
return Array.isArray(protocols) ? protocols.filter(Boolean) : [protocols];
|
|
2918
|
+
}
|
|
2890
2919
|
async function encodeFfurl(settings) {
|
|
2891
2920
|
const { ffurl } = await fetchApi.postJson("/auth/protocols/ffurl/encode", settings);
|
|
2892
2921
|
return ffurl;
|
|
@@ -2895,8 +2924,28 @@ async function decodeFfurl(ffurl) {
|
|
|
2895
2924
|
const { settings } = await fetchApi.postJson("/auth/protocols/ffurl/decode", { ffurl });
|
|
2896
2925
|
return settings;
|
|
2897
2926
|
}
|
|
2898
|
-
function subscribeToWebsocket(url, onMessage) {
|
|
2899
|
-
const
|
|
2927
|
+
function subscribeToWebsocket(url, onMessage, options = {}) {
|
|
2928
|
+
const bearerToken = extractBearerToken(options.headers, options.bearerToken);
|
|
2929
|
+
const bearerStrategy = options.bearerStrategy ?? "query";
|
|
2930
|
+
let resolvedUrl = url;
|
|
2931
|
+
const protocols = normalizeProtocols(options.protocols) ?? [];
|
|
2932
|
+
if (options.headers && Object.keys(options.headers).length > 0) {
|
|
2933
|
+
console.warn(
|
|
2934
|
+
"WebSocket connections in browsers do not support custom HTTP headers. shared-ui will derive bearer auth from Authorization and forward it using query string or subprotocol."
|
|
2935
|
+
);
|
|
2936
|
+
}
|
|
2937
|
+
if (bearerToken) {
|
|
2938
|
+
if (bearerStrategy === "protocol") {
|
|
2939
|
+
protocols.push("bearer", bearerToken);
|
|
2940
|
+
} else {
|
|
2941
|
+
resolvedUrl = appendWsQueryParam(
|
|
2942
|
+
url,
|
|
2943
|
+
options.bearerQueryParam ?? "access_token",
|
|
2944
|
+
bearerToken
|
|
2945
|
+
);
|
|
2946
|
+
}
|
|
2947
|
+
}
|
|
2948
|
+
const socket = protocols.length > 0 ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
|
|
2900
2949
|
socket.onmessage = (event) => {
|
|
2901
2950
|
try {
|
|
2902
2951
|
const data = JSON.parse(event.data);
|
package/dist/services.js
CHANGED
|
@@ -2847,6 +2847,35 @@ function buildWsUrl(path = "/") {
|
|
|
2847
2847
|
return `${proto}://${host}${path.startsWith("/") ? path : "/" + path}`;
|
|
2848
2848
|
}
|
|
2849
2849
|
}
|
|
2850
|
+
function extractBearerToken(headers, explicitToken) {
|
|
2851
|
+
if (explicitToken)
|
|
2852
|
+
return explicitToken;
|
|
2853
|
+
if (!headers)
|
|
2854
|
+
return null;
|
|
2855
|
+
const authHeader = headers.Authorization || headers.authorization;
|
|
2856
|
+
if (!authHeader)
|
|
2857
|
+
return null;
|
|
2858
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
2859
|
+
return match ? match[1] : null;
|
|
2860
|
+
}
|
|
2861
|
+
function appendWsQueryParam(url, key, value) {
|
|
2862
|
+
try {
|
|
2863
|
+
const parsed = new URL(
|
|
2864
|
+
url,
|
|
2865
|
+
typeof window !== "undefined" ? window.location.href : void 0
|
|
2866
|
+
);
|
|
2867
|
+
parsed.searchParams.set(key, value);
|
|
2868
|
+
return parsed.toString();
|
|
2869
|
+
} catch {
|
|
2870
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
2871
|
+
return `${url}${separator}${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
function normalizeProtocols(protocols) {
|
|
2875
|
+
if (!protocols)
|
|
2876
|
+
return void 0;
|
|
2877
|
+
return Array.isArray(protocols) ? protocols.filter(Boolean) : [protocols];
|
|
2878
|
+
}
|
|
2850
2879
|
async function encodeFfurl(settings) {
|
|
2851
2880
|
const { ffurl } = await fetchApi.postJson("/auth/protocols/ffurl/encode", settings);
|
|
2852
2881
|
return ffurl;
|
|
@@ -2855,8 +2884,28 @@ async function decodeFfurl(ffurl) {
|
|
|
2855
2884
|
const { settings } = await fetchApi.postJson("/auth/protocols/ffurl/decode", { ffurl });
|
|
2856
2885
|
return settings;
|
|
2857
2886
|
}
|
|
2858
|
-
function subscribeToWebsocket(url, onMessage) {
|
|
2859
|
-
const
|
|
2887
|
+
function subscribeToWebsocket(url, onMessage, options = {}) {
|
|
2888
|
+
const bearerToken = extractBearerToken(options.headers, options.bearerToken);
|
|
2889
|
+
const bearerStrategy = options.bearerStrategy ?? "query";
|
|
2890
|
+
let resolvedUrl = url;
|
|
2891
|
+
const protocols = normalizeProtocols(options.protocols) ?? [];
|
|
2892
|
+
if (options.headers && Object.keys(options.headers).length > 0) {
|
|
2893
|
+
console.warn(
|
|
2894
|
+
"WebSocket connections in browsers do not support custom HTTP headers. shared-ui will derive bearer auth from Authorization and forward it using query string or subprotocol."
|
|
2895
|
+
);
|
|
2896
|
+
}
|
|
2897
|
+
if (bearerToken) {
|
|
2898
|
+
if (bearerStrategy === "protocol") {
|
|
2899
|
+
protocols.push("bearer", bearerToken);
|
|
2900
|
+
} else {
|
|
2901
|
+
resolvedUrl = appendWsQueryParam(
|
|
2902
|
+
url,
|
|
2903
|
+
options.bearerQueryParam ?? "access_token",
|
|
2904
|
+
bearerToken
|
|
2905
|
+
);
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
const socket = protocols.length > 0 ? new WebSocket(resolvedUrl, protocols) : new WebSocket(resolvedUrl);
|
|
2860
2909
|
socket.onmessage = (event) => {
|
|
2861
2910
|
try {
|
|
2862
2911
|
const data = JSON.parse(event.data);
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from './auth
|
|
2
|
-
export * from './module
|
|
3
|
-
export * from './plugin.types
|
|
4
|
-
export * from './protocol
|
|
5
|
-
export * from './websocket
|
|
6
|
-
export * from './wizard
|
|
1
|
+
export * from './auth';
|
|
2
|
+
export * from './module';
|
|
3
|
+
export * from './plugin.types';
|
|
4
|
+
export * from './protocol';
|
|
5
|
+
export * from './websocket';
|
|
6
|
+
export * from './wizard';
|
|
@@ -25,3 +25,10 @@ export interface WebSocketData {
|
|
|
25
25
|
};
|
|
26
26
|
system: SystemInfo;
|
|
27
27
|
}
|
|
28
|
+
export interface WebSocketSubscribeOptions {
|
|
29
|
+
headers?: Record<string, string>;
|
|
30
|
+
protocols?: string | string[];
|
|
31
|
+
bearerToken?: string | null;
|
|
32
|
+
bearerStrategy?: 'query' | 'protocol';
|
|
33
|
+
bearerQueryParam?: string;
|
|
34
|
+
}
|
package/package.json
CHANGED
|
@@ -1,52 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viasoftbr/shared-ui",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"module": "./dist/index.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"version": "0.0.5",
|
|
3
|
+
"version": "0.0.7-1",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"types": "./dist/types/index.d.ts",
|
|
9
6
|
"exports": {
|
|
10
|
-
".": {
|
|
7
|
+
".": {
|
|
11
8
|
"import": "./dist/index.js",
|
|
12
|
-
"
|
|
13
|
-
"types": "./dist/index.d.ts"
|
|
14
|
-
},
|
|
15
|
-
"./index": {
|
|
16
|
-
"import": "./dist/index.js",
|
|
17
|
-
"require": "./dist/index.cjs",
|
|
18
|
-
"types": "./dist/index.d.ts"
|
|
19
|
-
},
|
|
20
|
-
"./context": {
|
|
21
|
-
"import": "./dist/context.js",
|
|
22
|
-
"require": "./dist/context.cjs",
|
|
23
|
-
"types": "./dist/context/index.d.ts"
|
|
9
|
+
"types": "./dist/types/index.d.ts"
|
|
24
10
|
},
|
|
25
11
|
"./components": {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"types": "./dist/components/index.d.ts"
|
|
29
|
-
},
|
|
30
|
-
"./services": {
|
|
31
|
-
"import": "./dist/services.js",
|
|
32
|
-
"require": "./dist/services.cjs",
|
|
33
|
-
"types": "./dist/services/index.d.ts"
|
|
12
|
+
"import": "./dist/components/index.js",
|
|
13
|
+
"types": "./dist/types/components/index.d.ts"
|
|
34
14
|
},
|
|
35
15
|
"./types": {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"types": "./dist/types/index.d.ts"
|
|
16
|
+
"import": "./dist/types-module/index.js",
|
|
17
|
+
"types": "./dist/types/types/index.d.ts"
|
|
39
18
|
},
|
|
40
|
-
"./
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"types": "./dist/i18n.d.ts"
|
|
19
|
+
"./services": {
|
|
20
|
+
"import": "./dist/services/index.js",
|
|
21
|
+
"types": "./dist/types/services/index.d.ts"
|
|
44
22
|
},
|
|
45
|
-
"./
|
|
46
|
-
"
|
|
23
|
+
"./context": {
|
|
24
|
+
"import": "./dist/context/index.js",
|
|
25
|
+
"types": "./dist/types/context/index.d.ts"
|
|
47
26
|
},
|
|
48
|
-
"./
|
|
49
|
-
"
|
|
27
|
+
"./hooks": {
|
|
28
|
+
"import": "./dist/hooks/index.js",
|
|
29
|
+
"types": "./dist/types/hooks/index.d.ts"
|
|
50
30
|
}
|
|
51
31
|
},
|
|
52
32
|
"scripts": {
|