Admin support for managing users (#245)

* First pass at displaying user data in admin

* Hide chat blurb on home page if chat is disabled

* Hide sidebar chat section if chat is disabled

* Block/unblock user interface for https://github.com/owncast/owncast/issues/1096

* Simplify past display name handling

* Updates to reflect the api access token change

* Update paths

* Clean up the new access token page

* Fix linter

* Update linter workflow action

* Cleanup

* Fix exception rendering table row

* Commit next-env file that seems to be required with next 11

* chat refactor - admin adjustments (#250)

* add useragent parser; clean up some html;

* some ui changes
- use modal instead of popover to confirm block/unblock user
- update styles, table styles for consistency
- rename some user/chat labels in nav and content

* format user info modal a bit

* add some sort of mild treatment and delay while processing ban of users

* rename button to 'ban'

* add some notes

* Prettified Code!

* fix disableChat toggle for nav bar

* Support sorting the disabled user list

* Fix linter error around table sorting

* No longer restoring messages on unban so change message prompt

* Standardize on forbiddenUsername terminology

* The linter broke the webhooks page. Fixed it. Linter is probably pissed.

* Move chat welcome message to chat config

* Other submenus don't have icons so remove these ones

Co-authored-by: gingervitis <omqmail@gmail.com>
Co-authored-by: gabek <gabek@users.noreply.github.com>
This commit is contained in:
Gabe Kangas
2021-07-19 22:02:02 -07:00
committed by GitHub
parent 4aac80196d
commit b10ba1dcc2
26 changed files with 8007 additions and 238 deletions

View File

@@ -28,6 +28,12 @@ export const VIEWERS_OVER_TIME = `${API_LOCATION}viewersOverTime`;
// Get currently connected clients
export const CONNECTED_CLIENTS = `${API_LOCATION}clients`;
// Get list of disabled/blocked chat users
export const DISABLED_USERS = `${API_LOCATION}chat/users/disabled`;
// Disable/enable a single user
export const USER_ENABLED_TOGGLE = `${API_LOCATION}chat/users/setenabled`;
// Get hardware stats
export const HARDWARE_STATS = `${API_LOCATION}hardwarestats`;

View File

@@ -30,7 +30,7 @@ export const API_VIDEO_VARIANTS = '/video/streamoutputvariants';
export const API_WEB_PORT = '/webserverport';
export const API_YP_SWITCH = '/directoryenabled';
export const API_CHAT_DISABLE = '/chat/disable';
export const API_CHAT_USERNAME_BLOCKLIST = '/chat/disallowedusernames';
export const API_CHAT_FORBIDDEN_USERNAMES = '/chat/forbiddenusernames';
export const API_EXTERNAL_ACTIONS = '/externalactions';
export const API_VIDEO_CODEC = '/video/codec';
@@ -177,17 +177,17 @@ export const DEFAULT_VARIANT_STATE: VideoVariant = {
export const FIELD_PROPS_DISABLE_CHAT = {
apiPath: API_CHAT_DISABLE,
configPath: 'chatDisabled',
configPath: '',
label: 'Disable chat',
tip: 'Disable chat functionality from your Owncast server.',
useSubmit: true,
};
export const TEXTFIELD_PROPS_CHAT_USERNAME_BLOCKLIST = {
apiPath: API_CHAT_USERNAME_BLOCKLIST,
placeholder: 'admin, god, owncast, stewiegriffin',
label: 'Disallowed usernames',
tip: 'A comma seperated list of chat usernames you disallow.',
export const TEXTFIELD_PROPS_CHAT_FORBIDDEN_USERNAMES = {
apiPath: API_CHAT_FORBIDDEN_USERNAMES,
placeholder: 'admin,god,owncast,stewiegriffin',
label: 'Forbidden usernames',
tip: 'A comma separated list of chat usernames you disallow.',
};
export const VIDEO_VARIANT_SETTING_DEFAULTS = {

View File

@@ -1,13 +1,15 @@
import UAParser from 'ua-parser-js';
export function formatIPAddress(ipAddress: string): string {
const ipAddressComponents = ipAddress.split(':')
const ipAddressComponents = ipAddress.split(':');
// Wipe out the port component
ipAddressComponents[ipAddressComponents.length - 1] = '';
let ip = ipAddressComponents.join(':')
ip = ip.slice(0, ip.length - 1)
let ip = ipAddressComponents.join(':');
ip = ip.slice(0, ip.length - 1);
if (ip === '[::1]' || ip === '127.0.0.1') {
return "Localhost"
return 'Localhost';
}
return ip;
@@ -39,3 +41,21 @@ export function parseSecondsToDurationString(seconds = 0) {
return daysString + hoursString + minString + secsString;
}
export function makeAndStringFromArray(arr: string[]): string {
if (arr.length === 1) return arr[0];
const firsts = arr.slice(0, arr.length - 1);
const last = arr[arr.length - 1];
return `${firsts.join(', ')} and ${last}`;
}
export function formatUAstring(uaString: string) {
const parser = UAParser(uaString);
const { device, os, browser } = parser;
const { major: browserVersion, name } = browser;
const { version: osVersion, name: osName } = os;
const { model, type } = device;
const deviceString = model || type ? ` (${model || type})` : '';
return `${name} ${browserVersion} on ${osName} ${osVersion}
${deviceString}`;
}

View File

@@ -25,7 +25,6 @@ export const initialServerConfigState: ConfigDetails = {
ffmpegPath: '',
rtmpServerPort: '',
webServerPort: '',
chatDisabled: false,
s3: {
accessKey: '',
acl: '',
@@ -48,7 +47,8 @@ export const initialServerConfigState: ConfigDetails = {
externalActions: [],
supportedCodecs: [],
videoCodec: '',
usernameBlocklist: '',
forbiddenUsernames: [],
chatDisabled: false,
};
const initialServerStatusState = {
@@ -62,6 +62,7 @@ const initialServerStatusState = {
overallPeakViewerCount: 0,
versionNumber: '0.0.0',
streamTitle: '',
chatDisabled: false,
};
export const ServerStatusContext = React.createContext({