release] v0.22.0-unstable13

This commit is contained in:
Yann Stepienik
2026-03-18 22:08:58 +00:00
parent 2825bc6036
commit 0c151cf987
26 changed files with 733 additions and 314 deletions
+13 -1
View File
@@ -4,7 +4,7 @@
"description": "REST API for Cosmos Cloud server management",
"title": "Cosmos Server API",
"contact": {},
"version": "0.22.0-unstable12"
"version": "0.22.0-unstable13"
},
"paths": {
"/_logs": {
@@ -9666,6 +9666,9 @@
"description": {
"type": "string"
},
"expiryDays": {
"type": "integer"
},
"ipWhitelist": {
"type": "array",
"items": {
@@ -11321,6 +11324,9 @@
"description": {
"type": "string"
},
"expiresAt": {
"type": "string"
},
"ipWhitelist": {
"type": "array",
"items": {
@@ -11344,6 +11350,9 @@
},
"tokenHash": {
"type": "string"
},
"tokenSuffix": {
"type": "string"
}
}
},
@@ -11939,6 +11948,9 @@
"disableHeaderHardening": {
"type": "boolean"
},
"disableLegacyHTTPHeaders": {
"type": "boolean"
},
"disabled": {
"type": "boolean"
},
+13 -1
View File
@@ -4,7 +4,7 @@
"description": "REST API for Cosmos Cloud server management",
"title": "Cosmos Server API",
"contact": {},
"version": "0.22.0-unstable12"
"version": "0.22.0-unstable13"
},
"basePath": "/cosmos",
"paths": {
@@ -7907,6 +7907,9 @@
"description": {
"type": "string"
},
"expiryDays": {
"type": "integer"
},
"ipWhitelist": {
"type": "array",
"items": {
@@ -9666,6 +9669,9 @@
"description": {
"type": "string"
},
"expiresAt": {
"type": "string"
},
"ipWhitelist": {
"type": "array",
"items": {
@@ -9689,6 +9695,9 @@
},
"tokenHash": {
"type": "string"
},
"tokenSuffix": {
"type": "string"
}
}
},
@@ -10284,6 +10293,9 @@
"disableHeaderHardening": {
"type": "boolean"
},
"disableLegacyHTTPHeaders": {
"type": "boolean"
},
"disabled": {
"type": "boolean"
},
+9 -1
View File
@@ -4,6 +4,8 @@ definitions:
properties:
description:
type: string
expiryDays:
type: integer
ipWhitelist:
items:
type: string
@@ -1325,6 +1327,8 @@ definitions:
type: string
description:
type: string
expiresAt:
type: string
ipWhitelist:
items:
type: string
@@ -1341,6 +1345,8 @@ definitions:
type: boolean
tokenHash:
type: string
tokenSuffix:
type: string
type: object
utils.AddionalFiltersConfig:
properties:
@@ -1743,6 +1749,8 @@ definitions:
type: string
disableHeaderHardening:
type: boolean
disableLegacyHTTPHeaders:
type: boolean
disabled:
type: boolean
extraHeaders:
@@ -1921,7 +1929,7 @@ info:
contact: {}
description: REST API for Cosmos Cloud server management
title: Cosmos Server API
version: 0.22.0-unstable12
version: 0.22.0-unstable13
paths:
/_logs:
get:
+3
View File
@@ -6,6 +6,9 @@
- Fixed issue with post-install on compose import
- Support for mounting network disk
- Enforce tighter folder permissions on the config folder
- Ability to add dynamic extra headers with variables like $user, $origin, $scheme, etc...
- Add a UI for extra headers on routes
- Added support for legacy HTTP_ headers
- Fix regression with static/spa folders
- Fix issue with Constellation sometime not connecting right away on new network
- Sync more settings accross servers in Constellations (Rclone and api token/permissions configs)
+3
View File
@@ -7,6 +7,7 @@ export interface CreateAPITokenRequest {
permissions?: number[];
ipWhitelist?: string[];
restrictToConstellation?: boolean;
expiryDays?: number;
}
export interface CreateAPITokenResponse {
@@ -26,10 +27,12 @@ export interface APITokenConfig {
Description?: string;
Owner?: string;
TokenHash: string;
TokenSuffix?: string;
Permissions: number[];
IPWhitelist?: string[];
RestrictToConstellation: boolean;
CreatedAt: string;
ExpiresAt?: string;
}
export default function createApiTokensAPI(apiFetch: ApiFetch) {
+37
View File
@@ -0,0 +1,37 @@
import React, { useRef, useState, useEffect, cloneElement } from 'react';
import { Tooltip } from '@mui/material';
function Ellipsis({ children, title, maxWidth, style, ...props }) {
const ref = useRef(null);
const [isOverflowing, setIsOverflowing] = useState(false);
useEffect(() => {
const el = ref.current;
if (el) {
// Check the element itself or its first child for overflow
const target = el.querySelector('.MuiChip-label') || el;
setIsOverflowing(target.scrollWidth > target.clientWidth);
}
});
const ellipsisStyle = {
maxWidth: maxWidth || '100%',
...style,
};
const child = cloneElement(children, {
ref,
style: { ...children.props.style, ...ellipsisStyle },
...props,
});
if (!isOverflowing) return child;
return (
<Tooltip title={title || children} arrow>
{child}
</Tooltip>
);
}
export default Ellipsis;
+1 -1
View File
@@ -30,7 +30,7 @@ const HostChip = ({route, settings, style, ellipsis}) => {
paddingRight: '4px',
// textDecoration: isOnline ? 'none' : 'underline wavy red',
...style,
...(ellipsis ? { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: '300px' } : {})
...(ellipsis ? { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: '250px' } : {})
}}
onClick={() => {
if(route.UseHost)
+44 -1
View File
@@ -41,6 +41,7 @@ const CreateTokenDialog = ({ open, onClose, onCreated, t }) => {
readOnly: false,
ipWhitelist: "",
restrictToConstellation: false,
expiryDays: 0,
},
validateOnChange: false,
onSubmit: async (values, { setErrors, setSubmitting }) => {
@@ -107,6 +108,20 @@ const CreateTokenDialog = ({ open, onClose, onCreated, t }) => {
name="restrictToConstellation"
label={t('mgmt.config.apiTokens.restrictToConstellation')}
/>
<TextField
fullWidth
select
id="expiryDays"
name="expiryDays"
label={t('mgmt.config.apiTokens.expiry')}
value={formik.values.expiryDays}
onChange={formik.handleChange}
>
<MenuItem value={0}>{t('mgmt.config.apiTokens.expiryNever')}</MenuItem>
<MenuItem value={7}>{t('mgmt.config.apiTokens.expiry7Days')}</MenuItem>
<MenuItem value={30}>{t('mgmt.config.apiTokens.expiry30Days')}</MenuItem>
<MenuItem value={90}>{t('mgmt.config.apiTokens.expiry90Days')}</MenuItem>
</TextField>
{formik.errors.submit && (
<Alert severity="error">{formik.errors.submit}</Alert>
)}
@@ -299,7 +314,18 @@ const ConfigAPITokens = () => {
columns={[
{
title: t('global.name'),
field: (r) => r.name,
field: (r) => (
<Stack direction="row" alignItems="center" spacing={1}>
<span>{r.name}</span>
{r.tokenSuffix && (
<Chip
label={`***${r.tokenSuffix}`}
size="small"
sx={{ fontFamily: "monospace", fontSize: "0.75rem" }}
/>
)}
</Stack>
),
},
{
title: t('global.owner'),
@@ -332,6 +358,23 @@ const ConfigAPITokens = () => {
? dayjs(r.createdAt).format("L, LT")
: "-",
},
{
title: t('mgmt.config.apiTokens.expiryColumn'),
field: (r) => {
if (!r.expiresAt) return t('mgmt.config.apiTokens.expiryNever');
const exp = dayjs(r.expiresAt);
const isExpired = exp.isBefore(dayjs());
return (
<Chip
label={isExpired
? t('mgmt.config.apiTokens.expired')
: exp.format("L, LT")}
size="small"
color={isExpired ? "error" : "default"}
/>
);
},
},
{
title: "",
field: (r) => (
+6 -1
View File
@@ -37,6 +37,10 @@ const validateAndDecodeJWT = (token) => {
};
const verifyJWTSignature = async (token) => {
if (typeof crypto === 'undefined' || !crypto.subtle) {
// crypto.subtle unavailable (e.g. HTTP context), skip verification
return true;
}
try {
const publicKey = await importSPKI(LICENSE_PUBLIC_KEY, 'ES256');
await jwtVerify(token, publicKey);
@@ -188,8 +192,9 @@ const ConfigGeneral = ({ formik, config, status, isAdmin }) => {
}}
/>
{(() => {
const isMasked = formik.values.Licence && /^\*+$/.test(formik.values.Licence);
const licenseResult = React.useMemo(() => {
if (!formik.values.Licence) return null;
if (!formik.values.Licence || isMasked) return null;
return validateAndDecodeJWT(formik.values.Licence);
}, [formik.values.Licence]);
+97 -1
View File
@@ -7,11 +7,15 @@ import {
Alert,
Button,
Grid,
IconButton,
InputLabel,
OutlinedInput,
Stack,
FormHelperText,
TextField,
MenuItem,
} from '@mui/material';
import { DeleteOutlined, PlusCircleOutlined } from '@ant-design/icons';
import RestartModal from '../users/restart';
import { CosmosCheckbox, CosmosCollapse, CosmosFormDivider, CosmosInputText, CosmosSelect } from '../users/formShortcuts';
import { CosmosContainerPicker } from '../users/containerPicker';
@@ -96,6 +100,10 @@ const RouteManagement = ({ routeConfig, routeNames, config, TargetContainer, noC
Tunnel: routeConfig.Tunnel,
TunneledHost: routeConfig.TunneledHost,
WhitelistInboundIPs: routeConfig.WhitelistInboundIPs && routeConfig.WhitelistInboundIPs.join(', '),
DisableLegacyHTTPHeaders: routeConfig.DisableLegacyHTTPHeaders === true,
_ExtraHeaders: routeConfig.ExtraHeaders
? Object.entries(routeConfig.ExtraHeaders).map(([key, value]) => ({ key, value }))
: [],
}}
validationSchema={ValidateRouteSchema}
onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => {
@@ -110,10 +118,20 @@ const RouteManagement = ({ routeConfig, routeNames, config, TargetContainer, noC
values.WhitelistInboundIPs = [];
}
// Convert extra headers array to map
const extraHeadersMap = {};
if (values._ExtraHeaders) {
values._ExtraHeaders.forEach(({ key, value }) => {
if (key.trim()) extraHeadersMap[key.trim()] = value;
});
}
let fullValues = {
...routeConfig,
...values,
ExtraHeaders: extraHeadersMap,
}
delete fullValues._ExtraHeaders;
fullValues = sanitizeRoute(fullValues);
@@ -147,11 +165,20 @@ const RouteManagement = ({ routeConfig, routeNames, config, TargetContainer, noC
}}
validate={(values) => {
let commaSepIps = values.WhitelistInboundIPs;
const extraHeadersMap = {};
if (values._ExtraHeaders) {
values._ExtraHeaders.forEach(({ key, value }) => {
if (key.trim()) extraHeadersMap[key.trim()] = value;
});
}
let fullValues = {
...routeConfig,
...values,
ExtraHeaders: extraHeadersMap,
}
delete fullValues._ExtraHeaders;
if(commaSepIps && commaSepIps.length) {
fullValues.WhitelistInboundIPs = commaSepIps.split(',').map((ip) => ip.trim());
@@ -412,6 +439,75 @@ const RouteManagement = ({ routeConfig, routeNames, config, TargetContainer, noC
placeholder={t('mgmt.urls.edit.advancedSettings.whitelistInboundIpInput.whitelistInboundIpPlaceholder')}
formik={formik}
/>
<CosmosFormDivider title={t('mgmt.urls.edit.advancedSettings.extraHeaders.title')} />
<Alert severity='info'>
{t('mgmt.urls.edit.advancedSettings.extraHeaders.info')}
</Alert>
{formik.values._ExtraHeaders.map((header, idx) => (
<Grid container key={idx} spacing={2} alignItems="center">
<Grid item xs={5}>
<TextField
fullWidth
label={t('mgmt.urls.edit.advancedSettings.extraHeaders.headerName')}
placeholder="X-Custom-Header"
value={header.key}
onChange={(e) => {
const newHeaders = [...formik.values._ExtraHeaders];
newHeaders[idx] = { ...newHeaders[idx], key: e.target.value };
formik.setFieldValue('_ExtraHeaders', newHeaders);
}}
/>
</Grid>
<Grid item xs={6}>
<TextField
fullWidth
label={t('mgmt.urls.edit.advancedSettings.extraHeaders.headerValue')}
placeholder="value"
value={header.value}
onChange={(e) => {
const newHeaders = [...formik.values._ExtraHeaders];
newHeaders[idx] = { ...newHeaders[idx], value: e.target.value };
formik.setFieldValue('_ExtraHeaders', newHeaders);
}}
/>
</Grid>
<Grid item xs={1}>
<IconButton
color="error"
onClick={() => {
const newHeaders = [...formik.values._ExtraHeaders];
newHeaders.splice(idx, 1);
formik.setFieldValue('_ExtraHeaders', newHeaders);
}}
>
<DeleteOutlined />
</IconButton>
</Grid>
</Grid>
))}
<PermissionGuard permission={PERM_CONFIGURATION}>
<Button
variant="outlined"
color="primary"
startIcon={<PlusCircleOutlined />}
onClick={() => {
const newHeaders = [...formik.values._ExtraHeaders];
newHeaders.push({ key: '', value: '' });
formik.setFieldValue('_ExtraHeaders', newHeaders);
}}
>
{t('mgmt.urls.edit.advancedSettings.extraHeaders.add')}
</Button>
</PermissionGuard>
<CosmosCheckbox
name="DisableLegacyHTTPHeaders"
label={t('mgmt.urls.edit.advancedSettings.disableLegacyHTTPHeaders')}
formik={formik}
/>
</Stack>
</CosmosCollapse>
</Grid>
+5 -4
View File
@@ -36,6 +36,7 @@ import RouteManagement from '../routes/routeman';
import { getFaviconURL, sanitizeRoute, ValidateRoute } from '../../../utils/routes';
import PrettyTableView from '../../../components/tableView/prettyTableView';
import HostChip from '../../../components/hostChip';
import Ellipsis from '../../../components/ellipsis';
import {RouteActions, RouteMode, RouteSecurity} from '../../../components/routeComponents';
import { useNavigate } from 'react-router';
import NewRouteCreate from '../routes/newRoute';
@@ -75,7 +76,7 @@ const ProxyManagement = () => {
const [openNewModal, setOpenNewModal] = React.useState(false);
const [isLoading, setIsLoading] = React.useState(false);
const [tunnels, setTunnels] = React.useState([]);
const { hasPermission } = useClientInfos();
const { hasPermission, hasRolePermission } = useClientInfos();
const isAdmin = hasPermission(PERM_CONFIGURATION);
function setRouteEnabled(key) {
@@ -282,8 +283,8 @@ const ProxyManagement = () => {
},
{ title: t('mgmt.config.proxy.originTitle'), screenMin: 'md', clickable:true, search: (r) => r.Host + ' ' + r.PathPrefix, field: (r) => <HostChip ellipsis route={r} /> },
{ title: t('global.target'), screenMin: 'md', search: (r) => r._IsTunnel ? (r._targets || []).map(t => t.targetURL).join(' ') : r.Target, field: (r) => r._IsTunnel && r._targets && r._targets.length > 0
? <><RouteMode route={r} /> {r._targets.map((t, i) => <Chip key={i} label={t.targetURL + ' (' + t.deviceName + ')'} style={{marginBottom: 2}} />)}</>
: <><RouteMode route={r} /> <Chip label={r.Target} /></>
? <><RouteMode route={r} /> {r._targets.map((t, i) => <Ellipsis key={i} title={t.targetURL + ' (' + t.deviceName + ')'} maxWidth={250}><Chip label={t.targetURL + ' (' + t.deviceName + ')'} style={{marginBottom: 2}} /></Ellipsis>)}</>
: <><RouteMode route={r} /> <Ellipsis title={r.Target} maxWidth={250}><Chip label={r.Target} /></Ellipsis></>
},
{ title: t('global.securityTitle'), screenMin: 'lg', field: (r) => <RouteSecurity route={r} />,
style: {minWidth: '70px'} },
@@ -316,7 +317,7 @@ const ProxyManagement = () => {
</div>
}
{routes && needSave && <>
{routes && needSave && hasRolePermission(PERM_CONFIGURATION) && <>
<div>
<br /><br /><br /><br />
</div>
+4 -4
View File
@@ -462,9 +462,9 @@ const HomePage = () => {
<Grid2 item xs={12} sm={6} md={4} lg={3} xl={3} xxl={3} key={route.Name}>
<Box className='app app-hover' style={{ padding: 25, borderRadius: 10, ...appColor, ...appBorder }}>
<Link to={getFullOrigin(route)} target="_blank" style={{ textDecoration: 'none', ...appColor }}>
<Stack direction="row" spacing={2} alignItems="center">
<Stack direction="row" spacing={2} alignItems="center" style={{ overflow: 'hidden' }}>
<DashboardIcon route={route} containerIcon={route.ContainerIcon} className="loading-image" width="70px" />
<div style={{ minWidth: 0 }}>
<div style={{ minWidth: 0, overflow: 'hidden' }}>
<h3 style={blockStyle}>{route.Name}</h3>
<p style={blockStyle}>{route.Description}</p>
<p style={{ ...blockStyle, fontSize: '90%', paddingTop: '3px', opacity: '0.45' }}>{route.Target}</p>
@@ -477,9 +477,9 @@ const HomePage = () => {
<Grid2 item xs={6} sm={4} md={3} lg={2} xl={2} xxl={2} key={route.Name}>
<Box className='app app-hover' style={{ padding: 25, borderRadius: 10, ...appColor, ...appBorder }}>
<Link to={getFullOrigin(route)} target="_blank" style={{ textDecoration: 'none', ...appColor }}>
<Stack direction="column" spacing={2} alignItems="center">
<Stack direction="column" spacing={2} alignItems="center" style={{ overflow: 'hidden', width: '100%' }}>
<DashboardIcon route={route} containerIcon={route.ContainerIcon} className="loading-image" width="70px" />
<div style={{ minWidth: 0 }}>
<div style={{ minWidth: 0, overflow: 'hidden', maxWidth: '100%' }}>
<h3 style={blockStyle}>{route.Name}</h3>
</div>
</Stack>
-1
View File
@@ -1,6 +1,5 @@
import React from 'react';
import { useCookies } from 'react-cookie';
import { logout } from '../api/authentication';
import { SUDO_PERMISSIONS } from './permissions';
const isDemo = import.meta.env.MODE === 'demo';
@@ -153,6 +153,13 @@
"mgmt.config.apiTokens.restrictToConstellation": "Restrict to Constellation network",
"mgmt.config.apiTokens.tokenCreated": "Token Created",
"mgmt.config.apiTokens.tokenName": "Token Name",
"mgmt.config.apiTokens.expiry": "Expiry",
"mgmt.config.apiTokens.expiryColumn": "Expires",
"mgmt.config.apiTokens.expiryNever": "Never",
"mgmt.config.apiTokens.expiry7Days": "7 days",
"mgmt.config.apiTokens.expiry30Days": "30 days",
"mgmt.config.apiTokens.expiry90Days": "90 days",
"mgmt.config.apiTokens.expired": "Expired",
"mgmt.config.appearance.appDetailsOnHomepageCheckbox.appDetailsOnHomepageLabel": "Show Application Details on Homepage",
"mgmt.config.appearance.primaryColorSlider": "Primary Color",
"mgmt.config.appearance.resetColorsButton.resetColorsLabel": "Reset Colors",
@@ -673,6 +680,12 @@
"mgmt.urls.edit.advancedSettings.skipURLCleanCheckbox.skipURLCleanLabel": "Skip URL Cleaning (preserve double slashes in path)",
"mgmt.urls.edit.advancedSettings.whitelistInboundIpInput.whitelistInboundIpLabel": "Whitelist Inbound IPs and/or IP ranges (comma separated)",
"mgmt.urls.edit.advancedSettings.whitelistInboundIpInput.whitelistInboundIpPlaceholder": "Whitelist Inbound IPs and/or IP ranges (comma separated)",
"mgmt.urls.edit.advancedSettings.disableLegacyHTTPHeaders": "Disable legacy HTTP_* headers (disables duplicating X-* headers as HTTP_X_* equivalents)",
"mgmt.urls.edit.advancedSettings.extraHeaders.title": "Extra Headers",
"mgmt.urls.edit.advancedSettings.extraHeaders.info": "Add custom headers to requests forwarded to this target. These headers will overwrite any existing headers with the same name. You can use variables in values: $target, $scheme, $host, $origin, $clientIP, $user, $route, $path.",
"mgmt.urls.edit.advancedSettings.extraHeaders.headerName": "Header Name",
"mgmt.urls.edit.advancedSettings.extraHeaders.headerValue": "Header Value",
"mgmt.urls.edit.advancedSettings.extraHeaders.add": "Add Header",
"mgmt.urls.edit.advancedSettingsTitle": "Advanced Settings",
"mgmt.urls.edit.basicSecurity.authEnabledCheckbox.authEnabledLabel": "Authentication Required",
"mgmt.urls.edit.basicSecurity.headers.headersTitle": "Headers",
+64
View File
@@ -0,0 +1,64 @@
# Cosmos Server Go SDK
Auto-generated Go client for the [Cosmos Server](https://github.com/azukaar/cosmos-server) API.
## Installation
```bash
go get github.com/azukaar/cosmos-server/go-sdk
```
## Usage
```go
package main
import (
"context"
"crypto/tls"
"fmt"
"net/http"
cosmossdk "github.com/azukaar/cosmos-server/go-sdk"
)
func main() {
httpClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
addToken := func(ctx context.Context, req *http.Request) error {
req.Header.Set("Authorization", "Bearer "+token)
return nil
}
client, err := cosmossdk.NewClient(
"https://cosmos.example.com/cosmos",
cosmossdk.WithHTTPClient(httpClient),
cosmossdk.WithRequestEditorFn(addToken),
)
if err != nil {
panic(err)
}
// List routes
resp, err := client.GetApiRoutes(context.Background())
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println(resp.StatusCode)
}
```
## Generation
The SDK is auto-generated from the OpenAPI spec using [oapi-codegen](https://github.com/oapi-codegen/oapi-codegen). To regenerate:
```bash
bash scripts/generate-api.sh
```
This runs on every commit via a pre-commit hook.
+286 -282
View File
@@ -220,6 +220,7 @@ func (e GetApiSnapraidNameActionParamsAction) Valid() bool {
// ConfigapiCreateAPITokenRequest defines model for configapi.CreateAPITokenRequest.
type ConfigapiCreateAPITokenRequest struct {
Description *string `json:"description,omitempty"`
ExpiryDays *int `json:"expiryDays,omitempty"`
IpWhitelist *[]string `json:"ipWhitelist,omitempty"`
Name string `json:"name"`
Permissions *[]UtilsPermission `json:"permissions,omitempty"`
@@ -955,12 +956,14 @@ type UtilsAPIResponse struct {
type UtilsAPITokenConfig struct {
CreatedAt *string `json:"createdAt,omitempty"`
Description *string `json:"description,omitempty"`
ExpiresAt *string `json:"expiresAt,omitempty"`
IpWhitelist *[]string `json:"ipWhitelist,omitempty"`
Name *string `json:"name,omitempty"`
Owner *string `json:"owner,omitempty"`
Permissions *[]UtilsPermission `json:"permissions,omitempty"`
RestrictToConstellation *bool `json:"restrictToConstellation,omitempty"`
TokenHash *string `json:"tokenHash,omitempty"`
TokenSuffix *string `json:"tokenSuffix,omitempty"`
}
// UtilsAddionalFiltersConfig defines model for utils.AddionalFiltersConfig.
@@ -1167,6 +1170,7 @@ type UtilsProxyRouteConfig struct {
Corsorigin *string `json:"corsorigin,omitempty"`
Description *string `json:"description,omitempty"`
DisableHeaderHardening *bool `json:"disableHeaderHardening,omitempty"`
DisableLegacyHTTPHeaders *bool `json:"disableLegacyHTTPHeaders,omitempty"`
Disabled *bool `json:"disabled,omitempty"`
ExtraHeaders *map[string]string `json:"extraHeaders,omitempty"`
HideFromDashboard *bool `json:"hideFromDashboard,omitempty"`
@@ -23759,288 +23763,288 @@ func ParsePostRcloneVfsStatsResponse(rsp *http.Response) (*PostRcloneVfsStatsRes
// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{
"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",
"sWkPvn76+v8CAAD//240b2D7fAIA",
"H4sIAAAAAAAC/+y9aXPbOLoo/FdQet+qdqpkO0n3nLon3xzL7vaMt5KcTN07SflC5CMJbRDgAUA56lT+",
"+y0spEgRoEjZTuw0P8x0LGLHs+NZvg4inqScAVNy8O7rQMD/ZCDVex4TMD+85/FK/zfiTAFT+p84TSmJ",
"sCKcHf4pOdO/yWgBCdb/UqsUBu8GfPonRGrw7du34SAGGQmS6g6Dd4Mr8wXdE7VAM4lmBGiMZAoRma0I",
"myO1ACQg4QoGQ7MeIiAevFMig2/DQSQ4O/gnn47tQv85ubrstLz/X8Bs8G7w/x2u931ov8pD39ieDfyT",
"TxGJgSkyIyB8i8wUofLgiIJQj7a48pieRZkPKOJsRuZo7/pqcoM4o6tXg+py3n6v9XxIY6wgRri6rg+1",
"ZR2Pry6PzedHXlpp4Ib16Vbtlvf2u66vui7PdU4YTsdHZ6MnObuNwRvOL2/ZYa1vv/tiGxf5behmk25d",
"MzLHKTk4FoAVHF2f3fA7YI4m6Cap4CkI5QhkZaaC/EklCJvrE4AvKRGrEV7J0mfCFMxB6O8k/feCKKDE",
"Dk4UJNI7kPsBC4FX+m+GE/A2TEEkRErCmayMuP0kr4uevgkF4PiK0VVp0innFDCzX/UKInXDjzmTCijF",
"G2dSNP5WJpn/sRv5PNzkHMPSXYwuJ/Z2g9cQZVLxZHQ5OWFKuN867LyyZjfKyncIMZNHcUx0M0zfUx7d",
"6ZuT3a4uZtJ0fU+x7e8/0pjJU0zpFEd33mFjJq+5UJ5v35pPE8vFlGMRj3mmoH6Wx5wpTBiIsygA1EWL",
"ccaY/m0TEdYtEGEzjvZmXKDJyfjj0fU1Enpa+Wow9Ox5tAWd/iAxnAqeFHvwH90fXCpv/+CWLnjsR6fL",
"EJ5dY7W4FjAjX7yfb7CYg38RHyRsLLC09A8SvCOX0afpcoFCC7IVoB7dUdMyggeTyZ3J4NNRuy70bOsB",
"GVQL3wbcF7jYYuGCf1mZ9jnLGw70aDh4ugbjLltd+XqgwL2vz+JgBEsSgSFlG/J4dXtT3SJA48wQ+dIS",
"/OUc2FwtBu9+fTscJIQVfw7ru2IkumM79NzYcWkJpTHb7t6KCY3bv86mlEQa44M8O+Iy4fKySoNKUsJD",
"jomwJZFkSsF/AyT1I6Q8+ULUxorK3eQ5mS/UgmcS6uRfk3tafDeilpfcE3nOcfweU8wiEKGZxkBxQOwo",
"w0B9CfbYZD7/xrnVJSc/Nx0OUnOD/4LVdvypQBNJdwGpk5ioRoDqejePfu4Bimc5/sFaJakuG4u5PJER",
"TiGuX9eNyACRGYp4kmAWIyIRplrkXCGwfdBeApgZE4HGOYQlwkVzShi8Qnv/Jizm99LZE0j06sALdlgp",
"HC0mKgYh6ks5Ml+NIUIqzGIsYgRCcNE8FmHthiIszdQQJfgOJEq5NLiJMmlkJQUCR6Zz41w8U+0m45lK",
"M+UdLEpin9xmz1NxJDKG7hfA9GBC5aaZ4po1eLeXeHmCCfMj6mj9zYOToCXxlBPm2fBJ8e2x1wtsWZ/u",
"nEiF+AwBWxLBWQJMoSUWBOv7UxxJUIiwh8z6JeUSYi3UW4Sh9Go2ePefZqGAYXWgu0xADb59HoYWbcdG",
"qRn823CwAEzVIlqAZc3t5loj+R+mey6A1Kb9Yz06sl+mINGC3+uDsj9Xzknju12ROYlFiVluDJx/8XG6",
"BM89XTQx1kegJzRNNOkgCt1jiVIs9alMV+arFX64QHtwMD9AEc9ojKaA5CqZckqiV75ZKZ4CtfdVaIbX",
"FcJX19y8V2QHMmCkOFILIitwVKO4CY6O4liArEvYgwscIfcx3/r67j6xT2wEqYAIK4jf2amsIZZIFBdf",
"kCQsAnR0fYaWbw5+++0AfZCATlhscG4CSmOZPLgo1oGI5mY4PvCdEwN1z8XdiEiNMB7acyaRa4PivJGP",
"cHH2PiPUM8DV5fsPZ+cjlIDCMVYYqQVW6B4EoBhmhEGMOCuBwYhHdyBmhEInNOUpsAC9v0oN/dHffCuX",
"C6C03muif0ZaYDEN9mdcJPrWxh8uh+j4YjREJ5c34/99fXV2edNppWYlVyzyIMXZDCmRwRBFlEuwa0Z4",
"pkCYA3qDLK+BGEWUaEoXExlxxiBS0s9UpeLphMwZ9u3Q/G6IpOKp4ds1wF5vQ7e5IQl4uZz7gPYIQxIi",
"zmL5qnngkhyt1CrINwueKbV8kUg9KEZKrYaIsIhmsWYp9pzITNMPIhHjyh5g7D8TzdXrE36Q5pQ1bBJK",
"DeOyCGp47558pfGIxFBF2yHCVHIks1TTcCMwvJsLnqW+I1xymiXQhiqt6YmfKrmR0F7CM6bkKz1xbIB1",
"k9HVBtSoTNh8RDxncJwJYcFKQKS4WKG963+PXq0ZqJVDzAFNAVGcMQ2Ng2FLW5ePTdUFaS1vLS3AtmOA",
"iiRwMMqcilzne/8HBEdaTjXgQ9gCBFEHKO8hERagebGmlhAbRmShEzHMuIPnA2uAKAyZ1SnG9oMGP31S",
"LEumIPRNaV0CokyRJaAZJjQToCkqxGDkOf2ZxCDKSKIXkDHHeA8+sdLy87V78ciIWGePfno3mjS7UQ36",
"KQVJqlBJVpEIKxRnIpfvzEpQCoLwuFjZtf3zUddVnqgO/va2iSKYkr8ATWHGBbi3THtdpr+0F5FpwOf3",
"zFy0ciahjSlBqvyKdQvdMQVhWENJhMIqKEcdfGJHDOnzWyFJSQQ1uDRdY5jhjKqDT+zGSEAFmL77xL5+",
"Q++KxqVL+MS+fhpcXl2efBroFo5b11ocX4w+DYZI630HBwe6JXyBSP+daeFZOuSnq7z1/uSPk/Nz3cfh",
"v+6jyeOaHKgFkiupIPlF5ku3XLMTY1Rr7vJIEOK4Un5jJDEqwT0mKgeGHP8KzcReIUcLvAS0yNj8IEDN",
"/G/efoNuN9uQ3l6cUcukHmBDcxL5ejifrSM24tZB8TRQMZ0Vv3rednB6i+O4m11Yd4oFTzv2snAWsNG5",
"Fd6GzXhpdisXWEDgsS9Ks/IXS7rzD6BuN76XFYYUWCxvrX03xNGbALjd4Y/sPFdM/zLwAaMzqXV+8Orc",
"4VYCFtGiY7+KnWGLMcHzuVDsu01rleuufZTAt1rR7Xg2cxL7oWtDo384NJSU+E2lPKx7eyzJnIafJnbQ",
"nmswSQm763iICY40TcmV51r7BJJbShKifPKX5JmILEFXAhOmpE8E10MIkFqYCe7e6bu3Sej10TWQT4L2",
"ExDGWG3n8B5tmtuiOrzIcaluCZMKW123Q09BloTCHOKwjwEOmOjto3LXJ0DPS1rtITBjmpt7J9XitiBq",
"dcvTjhTD6JG3PAXm36rWZm/nAkdwmxbCrE8O5+mtLJRunyYt8Bzy9e2OYnIlI/VQPHXat0dNDpG0XH9u",
"0m9b3bdRXg8u9P/7rsNpqrcxEdufeCyp213CqTLZurjDmT1gP5wHceDbzgv6o8o4wjpy/YJKWmpAS2yE",
"31z32Uly3xyu8wHkhK/+UmUsQjj4ZhoLsgwAJjDd7Zaky/8KPKvp86zia+U1FidekHD2i1bA3mbTZ9dH",
"F2GiF9ygl/0+Agv3G/v1ryjJpNahUMbI/2TQzgDU8QRqBz7HCu7xyk9TsymDR0HADf5bB0NKsOwqa5N0",
"+VujaKNBs6FB5118NKTY4/ITRpIH3PZwYKUv/1mEfK7abOqUCw/qfXxcRhPUAHfSq4AtP2LRFUDCknr+",
"/Lz03M49mCdr+1iEEWEKSZ6/sKAIM0TmjAtAr70Ww8cgEgkk57lMHpKUg358WpJ9T1hM2HzrJeZPqhc4",
"LfHca05J5KcJATmlAezs25OjABV88rmHPaES0CT9S7s8+bRGB+/ULR4wdp7ZUaz6tA33ZftsuagWJG9H",
"h0u3isjM767sGq8ox3FIfDk2PmWdBZiwXzkWwKzRf4YDBLiJN3bZZ0LmAiu44X9wqXKUrm5yoZTfc01/",
"kNuXYPrnrX1LmRO1yKa3EU9u8V/ZHcbi1rrp7Wu0AHErRXRbuI97xYjcLXZnMHZRNm6Ymry2XuyYU3jg",
"LHqIhhlwnBBW8YUNBwOYtoVD79l1Rw6F58DURdC9DWeKW69a//cpju6ytN2m35u2623bvlfGa2pE/Bgy",
"BYXt/AHsMv6uEB9rIaAWjNDCBl064zVkdQxiWG/JPDeJVRFscCYrrtYexzCxu5m5HtvkQ3Ks8BTLlu7O",
"I9d6PaB7b8ppw7+xyIMQPJTOtr1KgZ2NRua9qbHhBwniAjM8h9wM7GlqiFSXqxmVe2jBLcGEdhngpNTB",
"mGITSPEcugzxR7WPo5RRlxFubq7XvQmLxPsW6EJJBCzALyifzwmbn8MS/AasBIs7UF22eVHuoUfgbM5H",
"7/2jc0YU13+ZQMaHkmkbDOkTXIt5yt5PdcBK0pjd+leaxtltQO69P1sbWz3eUgbyj40TT1f76FWprz9I",
"IuEKJtbI2JLLlLusb8lx5ovTo4A91LBcS1EDarlpYfhkkym0ZUzh5vrUApJO2HZT6rApepSxv4KFPjHE",
"qGsHF86lrS5jUCzVDZ7fEJ9Kfb7+mD9Na76FjIuv/lFrbwvivIatV9w9lkgPihSez8Hny+cFcUzYwWUB",
"i/5Hakwpv9dU5JxHmJ5dH0VR1QhRjX47XmBKgc3hWvAliQMCa8xklDdc39DuWmbjM5cRF4/1cDMSYQVB",
"ddOQnXja9C3YtxzUUPvIE2KcYlYBIV3Key78L9hSUsNHAvgBfnlaUbPh0Dd/VIRRif9NaBxhEZfOq200",
"gTWjaH39ynqkeIyiRhcylpbNJ91ygAhnY4gyIZ1Ro95Cj4rnxRvdduPOdalDKS72lIsIKnNtvhv62iGB",
"iQSJMLMxBohYb10zFYowY9zYwxIcAxJ5L7pCetp9zujK73mYr+pyY//+NZVbuciE9SIYZ/vemYdomikk",
"FaEUUcDLSq+ixye2lzEKUqLKLGTt6WxCPxiKOPszYyb6wRu3EYaTY5pJBaIEKqGGnEkiFTBrxwGWJZog",
"R/nPajAcRNg5GsZAYY6V+7dxNSpRaAfpw8GXfT3M/hILjbNSj1ea5jQzrkmlX47z8Uu/jUpTVX52sxYb",
"GBWKe6t4Ts3+izPZlSSGz92aOevxflW03Y5RZTzXCkjtOrcPsQECTo8q3XWLIUodNuLdq1jj3BLlGsbX",
"OKHxNw/q8btJF+brDRdp61TgIpccKrFS6IJdJLKvh4TNEWcO1fQkQ2OY/cQSvNLkAju/XTeCQBhpvoZS",
"rBZD/TcsIbfYxgefmJvduTQ7H+PczzdJZxLt5ZZ5nDsVLjHNwBsSocKxz2awTjd7U+5RwGKrnrplYUvs",
"NOnHSpcGFLiuco+coohUkCU2OWzW/xLGN0zjePEPISleGtc589925KU05/i6GL30q/fH8SSftPSj77fx",
"xK2p3M4ur9j2zcY1VglA7s7SzreSy4NTQq0oVfes1D/nKGAhMUs5Q4b7Ow4syV/wfqV8ztIT8hdoPmPR",
"STesjDXUfGequ5qgmJsFkYXLecTZEgwSKK6B3kVGs7lzQC2CDC0ifGJxGTP1FBrjDtCpxrYvOEkpDPUX",
"Slj2ZWgCkDwzfWKZ1Oj7y90vQ/RL8ovG1V/mvyC5Ygp/OUDvJyON6jybLwyq3pNY8+Q1xt4TtfjErIli",
"iDIjWyDjpzRfKLNXu16z4WsQETCF52A90yvI73P9DiPCjUPLHAM0ExjkuDdwiD8YDlhKUv23I/ItQV6P",
"/t6OqP/5MR9V/3HjRtb/vsQJxNd2Bv33cT5Lsc6Pm8TAZ8Jvp+lVWPJjPYTzY54GzKoym2r63fKhKX/E",
"co9e9a3+waU6S/0hdmfXub5o2MbZdR5N5iP3ukmeiaQ+lP5SGcyEr7iXz2GXnVzgtOlwWxk2Nk/F52IS",
"mn8CDV5UJpqq3rdM3N59Hcy4SLAavBtkhKlf3waCK4zx4eDUtB0ReefXpmMi/Ylh8km66Yebgex69GKs",
"Uk+fkSJf8gWIefh5bCowixad7eELfs8CenTG1HXQnZenSgYzJGEWMO9uHEOx5sp0jWegm4UTFe26GwYG",
"FAI6rJ8sdNtqaQFuRN82q5EQZZAmTP3Xb/6wu1UK8uB3gdOFpZYjrykr/3XXOFp+v09hCRS5qygCQYco",
"tRYkE3F1B6tDwwJRiokocX7C7F4IZyYQ1ix1P2fzQ2M1c574OYt3M+3btp8YYZrl2qZykccPFyFzpRkw",
"RWkmUi5dfgqzjLG7jndGKfbF1F16XWfKIc755u2SDsKDNpFce2NnCZ7DGdMn4AHlM18M7ygn9S7D277z",
"NDIBQmcjvUjMrKWxdPBFOkWT98HbNyZzkApFmEYZNdHJM8ETPdUnZob7Rbr8bg420Z61bNrgTadQ2VGk",
"DbdegZD2bqarT6ywgL4yC7vkCvIAKw0MdvqYzGa6Vz43+r9jSPnIjvp/0RQovx9ak+ontuA0luUprYE1",
"wYzMzE9meAEzEMAiWNtgvfHTH4lQGaZaoq2fe+ljEYPEFaYVkddOvw5mxZTmp2DCWT8xwzD1gfDZlihx",
"nhClL4GwdXy4tQfdQaoMsE9xdHePRYz0qFiRKaFErWwQuV1oLVq8RDOwiBZEQaQy4dnvUelrIVxgEd9r",
"Kfb4+gMqd1/HydkTEBnTOOc9ZZypBfclBTG/F0GXJXyzPZwnFC5yj2hRfAE2dI2oPB+Fg1WjglfaqoUw",
"Mv3F0dnlzdHZ5ckY7a0j8Yu42HXIunf1ejLwpco4th8MejEX5YcpSjR2zd0BRZiZZAegaivnmrQlWnDL",
"o9fCcNruRbGWLqYcYdWYT87egCUlGzGY+RUYnFbcKollvHIwvVbTTEaKytOH7RMPy/DujCrG7NEdL/7R",
"Di8CZ+n8l9YPGx0TdQRTdBxXx94EDbsjN04pm0qJwNoL0FSjdgPmAckBUIEJRmWvwI/RQQUsCc8kWoIw",
"edz0uBbO0TQjNAbhLnR90DbeX4BtgIzJdviJmcRBRWA+Ycg6MyKjUrNVwgU83fUZzwkDOx7wtR86vcEV",
"gGhFBruqT2x8eox+/fXX/zYB4/suYhztGbFsfHqsP11ixl8FxRpjpcRLTKjhq2SGUgHSEIdScgx3mvl5",
"cLUAcU+kH+WtteGjvT9fhp/S5/wM3G2XLruGvvZyHxd7fcufrwXTDhHBXpm2jmalFsgKBOX7wFOeKY/Y",
"VpyBBfMqmv0iDfDkUo/mBtYkdWC9ZNdPxe22svHE7LHB5QlVNgQJ8wflEaYWBYMwZ9uYrDYa+iHhzMrI",
"Gk9TLNTGyEoCnR1Y/dmTZWWSA9FVYZObWJtcaQxp4KdIDRXg91wGwfZKhkG2/eSfmJ0d7YHh9pjSlaEj",
"LlfZK++yrLNlfU3X5vc6E0zd74+FJ/pyPrGcWmiRwKgvibEUrtPqmE0eusHsLdPVAbopBjVj2BHJbGMN",
"aUZpLsbnOgESMCdSCT+iirWs7XvLLD5aLYK6DCZhbcLqAXbVa5LoZLRNOb1yu4XQbtd/gC4yqkhKy70i",
"zD4x0zCHfKnFxrLuA3K9FC25ZjIza6nT6OrRAdH02J3gJ2aPsDg7I116jlsunDG71NLpSNKwaKsE5TvQ",
"v86BaSDXirPhrbKuhx10yrygr/AGzwP3p79UL8+u39iBD5X5WqY69quhPeaS3Hk7bUrToeKwiwuyfcxY",
"WuINXJAlT2YMsxSLHJ9YAcuM2zE86pt5VbAHG2EJFcj5xD4NMmZdaz4NNlsSK4XbJ/UplMFsujLHfzbq",
"eN6cq9NJV7Y2tr3qnMB+yMXCEC/LOZNtXc6fZBiZ0TnR2cgmupFehfZhmiwqK7JrK2aTjcpk8vOR3I/2",
"Q76YmnLpOqI9J0bRFToaX5jH4FcHXawt4+KqNj289MY6hkm615gWk2dSawnb09hC0HVo10S8GjopBEI5",
"K+ECTSlUzfq35kwNr75hDf65ztiSbDkrDW83/it4tLzF2w/lnM8Ja84as/PNlR8SSj3fvP1fla7/q/Uu",
"trwwmA1duxZjkNDyun9ISmk7+7DFFY0NIwbxY2/pv72yll2Z8+8r9f7Hm+rEb3a54+oEwfOZZDFvPJvH",
"gsPtwPdBgnh7enS8gCLdeX05KuB/vDGbbbZtqjKYN0PFQyhFHmI0BplyJn2RvFabtBH9ygawOo8GrSb9",
"qx2T88YyBbw64yO1/cEnVG0FZKD349da4fcs4JX8DOoSDC2Y/YGl/23QfJ1kM38Fi4YrjGNjIjwlVIGQ",
"oZsMHpoKMUbzKNdtKXmNrQ0/80jtcPBmsKNIBU6+kpej5WjHRZ8iNUQg9MO48Qsyn4OAuGNg5maCjXJQ",
"xBIECfiKq4XgSgVXpASO7gibX4AGuAfEdNZPt042GxwGO0iyvoOvzZUneQ6dZRSM+9qEz2ZRsR5fWHeI",
"MF8fGHY0IWxOYTOQsR50ZyOP2jrg+6qzbSYlaZErz/9V6M/ThvwpAZB8YBB1OEyytrlTIuAeU1viCWJf",
"+FS3QM7m8h/fr3oVfozqVdN21avixmC3mMnZlvJWwYIcMb/karJi0SWPQ1G4jZBEUoFZIA0GX4IQJIZL",
"mGYU56U2mgPf1YLIUaVIS71JxphzD3zUFGXf2kF6ARc1WL8LRPDswqfLeHgXEux9Yb2BnEfr5DJ1GJg2",
"fGwM4moMkkqzNIWG6HMtoAdHXq7fElrzq9FGNPFm4SwTAqJP6zrk5CXvSHotMgbGXyeADkWjUrqh9ozg",
"pBqw7AnrOzPJpwXcnE92wMeZ4EnwIv3iEFdktjImjpBPXNMthyhLJsM7aLj68MmVgqbrDm+Xk+PHDF3E",
"UQSpOqI0vwwP1yknUugQjmnaTkxK1hM2Jyycm2Hhog9CgYGmSUNBJROBFQo4jHDaPLrjOaXQBaOwh4NM",
"o1KQad7l35ioQCGuaod2UaljkJwunQ3X560bgb6FSSlOcgxMyx/+VeePMhdaTWTzo0wtNiI0S423hrPm",
"qFCynvzXFvuOi4ONWsTBmoY7TZGz4TyK1NYJCnj0ai7ZJTz7utQhL/AlFxejy0ko/pzObs4nwUBY9z0E",
"levPGiOlCwHsljHUDvERUxJ/YCoUxStp2NKtqIwaInmDcoD5tPPCFZXL5kUrkUkFsb6TztlSMgmnXNxj",
"EUN8ykWQcLePRa4kCVpXGypQpQzTnxvJ/okQXIxBZtSb5jMUOW598gJB2rn9rT3/qaUKqeugc8GzgCYH",
"X1LM4hDbvifxHLopEOGVai5k4s88KSLaW5dSwRWPOA1nCd5d8Jau5NEDc+k+UgJDT76T2jHZuboqHXZM",
"GxPa5QYr/dpfWSZopy1X0pLUE9bGgcS58Wb2n0oiZ9EmbxmJG1C+ZLhdx8G9Gb4dvnk9fPNm+Pb18O2b",
"4a+vh7++Gf72evjmtf7fm8+1t+gi/s0589oaoifji9uj0cXZ5eDdwLkb8VS+Qy434RDJRaZifs+GKDO5",
"qYZI6fUwTAfDUvfb8cnRyDiMwz2ifC7zr8dXl6dnv38YH92cXZlJQB2mWEUL5/Q5RJo5+hpXhozytCa2",
"3fhkdHJ5c3Z0Pqm2EmBc/jGVaA/YEi2xkEOUi+xyiOyNmCrRZqTzq9/N3o/YSi97DvG+jbUQQ3RxeoSK",
"Wyq3v/33ydG/Ap0YN/1s1mPXaXwyufowPj6ZmApqzPiW5JYsvSZLkoZ5XdEhcga8ITI5szZH2TyYtgMN",
"UWJsrsXdfJicjCeFG6nuRkH/F2JiC0HJIXprDkGCqnSqLMHUmKREqsMYFCbUhFM7YCu9rJiAyzJ8dIe3",
"wHTD1jt4yJHtdHNV4A0Bf3fgbQGvW6Hzsz8KfAOny1jugYEKKPkhtYYFYWz3Eo0Q0ldQuI6fn9cUtCrG",
"V+n6E2X4D7OZWt/aks7fB/We8/cTRaK7VUMaQ6OsF5q6VgBrNeMrORUrr25d37a8b3a+3ItxQpoyO2Zq",
"cdJkyDGm4aPrs6NpsPiwaXLMk4Sz91wFNPOIC8kFqVp32j8E5ykCAccg/tDawdYUgecwx9FK34PtJRtb",
"B7ZvqrqU+j8gDRWJ4VTwZITlYsqxiMPqvf+xOwocTYK/vMcsvicVa2LJxhEuRhJ8Bl+CuBdEGXuT3X3A",
"8KoW1wL8D84d37blHUk/jM+Pzd/+FgkWarIgYGuFtnhJW3dwuZ71KCnns2Y7ml51eu3bW/k5teGJ0z3E",
"XoO4ICxTgSLwpdIHHUqV5Q8PDW8SEP8RgqJMwh9vj4Na9Ua/6sdtJ3JfJIhlU61/dswT6y9B5o45LKW3",
"0i7XRbw60Ngm/bUD2ynl4e2g9T6Ju0l4kZ5H5/qzQKb4RPG0CDST4Xyzoedg9+2UB5Fnt1ceASmXRPFA",
"MkkBSkt4nDXkfA+q8X7ALM0YBs46Bap7NjZx3wR/+Z3yKaYTkmRUYQY8CxRnSUF8kCDerxRsJtWvt3JO",
"aNsbtp73hiTwPourt7ouh5Ca3U8MO2DVR4nyWEXBqN8Fz1LZzTdjwnA6PjobBV8gtfB9xU5D9Cvumq6g",
"to5dnB1MbJBz6elgPY5ENj1uQDS5YlH4e8MhbiGk7oy7UqWNu+lAmW6qmVo3vEUFSbBYHXMa8P+x8ZQN",
"TcITf5De4pWN/oxhWz3FUm0+bla/5s7QxwvM5sEZKGF33ZOMbjj/Nn0/+ZI2NgmurKvvv+vx2ZefMC/E",
"NtFAZA/+PWAB4iizUq4+x8HCSqY5armYfvKXlZTWIJYSve9v30yS6xl33ggKG+NhLe3I+GRyY4KFZ1wg",
"W3QBHVOexcimJEbJOp24FuKU8Zp1DSe2ydH12aDkPTB4ffD27cHr/YxJpSnEm1/zTM44JYN3g18PXh+8",
"dklazGYPb42p5t3XgSOotZLRmWAuB5qdkfK5CRxFWCKMUooJQwq+KFf33a3W5Tzj7CwevBv8DhokpWFm",
"1lfYTPn29ev8iHLXOfiiDs2YhgYYzK6kipkShsXK4zdcO92rf+mt//b6Tcsp2mUxL7/MeCb9wLADDYjt",
"9L9+z+lPuZiSOAbDBv7R+nQfZe4zV54sh0zTvIJjJoSsjF3/+fzt83Ags0STVhPufc8ox3EJ1EzaMBP1",
"95+BDVUefNZjHuKUHN4mkDhBrBF6bTOUmYwVzqTosuq4NZtAQBscPc1MohYfDB+l5MLOuBWQcZpSYqX6",
"wz8l73zgZbf6DsD90GkfBcS/wyIqgP7b6398/xVcgFrwGF1yhY4o5ff6MLrA+u+g1uDnANQ90jZAPC6q",
"DTiA98GoK0lguSFI9Z7HwUS26yYEauUIHgTjHZLdheH79fe/2Pc4RnnozDMB7//+/ivQcjAlG0LSVqA+",
"N7HXIk+fs65egXAOkzloX7hXl8+u8G8dmK+57KG5h+YXBs1VSn34VWsM36xoQsEaaKtgPjK/F4B+mYc7",
"CpyAfa/5Ty2lmG6JnG5jFBSTdLFQTwrDUa4MWThdH+qm8Pz5Ydj1tkev54Nev33/FWgh6NQ4gnUVgdY+",
"AFy4p32Ea5iGpitUWOnr7GOrKNTjVI9TPU51wqk080lkWY9TPU71OLUTThWCYUr2VVHbdS0VbpquEr60",
"1Z2Ors+Q6VAaPiRCpsSVja0hyqOctPVpwyk5cFO6nAwFaNXP3Hy3aW8Vd0dXw/lvz8We9hxQs7fpvTD6",
"MHL0oISqJQpQwveSsOo3VGNKi0y5EK+Hk2jvnqhFniUNRyozWTE1ai2wXIDxGPUKwBWK0JusnwV4dzZC",
"aLhYA0MYuHJD2kYiWRf1JxFGDO5LDEUDlX3bK9KJl/yBzHOIKL0ACnzvOu7JBb9nNtskZxHUwS+33n03",
"jmQdxFtzpLwMFFq7mPc8qedJz9h06XvR/Q4LeIR3XYuam9QnRMbqgnLJiur00g1QsTX1TYHBL0SazMrF",
"NL9IVGo9LBO4ITq7RoUzqZHtK6lXUO5XbL08vMpwTt/a6MNrWfjJ9OFHJqr2ZFsQ1VMCNJZaxLeKUk9O",
"e3L6E4n4Fg9aifg5+Sql6PKLZZYqaqHMNnWSv82XzYgimJK/XPWhtQ+wySANEEN8gFx9JolSAQnJEkRJ",
"ZBJK2wT5bH9dXyPhsanA4BXS3rulPg01CScb82FK6STySITHJiW9Ee/JPMxeoDwy9YNcjts5btQQe39d",
"rqhZp0cJTk31Mkq9k5Vqgjm/tzx09A5WNn+766blg4OAou/WeZwHoj4PZvsC9WzvFXUAiJKwugUupCGJ",
"3gkDINHq8ttIou/XAPWYomgPci/uZWMLHNZfNMLwXw2NaniVd0OM1+2fA0d/ubSqOHgCsrDpEYEoj+7q",
"TqVtLtARsUPJcCoXfKvLae1GNRGaFJ3bUyO0l9evEjb3WUn0ffVMSNVPAG0/nky9XOmxwL4COUzBwBoy",
"rtBeCUc19r3aFQsV3hEDTcce+3rs+2mwT4ssJRTTqEGkIpFEe5L8BUMbmxbxjKkhAhUdtEK6Q4htfHKj",
"K7rrfqLb/nhbibVJxSEFtreZPEObSRdI12BWedLY1VLRxQndDfIydcieNfytWYP1mdu0p+eabF6GUpa0",
"kraocyjAlNNtyyE0+oxdlx+DRbuxpq1I4jaF3ARW2cxP9CweIptFx9bALCqC23KLgGzUec+aep/cn47y",
"WLQwBbVdXeKcCuXY0YXcdDS77Gps6dl2jzzPxJ6ytqXMuEA4d0iMHBZ1QZ6MUW4rA7Vl1R9sjx5xesR5",
"SYhjwdZveRRWFpYKU1Py/K6d8THHoa85Pn47nHGa5yTtxolOXcfvjlbDWklwtyJ0NvJPUeLRD5hmZNLE",
"6+PXoxvZ2NWcL41vZv+fDMyjl5veLaYnFD2heDoO6/C48laxi2xaIQ2icHFob1da0wfT+1mRB6Q4muXr",
"eixC0WNvj70PwF6LJ2jP4tirsnCcg+OGyinKjhW7ILbMppZc7DvD174kf0F3EWCSj+MU5Ike5W8jDxS7",
"7+WBnqI8vzdUa7LSiG1eUQvNu4BaB7C4nZgQYbYvgcX7RWraRvfH+wWoBYiyj+MCS2Q6Iz0OYXMU4RRP",
"CSUaPkuBsQEvyGPMJsBiU3H02XjAPqPUhGv/5wVEd4jMNk6bSJTnlW5IQdjS7Vnf6yyjtOrAmj/G7Elg",
"kiiyBDSzkUMJlncQGxg0kQtFqRxb5CcU3/w4/s6Y0quZQZuO9z6sVd11qb2bxpkTtcimtxFPbvFf2R3G",
"4jYySX337VndShHdFoWY7et/jS5/fu4h1i80J6cPXEvo4KD/s61JEi3qCHANYsZFIpEpO4QKoJVoD8fx",
"UAtnFEelSlYJX8Jtlrp/xPyevUKcIVOZFLnaRbXAHT13FfyfPgzQVDRqiAE0313833rffSRgHwn4E7nM",
"G8xzuN2GSGReHmlIgGWSmssJCLBJxxVL3NCxSywApQJMr9iqf4WfkB3jVSBi+UlJxi6srQ4bWSkNij0I",
"x/WeLSnp0fg58fwX/KRjmWdbIaQqkx/GNqdYSDDRP4NEo8vJvgBqfEfzusTORUdTj5QLNUQzTOkUR3dD",
"ZIruUSKVtF49USaVpjZMCbJVMhl9j1RklxM7WYNoMrqcbAbY9QkLejHlb1BnwFGUGgJsISfrJCiH01bu",
"FJXCi++dP8UTIf56ooORKctr5nMA+8/J1aWXBJiWlpwdZsz8F6V4RTmOny/y9yH+uzFSAxGIC5TfNEYV",
"CHX1nKtYUKocGkKGmvUrYJRad+kj8n8KgPodbO7FKBMCmEKXMM0obqKp7aCJQaS6Eddj16ktef2yv8IJ",
"9Tp6h6tnue3976OL8yeOLOoh+0dnQ7HwhNSCSMR4bBL1luOOqoTz4/UlYqDuubjrDu8m8UpHcLd9njCo",
"obq/IjGkkw3QnmUVlziBISLynMwXasEzCUO0cNWdh4ikY8zmJg9mr0b0CYueMmHR46GjBWzZRZoZuS49",
"0X/ZEGVcAn0SsXUDKEs6mQSB9rgwOQ/IDOE4IexVA7ANO1D3Mjx9H13R4lI7ZXGTF/TCz9+Islp8MDbP",
"ucugbQJIIxCKzPTWQO5Kcg+/kvjbYaqF7+7E9yy+1h23+NE5ENbiyWHIz43ELzPHVy/L9O5vu+P8tSnY",
"4sd2xZGp3o8E4Ghhnc9W3bGcdROqWC9QPSALmnuRqt7n6HJSeqN6FFGFPW2G3Opkl5MTpsQq9Jilt7Yy",
"0FpWj3u1s695+rCapw3yUAF2u5DDw693sGqXgmYT6f4Fq62yToERd6axR9SxH/p8pn+LSkwhyEXTHELC",
"DKED0+4hs4fMXTLtPgA6G+pyPiPo/OEiUp4br8yzegGp12UftRRI4IFsdzkJYqL2nWNCpzeyk5ioUe7Q",
"8L0MqXrSdmZUva/ehPqzmlBNnsryg4HXsFIKk+qKFnNQ+wy+qH2SdrGq/A7qEr6os7S3rfwkvjcaCBBe",
"YkLxlAI6u0Y4jgVIk9RCN6hC3vHZaIwEZvPubl6UzztZ8M51+x7MXj6YOb+nj9eXxglfUy5q77YbAHV9",
"2nEvOj0AdTRX5ZHMGvsvj24mKKJE8yDnWafJAJEIU7LsTgTSbEpJtL+Dl8S16fncfCWegRP/i3aXsPCA",
"CJtxkbikwlOe2UcIxtm+8TSG2O9X0Rn8BEgLbm2hbmw69ESkKxEx52YpyJr6P8yxV4BUWHS9PdOlv78d",
"7k+f3OYN5vwbsxjpyV1UXee7VBljQDvR/xvXpb/LnR91cWSyg1RJqSrOdesVCrurphsThTd7yVzi2/y6",
"CYHCFDm+urShHW8HfQbz/qG160OrAXQu3Ps90uCE/uTTcN1JA67bPRZ6oO6B+sUBdZlqd6lWo7u3KVVT",
"LORJy2x0x7IeyfoXqJ3ekocua8FQY1tceD148c1Tw7XgJVvEox63etzqcWtH3Gpy1ehxq8etHrd2xa1c",
"XIyxXEw5FvHWbKRFS5e5rWzDNTXM9AFiwkC4etkmCm5yMv54dH0dSsJo+eSoWMSzS0JKFCSyQyKlfCcm",
"keNgnXMUC4FXLzIJaZ8yaMc0qGuEMcDUkCwoJvJum3F0ZNr0Sct/gqLnsbvKHB4migs8h02AOLT0tezG",
"VjuVBCubAtPVM4DYjG4Jsv59TpbAbFE9k4Ua2UEPDAsmAiRKsZT3XMSWcziKfoAmSgBOJEoFnxv/EJ6p",
"NFMH9Wx11mpm4NOu6Ikc6KQ9pgM7iZ4v5DNnW9iTcCvZwWdOwRd1mFJMWMfEL/boIEZ6BHduyCUINxfz",
"n6vrk/HRzdnVJZp8OD4+ORmdjD77BbLQIr5PjronnX07q3nS6bfQlCed+3FKmmgYxxbKuUApFopsvLR6",
"KEslrDKQdhsbB1zK+V2WFrkMLCX5MD43r4GilKNegOR0CTE6u17+lvuThUQ9trWamZ5C8XzUQH2PTNDv",
"W0Do0SXLWu2TLpJhnyU2gD7lF20NPgaSbVWOD+PzpqIMMZP7Jm45iB8fQWgWq4EeKzMwkSjiQkCk6KpU",
"XKOOM2FsMO5XLVHChlW7HT0TxPi58j/3ePXQZCAFiG7kCm6Fgjy6A7HvvE62xm+MTPOJa/00Qqdd0kFl",
"qkr6G68A6NxmHiH3zcOF0GIRVhB9DmJmL+ftEE1uQbBwydoz65KwT8kdvLJ6hUtiJodoyWmWQJ5uPDfM",
"lZVOC9gl5IOl3uMWK8SJbbSFXU2ML5mJ8SIMjU+Pf/311/92mifae/v69X/tv36z//rtzZt/vHv927vX",
"//g/rwLcbCZ4MuhUMe6ExY8ys+Ld5r0gjCRZgiifIwpLoGgvhmk2HxpD6RDJLIpAyiG6x4IRpn9PUi4U",
"ZmqIQMNFaCWUz8/1gJX1xDDDGujeDfTwg+H2BZ5mlO4bjVQCFtECKRBJYErbotsBvJ9cXSIzDsISadUc",
"ucb+OfI/O0xxjeeEuRSTmZBcoL0rIyyfjdACvrj5XgVLApoolr4k4M9rXbM0zBLDGaEKhMlTxGKUFqBT",
"ooEXoASJyhX4ZnhJoorb48ZRgS0AYcgqNv80Vdpst7rcP3SKsqkNpzRiYIZIYiHRR2BP3QK2KwT7wCIe",
"Q4wkUYCchjDT6ysvJ4R8DyzLmfsFpylKeAxoRvE8SEvEEqfpI2IejxSofWkEnCow5hbTwZQwbKOHt8lJ",
"bdSP8IQ/QA154sXsoo488ZIeKS6tjKRbVZEZFxG4ikv7rrxJ0BB/I8h8DkIijBLMMkydpm5mKmItXUUa",
"O5gM2dFP9cR2ox/WVVV6Bb1/jdz9NdLAVAkma5AYRIM5qH1b47pVtVJXPNvVK3MaipUFZ4SGeN7voGwt",
"3IeC+hOR/x64e/tXF0bjsMBBfPDV34iBJVftRuzCKBWwJDyTdIWylHKsRT8zRMnJx4ddZ7pNG08509Cs",
"2gyH9tYFzeCLAiYJZ68e04Puxwp8P1Cg6VQbrBc+fwbhE7MNrG3iuqbBNlPcmW20Bak14iNug/udBdES",
"DcURYTK1VXB8ehsp0Y3n8Zyk55IHZt9nbum9IeXRodUd7drivMlkghZkC7aHaUZpK9i91g0fAL+p7f89",
"gffhzzF60ZWnmP4xpEPacX14G4BpCjdjJGBOZDVjXBOA7pPZfkKk3J5jZg2rZ7ML16MH2h5oHwS0nNEV",
"IjNEFDIVwxTCVACOV7YiOVOI8ghT2gzObEmazFK/u5Ib0uWidihiH1DuYGWs2Dy1TxZ0hSSw2BqozcDW",
"qcw5h5pMKggSTGjIcnVml/NEyUsliAM7w5aEiZckujP6i96d1g+QgfO+7vnztjz86Eocve3jwYRurClX",
"nFMPSli5nJpG4PJL2598uk3D+adu0r/J7hRjoCeMMwox+tOeYiD+S389XCcJaPS30vdh8wbskh4jEpwd",
"/JNPK+S7v92Xi+5FpYA/+dRK4SZ/6PgqnPnLB3yOAGyFvN9B9WDXF796Jva8GBQm1DqCUD6XWt3DeRRW",
"pFFiC9iLjLUC+3HGerDvqe3gwjgW0BVS1tnA0V3FkcjYdlhj2w0dDtrYI6TR/TtKXS51O10hd9xtJC+p",
"eNqKDEx0w54O9HRAAwLCZRgLgxglUu3HRGxBfA2+IyK2e3WbYEL3OOwckN9ZQ1XI59bF7HZz8x0RAZHi",
"YoVSrBalqQ7Drr1q0bv29hLfkzoXm/ocduVO3ItzQG0MuTVYmDhX4+2YmDsl9xD7E6R6WHt/WgBAd7Cy",
"SoNaABGI4mk1GW/dJZ3yOWFhI79eADBla2kjbEvN22igsiE8N+QPkQQl0T//fYMizu8IIM7y2JSQYf/c",
"rOAJ7fpmgi1mfdMGRQJivVtMZW/R7yNZHxQh/kFjCnWwneOfPsYq8vFMBb3zzo3mn1VrNxkMnK5QRAHb",
"+JM1iprQJYN3oQQJ53bG5wLLz8jbuXZx9pwCN5dgcQdKbnespBTZtinFESDJMxFBmUaXtiyHKKWZy7iz",
"4PcRls4BIXd5pjyLDwJXe+GW1HP2l19Hy0Q+lcCG2jqGFVZuPpdBElo50aeCGyfccoI950yytjGUaArE",
"huSEgA6eX1K97eNoFH+R2fJ6tvsICFbhpHl8c4DMg5hvf7m8MK2eNi2ZmaMhKYT5/oB0ZH022J4xNb0P",
"GPBKMqpISqGU8U+iTGop1DQQp5NGW0U7M8XaRNGcepknCd6XoBtpLkVNaYNZRRU2ib6UIBDM9JUUk/Xm",
"vUd6rzABCfO5gLm5F3fCm2lK66aIZIarNSU2hZiEL11E/NvTI+NiaINt19kpDUnfw3FCGCpA61VNdinK",
"U1zM8FNaHrSc8fb0yJQva6DdhU+hk8PMLmyOOlBmrzbUvjdIPF8Xw5fsVVfAmDPw1eWhoV+v2HQBvrm6",
"uS7wsma02EzsmAq+JJJw89IUzmKX42gP6i9c8rawYgDF0W8foPnt0B8xJbGDNANlit8B88OZ4kjv1biP",
"GYllf4YjpaG7YikL2aO/D08wmewaeMJ6kz3h/wmxwST7XBk8yC85pIKSuUab/YXDi2ZN1Db+g0v1tBkL",
"3apuuJ7qgsdeODE1PfPinhOUcqFqvpvPFLR7XfUF66oWNtGxMZqXCocojjQW5YkMTW6ppgiohGesBc6Z",
"Vk9s/dFzNFl/9Pfe+tNj1BNhlAEvXDL7NJt5dPOtVh7bqDet/AR+KObCIS6bBRsBxBHgw6/uH2ejdtVE",
"L23zy7zX1khpR+hNS19imdJALzCneQ+3DwwtckHTuTwwXVlICQoEeQbkLaTtMm/WA8pPQuCqgOJNdL2l",
"7HcFJp5MLbNlnd1c1y4tvM/i7CD+EVLI9wpZj0Ztk8wzuN9ApWZqe5+HF2xBrfuO8QWPGU5wjY3lMa5E",
"FewaSFBPq85prE8LJya9i8XvUDZ70/b71i3qAxf+zoELFcQuwK9J7r8/Y1Jhm8HLb+n/A7OYgnSWe6kg",
"zRPKEtvVMqx19sgYKzzFEpAElaVDZ2ys2BltoQr7LGyeCHK+F3oDuFwv9Gn4dYIJO1jPEnJLPytv2ZyF",
"e0V/ply6TzH7/B3TrwWPQEqDs2QTvhrTNTOuyCz3Vd6mA1XabuHN7SpvmNc+xw/Lo+9c3aXnfi/ck7MC",
"BsVjsNd5OQfqKlwGYPtQAI67APgYjO60k79aeWbkAXsZyucXy5cn6/VqXC9vPiRLhbjbQHoskbDItw3D",
"eQqMxK0idkq1Nq9SYGcjdMwZg0ihiBKt7VWky1Cs1ZWd8NnFRxBjn291rXb3x2bTg3W8BBYCr15kAMUL",
"zLXmINBCXlk+cwAddpqy6lnunNcCkkPqUAmSn8ArygNpHigqn8ITe5H8iJCkjf13wqznwFR77DYr+O/v",
"v4JjzmaURGo30w2r0hcfeaky0MOvJP7Wxk9/PXQTySke3QJPvpb0nG2Vrqv0IfTgS+K+enWfxXdHuXmX",
"J+YW6DXcVppHEjansBP/LguiLxSHXhoz7lH1haGqq59TBf5NV5CyrJ15sdUE6huuB19stP5uEnf2PDD2",
"R8n5tipljHp5v5f3ezL3iGTOIlYngT/P6rVvAlHDT7YTW9nDW84DKb6OaSUz9yORJRtbyOpw7YYzIYpP",
"GZJVmahL/Q+7mVmtkkkfstVnMXnQG60DwhpOhcPE0moG5g0TwQKiO6nRz1Sm1ugnAEcLkzqwHJaLEeNs",
"/x9fvqAcXAMqxXWLOlWhKvKp7fvTFY7v0bZPPtRcqsuk69tWG15ElDPQPFdhoba8Qo9N47Fr2/szdEx9",
"oE/NPLKMj/U5IgEJV4CcIyhK8hilsEubrXoGIiwdHbtYdGlloEqZNJs7B9drp+2Vyhy9CglI43zuJ5SN",
"8jm2iEXj8gby6hVrH738lFzQfy8c9VT2IcKRAyb7runPWLLGTwlt82Mb+b9PkP2zJLUxkYku+ZTR1pYm",
"t/rWPFR1zruRmsOWSNHS8lzgCGYZzV2URcGIA/D1GGy6f1X6KV2GdxFdTKZgA3oliLaWlTpA77uWLeDa",
"9cgTkpmsCQmOFoQB2jP1ZIvM8/cLYEW9EMIkiQHhddKFV824MMkX32NEn8rs4VS/QIoyxDYqWzxTILs6",
"BaaCf1kh1zcA3/nHl+v8d613afZxbClK7wD4QxwAN6Ath2X3Q1v3v9Io7Zz+ShD8VI+BdQjzaJbeFb/8",
"B0DP3vtHwN7p77s4/W0SBB9VqXLIw68MJ9DO7y9MatB0lcdfB9z9LNG5tG0aXxcsXShHc2/kdrFfeme/",
"/mn9ezn7bUOptp5+jfhDlPTjUFnufJEI9BK5cI+rL9Hbr4Jha57kk6xbO/t1Z3rW1e9HI+yPlO1zZz/R",
"y/i9jN9TuMd19Gsr4DtHmG2PY5O82RYqdYG/kCRLEMuSKQjEZ2tbcF6PJRMs4JRDSUKUzyWHMAVzU7Sr",
"z774kyXVW4NHUzKwHEoPvxbtz+Jvhy2B9njdZ3uahjxd9NkIcdHAb6PKoH3+0L8NBJ8xmUKk1grbJiRv",
"zyQaAGecKb6fGQJ++FUqrDL5rTuIH2WKWy4wMUP8eJAfeupK5xtFdp9oTw+ip59hKuGVfwEy31CPbn8b",
"dDth5qGZCxQTaV2WS9BjyxZtYuAOuBctILpzo3bHOeNibZGu5zA9yD80saKGJnS/ALUwfm4FIPwiEUnw",
"HNACu4c9EGgJQhLO1k4ZO0A/fEn5Vm9jD9yf2H49yPcg/0AqbwCpDOsbZjQD8NJFeMQwI4w4Q1FXWKd8",
"LrtD+jmfP0dJqq5vUz5HlDB4FHW7npGYUGUL5Est5krAIlq4VHXBUBvdplvi4xuSgFQ4SfUmZqCihZ0y",
"Y4rQ0HawVGOIgCwhv60OM9pnGMQZXSGpYhB2k4G5QEP4FaMr3yRTzilg1pOln8GpzJYPttD3aMJmghme",
"w+FXHOmlfgs6oB2Z7/IdkoqnQ2Qc3Ia5e+YQ3RFKhyZqZQlDlOJMwhBlzP1DgM0XPkRZLpi2pHUXZnl2",
"8mdJ8/TyEmAK4XyNnvmKb+GpgGWJcQxU3IQCrv2z3b/0CZsf9BGbo8hMUKQ7ZPOpyMrujvnz8PmKJ30C",
"zhccPwhixkWCMEo2EQBpAekxCFOtNFPcrjSTh4hsVGuKnyEhaVsg6oXqIj2yv+QiVQpHi3qRqpngSVlL",
"2qEWUY+rvd3gp8GTI+XHE8W3YUk7TriDpaBU66u3ivXQ/SiP5Tk0mkhWtYDSDyWLmc2rxCBSECPFd4B6",
"s7KHPD5OzADP9uEx5yJ2n/Hf5vGxFwVfLhGYgNKgmTEJ6+LlRHJXt+exVL/102dX6fFZvXs+WXHNYv2n",
"XCSBoBy3Qfc23VfV7KnCk1GFws9zE/V/kUiCUq50UJgKJFio/VhvppnH63YjmPUZUToHGkwujsY3CCsl",
"yDRT5VdL+5RwdHNk5LnLjxeAYkGW0JxsSjKcCky2laaa5M1q5NB3IOsmBPJj0SOMj85G1m397eBbXzuq",
"J1YP1mO4K7wJKIeveiGlOvBvM2b1wN4D+08D7JuU3ht3HXqCcX3axJJtrOlpo8p2Q8QeD3s8fBQJmQsU",
"5xHaflz0xIB25j891vVY12Pdo2FdgBH6PKaaVCCNle3cmJ4QN4d+ry7jnpk9gu/SikXGC1Fk08FwMCNf",
"BsMBMOcI7mImnsIpqUf1v2F48ThjZYx27kd7GgiHyMDgEM3IlyGyEDjMg3ZeNaO5fVrZlodPLQBFmRDA",
"VJ5y1T3grHNNV2iM8ZXkmYgAETbjQ2NusVkATc+gT+T6qadPCRQ/uzypFStbBRCakj3KLObhPO1j2C9X",
"jpfrsjX3RC30X6RU50VxNBeYKQQUliaJxZ4e/hVKQSRESm9d6Fxk1Ot4wpztevwt+drzkjfGDKkX7vbx",
"FJk3eizoq2CUA30swmgMMoCX8BjC+dszZoowbH2V/ODaPQ1auYIQBxd6jkJ08IGLWQVya3j8JDa9xPU3",
"V64cgGE0IxQch2sSrLKUclw2I/qZ3wfTzGS0svGlevi8dptjsHsyS1MulER/pvMh+jOF+RClbD5EczIb",
"ommSDpFczofoHqbpECkymw0RXpJZsICJnbWN5eQ9ljb1lWFYhjObvhCblX6PhFhJRhVJsVCHMy6S/TwL",
"1Hq0apYoc4z1gz6rnK7dhFbauEiwGrwbTAnDJs6spkSW9vEfN/pnL9b3vgZ9MqsXUfHgJdu4NN4W1LJJ",
"6dASeYsE84iaR6OZcfY0fazawVPL71Eeq+vTVj9Imz2pY2IuO80zyMn1Q9Pc68PrU9v3dOVZuXtnspoP",
"zf7dNte/sVrgKDKioiEjnhJzWpCyVeb2p1hCjDibcixiG8fvl9fcqp7McmG3scV2oVdh39ZLxeZ6q0VP",
"G9rRhh+cr/8FJyUqVw/YqLqX06eK1HP4lblq2Y2FA6wDi6ZdFbo1XaG8e7hegKFIl+tmzQWJ9fClMX0q",
"4/prXzmgJzV/UzGkKGgQwPIthQwMGudFYHN7jUwhIjMCcRirS8rMS0fpH5Ft3CoyveLSU4zvTzFsWQWD",
"+FW+7VFgsIoWPgt0jIsi2TnxkFm0QFgiSDCh5u1ecOqppKCHfFak44n0o5OYqC3a0SkBGktrXHZReb1i",
"1NOen/lBOSYqLKvkGsmS0yyBw6/2v5etveo/mvYfi17byIpuk9fNtXNpXHTTeKnMsjx2n9vhb5Thx0nZ",
"LoDTQUvdK7YWumlbbstM8tG16uHk5yqYsSzutWvipzJEPFmYvJ2kYsn1HYxttrbj9rHyvdvM9zFdVtAo",
"RGYpn/NW7sjHXCZc5j4yupvNVH19+XvxOFyjzud69K2AbbofpmxePdTtviIBGP5H2xme+toqaqM7QGqP",
"xPuOLiLKGRxaz+5Dl2610SNwbHrYkKbjPD3rrkRvq2fdGBJeFLCzD26ahQ+R7ml9zksyY+8U2FO3p6Nu",
"42MN+SYndKXum/3di1Dlh5kmbaiMVKNcoXkypLoyX9bYpJUqu6uKQtXj0jPEpV3UILYT6GZJ2qQGVUBW",
"t+2T2HS6myxJjZQzyyjN72ezTmuLa6JEKnutsu1tnZe69JfWWV+s4JJEe4aCmtyRqxRMkYshYlyrXzEw",
"RTCVr9pdpcTLDrLXBC+hv75u2f7wEgzO7Y5upUx+me+SssodfSi/EzylfOyy4q05ei8Y94Lx90iRVyrT",
"3k3GEGAik1sxLZv0tmdWL/0Ze075FBfCjhKYyZkLL5ZbAKaADXmIpzxTbfjkVdHnyHTZIY+LadkTy55Y",
"1mBfr+bNj0ktcZak1FSogbg7Drp4W5RJ/f+EzbgrveUMAHuKK0yHKJMQD9FMAGyTXpczuSbl23Dy40yu",
"aXmPjH8LM4QGu4+nE0vnHbSZWFuIm6QFM4VGOesLkAk6eDc4jIxNe/Dt87f/FwAA//+KsQtXh30CAA==",
}
// GetSwagger returns the content of the embedded swagger specification file
+1 -1
View File
@@ -1,4 +1,4 @@
package cosmossdk
// Version is the SDK version, synced with Cosmos Server at build time.
const Version = "0.22.0-unstable12"
const Version = "0.22.0-unstable13"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "cosmos-server",
"version": "0.22.0-unstable12",
"version": "0.22.0-unstable13",
"description": "",
"main": "test-server.js",
"bugs": {
+6 -2
View File
@@ -203,9 +203,13 @@ You might also wonder about **cloudflare proxy** and **cloudflare tunnel** when
* While they protect your remote access to your applications, they leave your origin server completely unprotected. A rogue device / application in your local network would have no troubles taking advantage of it
* Those options let **Cloudflare see your entire network unencrypted**. Yes, even if you use HTTPS: Cloudflare proxy de-encrypt your traffic, to re-encrypt it. Meaning that everything that goes through your traffic is plain readable text to Cloudflare. On the other hand, Cosmos is self-hosted so you stay in control of your data.
# SDK
# SDK and Terraform
A JavaScript/TypeScript SDK is available for programmatic access to the Cosmos API. See the [SDK documentation](./sdk/README.md) for installation, usage, and examples.
A JavaScript/TypeScript SDK is available for programmatic access to the Cosmos API. See the [JS SDK documentation](./sdk/README.md) for installation, usage, and examples.
The GO SDK can be found in the go-sdk folder and used with [Go SDK documentation](./go-sdk/README.md)
Finally a Terraform provider is available to fully automate your setup: [Terraform documentation](./terraform-provider-cosmos/README.md)
# What is the SmartShield?
+25 -5
View File
@@ -24,6 +24,7 @@ type CreateAPITokenRequest struct {
Permissions []utils.Permission `json:"permissions,omitempty"`
IPWhitelist []string `json:"ipWhitelist,omitempty"`
RestrictToConstellation bool `json:"restrictToConstellation"`
ExpiryDays int `json:"expiryDays,omitempty"`
}
type DeleteAPITokenRequest struct {
@@ -69,15 +70,20 @@ func listAPITokens(w http.ResponseWriter, req *http.Request) {
tokens := make(map[string]interface{})
for name, tok := range config.APITokens {
tokens[name] = map[string]interface{}{
entry := map[string]interface{}{
"name": tok.Name,
"description": tok.Description,
"owner": tok.Owner,
"tokenSuffix": tok.TokenSuffix,
"permissions": tok.Permissions,
"ipWhitelist": tok.IPWhitelist,
"restrictToConstellation": tok.RestrictToConstellation,
"createdAt": tok.CreatedAt,
}
if !tok.ExpiresAt.IsZero() {
entry["expiresAt"] = tok.ExpiresAt
}
tokens[name] = entry
}
json.NewEncoder(w).Encode(map[string]interface{}{
@@ -131,6 +137,7 @@ func createAPIToken(w http.ResponseWriter, req *http.Request) {
return
}
rawToken := "cosmos_" + base64.RawURLEncoding.EncodeToString(rawBytes)
tokenSuffix := rawToken[len(rawToken)-5:]
// Hash for storage
h := sha256.Sum256([]byte(rawToken))
@@ -163,15 +170,22 @@ func createAPIToken(w http.ResponseWriter, req *http.Request) {
owner := utils.GetAuthContext(req).Nickname
var expiresAt time.Time
if request.ExpiryDays > 0 {
expiresAt = time.Now().Add(time.Duration(request.ExpiryDays) * 24 * time.Hour)
}
tokenConfig := utils.APITokenConfig{
Name: request.Name,
Description: request.Description,
Owner: owner,
TokenHash: tokenHash,
TokenSuffix: tokenSuffix,
Permissions: permissions,
IPWhitelist: request.IPWhitelist,
RestrictToConstellation: request.RestrictToConstellation,
CreatedAt: time.Now(),
ExpiresAt: expiresAt,
}
utils.ConfigLock.Lock()
@@ -206,12 +220,18 @@ func createAPIToken(w http.ResponseWriter, req *http.Request) {
},
)
responseData := map[string]interface{}{
"token": rawToken,
"name": request.Name,
"tokenSuffix": tokenSuffix,
}
if !expiresAt.IsZero() {
responseData["expiresAt"] = expiresAt
}
json.NewEncoder(w).Encode(map[string]interface{}{
"status": "OK",
"data": map[string]interface{}{
"token": rawToken,
"name": request.Name,
},
"data": responseData,
})
}
+4
View File
@@ -1068,6 +1068,10 @@ func GetCurrentDeviceName() (string, error) {
config := utils.GetMainConfig()
name := config.ConstellationConfig.ThisDeviceName
if !config.ConstellationConfig.Enabled {
return "", errors.New("constellation not enabled")
}
if name == "" {
nebulaFile, err := ioutil.ReadFile(utils.CONFIGFOLDER + "nebula.yml")
if err != nil {
+16
View File
@@ -258,6 +258,22 @@ func tokenMiddleware(next http.Handler) http.Handler {
return
}
if !matchedToken.ExpiresAt.IsZero() && time.Now().After(matchedToken.ExpiresAt) {
utils.Error("API Token: Token expired: "+matchedName, nil)
utils.TriggerEvent(
"cosmos.api.token.expired",
"API Token expired",
"warning",
"token@"+matchedName,
map[string]interface{}{
"tokenName": matchedName,
"expiresAt": matchedToken.ExpiresAt,
},
)
utils.HTTPError(w, "API token has expired", http.StatusUnauthorized, "AT004")
return
}
clientIP, _ := r.Context().Value("ClientID").(string)
remoteAddr, _, _ := net.SplitHostPort(r.RemoteAddr)
+1 -1
View File
@@ -201,7 +201,7 @@ func main() {
}
// @title Cosmos Server API
// @version 0.22.0-unstable11
// @version 0.22.0-unstable12
// @description REST API for Cosmos Cloud server management
// @BasePath /cosmos
// @securityDefinitions.apikey BearerAuth
+36 -5
View File
@@ -198,10 +198,38 @@ func NewProxy(targetHost string, AcceptInsecureHTTPSTarget bool, DisableHeaderHa
req.Host = req.URL.Host
}
// Extra headers
for name, value := range route.ExtraHeaders {
req.Header.Del(name)
req.Header.Set(name, value)
// Extra headers (applied last so they can overwrite anything)
if len(route.ExtraHeaders) > 0 {
clientIP := GetClientID(req, route)
replacer := strings.NewReplacer(
"$target", route.Target,
"$scheme", originalScheme,
"$protocol", originalScheme,
"$host", hostname,
"$origin", hostname,
"$clientIP", clientIP,
"$user", req.Header.Get("x-cosmos-user"),
"$route", route.Name,
"$path", req.URL.Path,
)
for name, value := range route.ExtraHeaders {
req.Header.Del(name)
req.Header.Set(name, replacer.Replace(value))
}
}
// Duplicate X-* headers as HTTP_* equivalents (legacy CGI convention)
if !route.DisableLegacyHTTPHeaders {
for name, values := range req.Header {
if strings.HasPrefix(name, "X-") {
httpName := "HTTP_" + strings.ReplaceAll(strings.ToUpper(name), "-", "_")
for _, v := range values {
req.Header.Set(httpName, v)
}
}
}
}
}
@@ -242,7 +270,10 @@ func TunnelRouteTo(tunnel utils.ConstellationTunnel, lb *TunnelLoadBalancer) htt
}
// For self-tunnel, use the original route handler to avoid proxy loop
currentDeviceName, _ := constellation.GetCurrentDeviceName()
currentDeviceName, er12 := constellation.GetCurrentDeviceName()
if er12 != nil {
utils.Error("Get Current Device Name for Tunnel Route", er12)
}
proxies := make([]targetProxy, 0, len(tunnel.Targets))
for _, t := range tunnel.Targets {
+3
View File
@@ -348,6 +348,7 @@ type ProxyRouteConfig struct {
Tunnel string `yaml:"tunnel,omitempty"`
TunneledHost string `yaml:"tunneled_host,omitempty"`
ExtraHeaders map[string]string `yaml:"extra_headers,omitempty"`
DisableLegacyHTTPHeaders bool `yaml:"disable_legacy_http_headers"`
SkipURLClean bool `yaml:"skip_url_clean"`
UseH2C bool `yaml:"use_h2c"`
LBMode string `yaml:"lb_mode" json:"LBMode,omitempty"`
@@ -579,10 +580,12 @@ type APITokenConfig struct {
Description string `json:"description,omitempty"`
Owner string `json:"owner,omitempty"`
TokenHash string `json:"tokenHash"`
TokenSuffix string `json:"tokenSuffix,omitempty"`
Permissions []Permission `json:"permissions"`
IPWhitelist []string `json:"ipWhitelist,omitempty"`
RestrictToConstellation bool `json:"restrictToConstellation"`
CreatedAt time.Time `json:"createdAt"`
ExpiresAt time.Time `json:"expiresAt,omitempty"`
}
type APITokenContext struct {
@@ -11,6 +11,8 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource"
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64default"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -36,9 +38,12 @@ type apiTokenModel struct {
Name types.String `tfsdk:"name"`
Description types.String `tfsdk:"description"`
ReadOnly types.Bool `tfsdk:"read_only"`
ExpiryDays types.Int64 `tfsdk:"expiry_days"`
IpWhitelist types.List `tfsdk:"ip_whitelist"`
RestrictToConstellation types.Bool `tfsdk:"restrict_to_constellation"`
Token types.String `tfsdk:"token"`
TokenSuffix types.String `tfsdk:"token_suffix"`
ExpiresAt types.String `tfsdk:"expires_at"`
}
func (r *apiTokenResource) Metadata(_ context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
@@ -69,6 +74,15 @@ func (r *apiTokenResource) Schema(_ context.Context, _ resource.SchemaRequest, r
// read_only is only sent on create; after that it is immutable.
},
},
"expiry_days": schema.Int64Attribute{
Description: "Number of days until the token expires (0 = never). Changing this forces re-creation.",
Optional: true,
Computed: true,
Default: int64default.StaticInt64(0),
PlanModifiers: []planmodifier.Int64{
int64planmodifier.RequiresReplace(),
},
},
"ip_whitelist": schema.ListAttribute{
Description: "List of IP addresses or CIDRs allowed to use this token.",
Optional: true,
@@ -88,6 +102,14 @@ func (r *apiTokenResource) Schema(_ context.Context, _ resource.SchemaRequest, r
stringplanmodifier.UseStateForUnknown(),
},
},
"token_suffix": schema.StringAttribute{
Description: "The last 5 characters of the token, for identification purposes.",
Computed: true,
},
"expires_at": schema.StringAttribute{
Description: "The absolute expiration time of the token in ISO 8601 format. Empty if the token never expires.",
Computed: true,
},
},
}
}
@@ -128,6 +150,10 @@ func (r *apiTokenResource) Create(ctx context.Context, req resource.CreateReques
if !plan.RestrictToConstellation.IsNull() && !plan.RestrictToConstellation.IsUnknown() {
createReq.RestrictToConstellation = client.BoolPtr(plan.RestrictToConstellation.ValueBool())
}
if !plan.ExpiryDays.IsNull() && !plan.ExpiryDays.IsUnknown() {
ed := int(plan.ExpiryDays.ValueInt64())
createReq.ExpiryDays = &ed
}
if !plan.IpWhitelist.IsNull() && !plan.IpWhitelist.IsUnknown() {
var ips []string
resp.Diagnostics.Append(plan.IpWhitelist.ElementsAs(ctx, &ips, false)...)
@@ -153,7 +179,9 @@ func (r *apiTokenResource) Create(ctx context.Context, req resource.CreateReques
}
var createResult struct {
Token string `json:"token"`
Token string `json:"token"`
TokenSuffix string `json:"tokenSuffix"`
ExpiresAt string `json:"expiresAt"`
}
if err := json.Unmarshal(rawData, &createResult); err != nil {
resp.Diagnostics.AddError("Error unmarshalling create API token response", err.Error())
@@ -161,6 +189,8 @@ func (r *apiTokenResource) Create(ctx context.Context, req resource.CreateReques
}
plan.Token = types.StringValue(createResult.Token)
plan.TokenSuffix = types.StringValue(createResult.TokenSuffix)
plan.ExpiresAt = types.StringValue(createResult.ExpiresAt)
resp.Diagnostics.Append(resp.State.Set(ctx, &plan)...)
}
@@ -226,6 +256,17 @@ func (r *apiTokenResource) Read(ctx context.Context, req resource.ReadRequest, r
state.IpWhitelist = types.ListNull(types.StringType)
}
if found.TokenSuffix != nil {
state.TokenSuffix = types.StringValue(*found.TokenSuffix)
} else {
state.TokenSuffix = types.StringValue("")
}
if found.ExpiresAt != nil && *found.ExpiresAt != "" {
state.ExpiresAt = types.StringValue(*found.ExpiresAt)
} else {
state.ExpiresAt = types.StringValue("")
}
// The token field is never returned by Read. Preserve whatever is already
// in state (set during Create). On import it will be empty/unknown.
// state.Token is left unchanged from what was in req.State.