mirror of
https://gitlab.nic.cz/turris/reforis/foris-js.git
synced 2025-06-16 13:46:16 +02:00
Compare commits
35 Commits
v5.1.15
...
61e90d1e23
Author | SHA1 | Date | |
---|---|---|---|
61e90d1e23 | |||
9e15f1e93e | |||
390e6cc807 | |||
e044439646 | |||
844ea9ea72 | |||
bf57281fa7 | |||
0a143e7de6 | |||
7ec1c46a63 | |||
7ceccd5222 | |||
f868881b3d | |||
188ed87fc0 | |||
c0f64e8c6c | |||
b95cfb664d | |||
52cdaf5bc5 | |||
175a07a865 | |||
f952e25205 | |||
01eeb06f9e | |||
839e227feb | |||
4b239ed195 | |||
2bcbe0ae59 | |||
b1ff608337 | |||
b662ba5b52 | |||
a4115245fe | |||
e1a893874a | |||
dd383ef1b2 | |||
b6e2cb71bb | |||
048e686185 | |||
a1e9f23620 | |||
579ed5ea8c | |||
c2eda33998 | |||
f49529018c | |||
a66a2f4708 | |||
43cb5bff50 | |||
c67ea089fd | |||
4b25f6eafc |
36
docs/components/Logo.js
Normal file
36
docs/components/Logo.js
Normal file
@ -0,0 +1,36 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Styled from "rsg-components/Styled";
|
||||
import logo from "./logo.svg";
|
||||
|
||||
const styles = ({ fontFamily }) => ({
|
||||
logo: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
margin: 0,
|
||||
fontFamily: fontFamily.base,
|
||||
fontSize: 18,
|
||||
fontWeight: "normal",
|
||||
},
|
||||
image: {
|
||||
height: "1.3em",
|
||||
marginLeft: "-0.2em",
|
||||
marginRight: "0.2em",
|
||||
},
|
||||
});
|
||||
|
||||
export function LogoRenderer({ classes, children }) {
|
||||
return (
|
||||
<h1 className={classes.logo}>
|
||||
<img className={classes.image} src={logo} alt="React logo" />
|
||||
{children}
|
||||
</h1>
|
||||
);
|
||||
}
|
||||
|
||||
LogoRenderer.propTypes = {
|
||||
classes: PropTypes.object.isRequired,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default Styled(styles)(LogoRenderer);
|
3
docs/components/logo.svg
Normal file
3
docs/components/logo.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000">
|
||||
<path d="M288.258 240.0394L717.5586-.44c.803 62.277-1.8207 124.502-1.4996 186.7266 1.8208 7.6343-7.2288 10.1966-12.102 13.4908L286.4375 432.1518l1.8206-192.1124zm2.284 277.645L711 278.3176l-.8416 192.7742L457.357 614.514l-1.842 289.03-167.7097 95.8926 2.7365-481.753z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 349 B |
@ -1,15 +1,15 @@
|
||||
Sooner or later you will face with situation when you want/need to make some
|
||||
changes in the library. Then the most important tool for you it's
|
||||
Sooner or later, you will face with situation when you want/need to make some
|
||||
changes in the library. Then the most important tool for you it's the
|
||||
[`npm link`](https://docs.npmjs.com/cli/link).
|
||||
|
||||
Please, notice that it will not work if you link library just from root of the
|
||||
repo. It happens due to location of sources `./src`. You need to pack library
|
||||
first `make pack` and then link it from `./dist` directory.
|
||||
Please, notice that it will not work if you link the library just from the root
|
||||
of the repo. It happens due to the location of sources `./src`. You need to pack
|
||||
the library first, `make pack` and then link it from the `./dist` directory.
|
||||
|
||||
Yeah it's not such comfortable solution for development. But it can fixed by
|
||||
writing small script similar as `make pack` but with linking every file and
|
||||
directory from `./src` to the some directory and linking then from it. Notice
|
||||
that you need to link `package.json` and `package-lock.json` as well.
|
||||
Yeah, it's not such a comfortable solution for development. But it can be fixed
|
||||
by writing a small script similar to making a pack but by linking every file and
|
||||
directory from `./src` to the same directory and linking then from it. Notice
|
||||
that you need to link a `package.json` and a `package-lock.json` as well.
|
||||
|
||||
So step by step:
|
||||
|
||||
|
4
docs/forisjs-npm.svg
Normal file
4
docs/forisjs-npm.svg
Normal file
@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500" fill="white">
|
||||
<path d="M49.5 171.722222222222h400v133.333333333333h-200v22.222222222223h-88.888888888889v-22.222222222223H49.5V171.722222222222zm22.222222222222 111.111111111111h44.444444444445v-66.666666666667h22.222222222222v66.666666666667h22.222222222222v-88.888888888889H71.722222222222v88.888888888889zm111.111111111111-88.888888888889v111.111111111111h44.444444444445v-22.222222222222h44.444444444444v-88.888888888889h-88.888888888889zm44.444444444445 22.222222222222H249.5v44.444444444445h-22.222222222222v-44.444444444445zm66.666666666666-22.222222222222v88.888888888889h44.444444444445v-66.666666666667h22.222222222222v66.666666666667h22.222222222222v-66.666666666667h22.222222222222v66.666666666667h22.222222222223v-88.888888888889H293.944444444444z" fill="#cb3837" />
|
||||
<path d="M71.722222222222 282.833333333333h44.444444444444v-66.666666666667h22.222222222223v66.666666666667h22.222222222222v-88.888888888889H71.722222222222zm111.111111111111-88.888888888889v111.111111111111h44.444444444444v-22.222222222222h44.444444444445v-88.888888888889h-88.888888888889zM249.5 260.611111111111h-22.222222222223v-44.444444444445H249.5v44.444444444445zm44.444444444444-66.666666666667v88.888888888889h44.444444444444v-66.666666666667h22.222222222223v66.666666666667h22.222222222222v-66.666666666667h22.222222222222v66.666666666667h22.222222222222v-88.888888888889z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
@ -1,6 +0,0 @@
|
||||
Foris JS library is set of components and utils for Foris JS application and
|
||||
plugins.
|
||||
|
||||
Please notice that all of these components or utils are used in reForis and
|
||||
plugins. If you like to study by example I would recommend to full-text search
|
||||
these repos.
|
37
docs/introduction.md
Normal file
37
docs/introduction.md
Normal file
@ -0,0 +1,37 @@
|
||||
Welcome! This is the official documentation for Foris JS.
|
||||
|
||||
## What Foris JS is
|
||||
|
||||
Foris JS library is a set of components and utils for reForis application and
|
||||
plugins.
|
||||
|
||||
Please notice that all of these components or utils are used in reForis and
|
||||
plugins. If you want to study them by example, I recommend you to full-text
|
||||
search those repositories.
|
||||
|
||||
# Installation
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Please make sure that [Node.js](https://nodejs.org/en/) is installed on your
|
||||
system.
|
||||
|
||||
The current Long Term Support (LTS) release is an ideal starting point, see
|
||||
[here](https://github.com/nodejs/Release#release-schedule).
|
||||
|
||||
## Installation
|
||||
|
||||
To install the latest release:
|
||||
|
||||
```plain
|
||||
npm install foris
|
||||
```
|
||||
|
||||
To install a specific version:
|
||||
|
||||
```plain
|
||||
npm install foris@version
|
||||
```
|
||||
|
||||
<a target="_blank" href="https://www.npmjs.com/package/foris">Check
|
||||
on<img width="100px" src="./docs/forisjs-npm.svg"></a>
|
37831
package-lock.json
generated
37831
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "foris",
|
||||
"version": "5.1.15",
|
||||
"description": "Set of components and utils for Foris and its plugins.",
|
||||
"version": "5.2.0",
|
||||
"description": "Foris JS library is a set of components and utils for reForis application and plugins.",
|
||||
"author": "CZ.NIC, z.s.p.o.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -53,13 +53,10 @@
|
||||
"react": "16.9.0",
|
||||
"react-dom": "16.9.0",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-styleguidist": "^11.1.7",
|
||||
"react-styleguidist": "^11.2.0",
|
||||
"snapshot-diff": "^0.7.0",
|
||||
"style-loader": "^1.2.1",
|
||||
"webpack": "^5.15.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"immer": "9.0.6"
|
||||
"webpack": "^5.68.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint src",
|
||||
@ -68,7 +65,6 @@
|
||||
"test:watch": "jest --watch",
|
||||
"test:coverage": "jest --coverage --colors",
|
||||
"docs": "npx styleguidist build ",
|
||||
"docs:watch": "styleguidist server",
|
||||
"preinstall": "npx npm-force-resolutions"
|
||||
"docs:watch": "styleguidist server"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
@ -7,7 +7,6 @@
|
||||
|
||||
import { useCallback, useEffect, useReducer, useState } from "react";
|
||||
|
||||
import { ForisURLs } from "../utils/forisUrls";
|
||||
import {
|
||||
API_ACTIONS,
|
||||
API_METHODS,
|
||||
@ -84,8 +83,8 @@ function APIReducer(state, action) {
|
||||
data: action.payload,
|
||||
};
|
||||
case API_ACTIONS.FAILURE:
|
||||
if (action.status === 403) {
|
||||
window.location.assign(ForisURLs.login);
|
||||
if (action.status === 401) {
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// Not an API error - should be rethrown.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
@ -11,6 +11,7 @@ export const HEADERS = {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
"X-CSRFToken": getCookie("_csrf_token"),
|
||||
"X-Requested-With": "json",
|
||||
};
|
||||
|
||||
export const TIMEOUT = 30500;
|
||||
@ -56,7 +57,7 @@ function getCookie(name) {
|
||||
|
||||
export function getErrorPayload(error) {
|
||||
if (error.response) {
|
||||
if (error.response.status === 403) {
|
||||
if (error.response.status === 401) {
|
||||
return _("The session is expired. Please log in again.");
|
||||
}
|
||||
return getJSONErrorMessage(error);
|
||||
|
@ -21,9 +21,14 @@ DownloadButton.defaultProps = {
|
||||
className: "btn-primary",
|
||||
};
|
||||
|
||||
export function DownloadButton({ href, className, children }) {
|
||||
export function DownloadButton({ href, className, children, ...props }) {
|
||||
return (
|
||||
<a href={href} className={`btn ${className}`.trim()} download>
|
||||
<a
|
||||
href={href}
|
||||
className={`btn ${className}`.trim()}
|
||||
{...props}
|
||||
download
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
@ -21,14 +21,17 @@ PasswordInput.propTypes = {
|
||||
helpText: PropTypes.string,
|
||||
/** Use show/hide password button. */
|
||||
withEye: PropTypes.bool,
|
||||
/** Use new-password in autocomplete attribute. */
|
||||
newPass: PropTypes.bool,
|
||||
};
|
||||
|
||||
export function PasswordInput({ withEye, ...props }) {
|
||||
export function PasswordInput({ withEye, newPass, ...props }) {
|
||||
const [isHidden, setHidden] = useState(true);
|
||||
|
||||
return (
|
||||
<Input
|
||||
type={withEye && !isHidden ? "text" : "password"}
|
||||
autoComplete={isHidden ? "new-password" : null}
|
||||
autoComplete={newPass ? "new-password" : "current-password"}
|
||||
{...props}
|
||||
>
|
||||
{withEye ? (
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
@ -18,20 +18,14 @@ Select.propTypes = {
|
||||
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
/** Help text message. */
|
||||
helpText: PropTypes.string,
|
||||
/** Turns on/off alphabetical ordering of the Select options. */
|
||||
customOrder: PropTypes.bool,
|
||||
};
|
||||
|
||||
export function Select({ label, choices, helpText, customOrder, ...props }) {
|
||||
export function Select({ label, choices, helpText, ...props }) {
|
||||
const uid = useUID();
|
||||
|
||||
const keys = Object.keys(choices);
|
||||
if (!customOrder) {
|
||||
keys.sort((a, b) => a - b || a.toString().localeCompare(b.toString()));
|
||||
}
|
||||
const options = keys.map((key) => (
|
||||
<option key={key} value={key}>
|
||||
{choices[key]}
|
||||
const options = Object.keys(choices).map((choice) => (
|
||||
<option key={choice} value={choice}>
|
||||
{choices[choice]}
|
||||
</option>
|
||||
));
|
||||
|
||||
|
5
src/bootstrap/Switch.md
Normal file
5
src/bootstrap/Switch.md
Normal file
@ -0,0 +1,5 @@
|
||||
Switch example:
|
||||
|
||||
```js
|
||||
<Switch label="Enable Switch" helpText="Toggle that switch!" />
|
||||
```
|
@ -13,7 +13,7 @@ exports[`<PasswordInput/> Render password input 1`] = `
|
||||
class="input-group"
|
||||
>
|
||||
<input
|
||||
autocomplete="new-password"
|
||||
autocomplete="current-password"
|
||||
class="form-control"
|
||||
id="1"
|
||||
type="password"
|
||||
|
@ -64,6 +64,7 @@ DeviceForm.propTypes = {
|
||||
channel: PropTypes.string.isRequired,
|
||||
guest_wifi: PropTypes.object.isRequired,
|
||||
encryption: PropTypes.string.isRequired,
|
||||
available_bands: PropTypes.array.isRequired,
|
||||
}),
|
||||
formErrors: PropTypes.object.isRequired,
|
||||
setFormValue: PropTypes.func.isRequired,
|
||||
@ -87,6 +88,7 @@ function DeviceForm({
|
||||
...props
|
||||
}) {
|
||||
const deviceID = formData.id;
|
||||
const bnds = formData.available_bands;
|
||||
return (
|
||||
<>
|
||||
<Switch
|
||||
@ -159,18 +161,24 @@ function DeviceForm({
|
||||
value={formData.hwmode}
|
||||
helpText={HELP_TEXTS.hwmode}
|
||||
inline
|
||||
onChange={setFormValue((value) => ({
|
||||
onChange={setFormValue((value) => {
|
||||
// Get the last item in an array of available HT modes
|
||||
const [best2] = bnds[0].available_htmodes.slice(-1);
|
||||
const [best5] = bnds[1].available_htmodes.slice(-1);
|
||||
return {
|
||||
devices: {
|
||||
[deviceIndex]: {
|
||||
hwmode: { $set: value },
|
||||
channel: { $set: "0" },
|
||||
htmode: {
|
||||
$set:
|
||||
value === "11a" ? "VHT80" : "HT20",
|
||||
// Set HT mode depending on checked frequency
|
||||
value === "11a" ? best5 : best2,
|
||||
},
|
||||
},
|
||||
},
|
||||
}))}
|
||||
};
|
||||
})}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
@ -209,7 +217,6 @@ function DeviceForm({
|
||||
[deviceIndex]: { encryption: { $set: value } },
|
||||
},
|
||||
}))}
|
||||
customOrder
|
||||
{...props}
|
||||
/>
|
||||
|
||||
|
@ -82,6 +82,10 @@ export function validator(formData) {
|
||||
|
||||
if (device.password.length < 8)
|
||||
errors.password = _("Password must contain at least 8 symbols");
|
||||
if (device.password.length >= 64)
|
||||
errors.password = _(
|
||||
"Password must not contain more than 63 symbols"
|
||||
);
|
||||
|
||||
if (!device.guest_wifi.enabled) return errors;
|
||||
|
||||
@ -97,6 +101,10 @@ export function validator(formData) {
|
||||
guest_wifi_errors.password = _(
|
||||
"Password must contain at least 8 symbols"
|
||||
);
|
||||
if (device.guest_wifi.password.length >= 64)
|
||||
guest_wifi_errors.password = _(
|
||||
"Password must not contain more than 63 symbols"
|
||||
);
|
||||
|
||||
if (guest_wifi_errors.SSID || guest_wifi_errors.password) {
|
||||
errors.guest_wifi = guest_wifi_errors;
|
||||
|
@ -26,6 +26,7 @@ describe("<WiFiSettings/>", () => {
|
||||
let getAllByText;
|
||||
let getAllByLabelText;
|
||||
let getByText;
|
||||
let getByLabelText;
|
||||
let asFragment;
|
||||
const endpoint = "/reforis/api/wifi";
|
||||
|
||||
@ -41,6 +42,7 @@ describe("<WiFiSettings/>", () => {
|
||||
asFragment = renderRes.asFragment;
|
||||
getAllByText = renderRes.getAllByText;
|
||||
getAllByLabelText = renderRes.getAllByLabelText;
|
||||
getByLabelText = renderRes.getByLabelText;
|
||||
getByText = renderRes.getByText;
|
||||
mockAxios.mockResponse({ data: wifiSettingsFixture() });
|
||||
await wait(() => renderRes.getByText("Wi-Fi 1"));
|
||||
@ -51,7 +53,6 @@ describe("<WiFiSettings/>", () => {
|
||||
const webSockets = new WebSockets();
|
||||
const { getByText } = render(
|
||||
<WiFiSettings
|
||||
ws={webSockets}
|
||||
ws={webSockets}
|
||||
endpoint={endpoint}
|
||||
resetEndpoint="foo"
|
||||
@ -146,7 +147,7 @@ describe("<WiFiSettings/>", () => {
|
||||
enabled: true,
|
||||
guest_wifi: { enabled: false },
|
||||
hidden: false,
|
||||
htmode: "HT20",
|
||||
htmode: "VHT80",
|
||||
hwmode: "11g",
|
||||
id: 0,
|
||||
password: "TestPass",
|
||||
@ -220,4 +221,24 @@ describe("<WiFiSettings/>", () => {
|
||||
it("ByteCount function", () => {
|
||||
expect(byteCount("abc")).toEqual(3);
|
||||
});
|
||||
|
||||
it("Should validate password length", () => {
|
||||
const shortErrorFeedback = /Password must contain/i;
|
||||
const longErrorFeedback = /Password must not contain/i;
|
||||
|
||||
fireEvent.click(getByText("Wi-Fi 1"));
|
||||
|
||||
const passwordInput = getByLabelText("Password");
|
||||
|
||||
const changePassword = (value) =>
|
||||
fireEvent.change(passwordInput, { target: { value } });
|
||||
|
||||
changePassword("12");
|
||||
expect(getByText(shortErrorFeedback)).toBeDefined();
|
||||
|
||||
changePassword(
|
||||
"longpasswordlongpasswordlongpasswordlongpasswordlongpasswordlong"
|
||||
);
|
||||
expect(getByText(longErrorFeedback)).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
@ -394,7 +394,7 @@ exports[`<WiFiSettings/> Snapshot guest network. 1`] = `
|
||||
+ class=\\"input-group\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ autocomplete=\\"new-password\\"
|
||||
+ autocomplete=\\"current-password\\"
|
||||
+ class=\\"form-control is-invalid\\"
|
||||
+ id=\\"23\\"
|
||||
+ required=\\"\\"
|
||||
@ -509,7 +509,7 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
||||
+ class=\\"input-group\\"
|
||||
+ >
|
||||
+ <input
|
||||
+ autocomplete=\\"new-password\\"
|
||||
+ autocomplete=\\"current-password\\"
|
||||
+ class=\\"form-control\\"
|
||||
+ id=\\"5\\"
|
||||
+ required=\\"\\"
|
||||
@ -627,6 +627,11 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
||||
+ id=\\"8\\"
|
||||
+ >
|
||||
+ <option
|
||||
+ value=\\"NOHT\\"
|
||||
+ >
|
||||
+ Disabled
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"HT20\\"
|
||||
+ >
|
||||
+ 802.11n - 20 MHz wide channel
|
||||
@ -637,11 +642,6 @@ exports[`<WiFiSettings/> Snapshot one module enabled. 1`] = `
|
||||
+ 802.11n - 40 MHz wide channel
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"NOHT\\"
|
||||
+ >
|
||||
+ Disabled
|
||||
+ </option>
|
||||
+ <option
|
||||
+ value=\\"VHT20\\"
|
||||
+ >
|
||||
+ 802.11ac - 20 MHz wide channel
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
@ -13,6 +13,10 @@ export const HTMODES = {
|
||||
VHT40: _("802.11ac - 40 MHz wide channel"),
|
||||
VHT80: _("802.11ac - 80 MHz wide channel"),
|
||||
VHT160: _("802.11ac - 160 MHz wide channel"),
|
||||
HE20: _("802.11ax - 20 MHz wide channel"),
|
||||
HE40: _("802.11ax - 40 MHz wide channel"),
|
||||
HE80: _("802.11ax - 80 MHz wide channel"),
|
||||
HE160: _("802.11ax - 160 MHz wide channel"),
|
||||
};
|
||||
export const HWMODES = {
|
||||
"11g": "2.4",
|
||||
|
@ -1,16 +1,17 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
import {
|
||||
validateDomain,
|
||||
validateDUID,
|
||||
validateIPv4Address,
|
||||
validateIPv6Address,
|
||||
validateIPv6Prefix,
|
||||
validateDomain,
|
||||
validateHostname,
|
||||
validateDUID,
|
||||
validateMAC,
|
||||
} from "utils/validations";
|
||||
|
||||
@ -68,6 +69,15 @@ describe("Validation functions", () => {
|
||||
expect(validateDomain(".")).not.toBe(undefined);
|
||||
});
|
||||
|
||||
it("validateHostname valid", () => {
|
||||
expect(validateHostname("new-android")).toBe(undefined);
|
||||
expect(validateHostname("local")).toBe(undefined);
|
||||
});
|
||||
it("validateHostname invalid", () => {
|
||||
expect(validateHostname("-android")).not.toBe(undefined);
|
||||
expect(validateHostname("local.")).not.toBe(undefined);
|
||||
});
|
||||
|
||||
it("validateDUID valid", () => {
|
||||
expect(validateDUID("abcdefAB")).toBe(undefined);
|
||||
expect(validateDUID("ABCDEF12")).toBe(undefined);
|
||||
|
@ -82,6 +82,7 @@ export {
|
||||
validateIPv6Address,
|
||||
validateIPv6Prefix,
|
||||
validateDomain,
|
||||
validateHostname,
|
||||
validateDUID,
|
||||
validateMAC,
|
||||
validateMultipleEmails,
|
||||
|
@ -9,8 +9,8 @@ export const REFORIS_URL_PREFIX = "/reforis";
|
||||
export const REFORIS_API_URL_PREFIX = `${REFORIS_URL_PREFIX}/api`;
|
||||
|
||||
export const ForisURLs = {
|
||||
login: `${REFORIS_URL_PREFIX}/login`,
|
||||
logout: `${REFORIS_URL_PREFIX}/logout`,
|
||||
login: `/login?${REFORIS_URL_PREFIX}/`,
|
||||
logout: `/logout`,
|
||||
|
||||
static: `${REFORIS_URL_PREFIX}/static/reforis`,
|
||||
wifi: `${REFORIS_URL_PREFIX}/network-settings/wifi`,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
@ -14,6 +14,7 @@ export const ERROR_MESSAGES = {
|
||||
IPv6: _("This is not a valid IPv6 address."),
|
||||
IPv6Prefix: _("This is not a valid IPv6 prefix."),
|
||||
domain: _("This is not a valid domain name."),
|
||||
hostname: _("This is not a valid hostname."),
|
||||
DUID: _("This is not a valid DUID."),
|
||||
MAC: _("This is not a valid MAC address."),
|
||||
MultipleEmails: _("Doesn't contain a list of emails separated by commas."),
|
||||
@ -23,7 +24,8 @@ const REs = {
|
||||
IPv4: /^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
|
||||
IPv6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,
|
||||
IPv6Prefix: /^s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]d|1dd|[1-9]?d)(.(25[0-5]|2[0-4]d|1dd|[1-9]?d)){3}))|:)))(%.+)?s*(\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8]))$/,
|
||||
domain: /^[A-Za-z0-9][A-Za-z0-9.-]{1,255}$/,
|
||||
domain: /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/,
|
||||
hostname: /^[a-z\d]([a-z\d-]{0,61}[a-z\d])?(\.[a-z\d]([a-z\d-]{0,61}[a-z\d])?)*$/i,
|
||||
DUID: /^([0-9a-fA-F]{2}){4}([0-9a-fA-F]{2})*$/,
|
||||
MAC: /^([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}$/,
|
||||
MultipleEmails: /^([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+ *)( *, *[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+ *)*$/,
|
||||
@ -40,6 +42,7 @@ const validateIPv4Address = createValidator("IPv4");
|
||||
const validateIPv6Address = createValidator("IPv6");
|
||||
const validateIPv6Prefix = createValidator("IPv6Prefix");
|
||||
const validateDomain = createValidator("domain");
|
||||
const validateHostname = createValidator("hostname");
|
||||
const validateDUID = createValidator("DUID");
|
||||
const validateMAC = createValidator("MAC");
|
||||
const validateMultipleEmails = createValidator("MultipleEmails");
|
||||
@ -49,6 +52,7 @@ export {
|
||||
validateIPv6Address,
|
||||
validateIPv6Prefix,
|
||||
validateDomain,
|
||||
validateHostname,
|
||||
validateDUID,
|
||||
validateMAC,
|
||||
validateMultipleEmails,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2020-2021 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
@ -7,8 +7,6 @@
|
||||
|
||||
/* eslint no-console: "off" */
|
||||
|
||||
import { ForisURLs } from "../utils/forisUrls";
|
||||
|
||||
const PROTOCOL = window.location.protocol === "http:" ? "ws" : "wss";
|
||||
|
||||
const URL = process.env.LIGHTTPD
|
||||
@ -21,12 +19,6 @@ export class WebSockets {
|
||||
constructor() {
|
||||
this.ws = new WebSocket(URL);
|
||||
this.ws.onerror = (e) => {
|
||||
if (!window.initialData.logged) {
|
||||
console.error(
|
||||
"WS: Error observed, you aren't logged probably."
|
||||
);
|
||||
window.location.replace(ForisURLs.login);
|
||||
}
|
||||
console.error("WS: Error:", e);
|
||||
};
|
||||
this.ws.onmessage = (e) => {
|
||||
|
@ -1,23 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
|
||||
* Copyright (C) 2019-2022 CZ.NIC z.s.p.o. (https://www.nic.cz/)
|
||||
*
|
||||
* This is free software, licensed under the GNU General Public License v3.
|
||||
* See /LICENSE for more information.
|
||||
*/
|
||||
|
||||
const path = require("path");
|
||||
const pjson = require("./package.json");
|
||||
|
||||
module.exports = {
|
||||
title: "Foris JS docs",
|
||||
title: "Foris JS Docs",
|
||||
version: `v${pjson.version}`,
|
||||
theme: {
|
||||
color: {
|
||||
link: "#0075a3",
|
||||
linkHover: "#00a2e2",
|
||||
},
|
||||
},
|
||||
tocMode: "collapse",
|
||||
pagePerSection: true,
|
||||
sections: [
|
||||
{
|
||||
name: "Foris JS",
|
||||
content: "docs/intro.md",
|
||||
name: "Introduction",
|
||||
content: "docs/introduction.md",
|
||||
},
|
||||
{
|
||||
name: "Development (Linking)",
|
||||
name: "Development",
|
||||
content: "docs/development.md",
|
||||
},
|
||||
{
|
||||
name: "Components",
|
||||
description: "Set of main components.",
|
||||
sections: [
|
||||
{
|
||||
name: "Foris forms",
|
||||
components: [
|
||||
@ -34,6 +47,10 @@ module.exports = {
|
||||
exampleMode: "expand",
|
||||
usageMode: "expand",
|
||||
},
|
||||
],
|
||||
sectionDepth: 1,
|
||||
},
|
||||
|
||||
{
|
||||
name: "Bootstrap components",
|
||||
description: "Set of bootstrap components.",
|
||||
@ -41,8 +58,12 @@ module.exports = {
|
||||
exampleMode: "expand",
|
||||
usageMode: "expand",
|
||||
ignore: ["src/bootstrap/constants.js"],
|
||||
sectionDepth: 0,
|
||||
},
|
||||
],
|
||||
template: {
|
||||
favicon: "/docs/components/logo.svg",
|
||||
},
|
||||
require: [
|
||||
"babel-polyfill",
|
||||
path.join(__dirname, "src/testUtils/mockGlobals"),
|
||||
@ -55,6 +76,9 @@ module.exports = {
|
||||
"node_modules/@fortawesome/fontawesome-free/css/all.min.css"
|
||||
),
|
||||
],
|
||||
styleguideComponents: {
|
||||
LogoRenderer: path.join(__dirname, "docs/components/Logo"),
|
||||
},
|
||||
webpackConfig: {
|
||||
module: {
|
||||
rules: [
|
||||
@ -73,5 +97,8 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
},
|
||||
devServer: {
|
||||
publicPath: "/",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
Reference in New Issue
Block a user