mirror of
https://github.com/wassname/talk.git
synced 2026-07-31 12:50:48 +08:00
[CORL-416] Disable Live Updates (#2391)
* feat: initial implementation * fix: docs
This commit is contained in:
@@ -8,9 +8,10 @@ export const Settings = ({
|
||||
redis,
|
||||
tenantCache,
|
||||
tenant,
|
||||
config,
|
||||
}: TenantContext) => ({
|
||||
update: (input: GQLUpdateSettingsInput): Promise<Tenant | null> =>
|
||||
update(mongo, redis, tenantCache, tenant, input.settings),
|
||||
update(mongo, redis, tenantCache, config, tenant, input.settings),
|
||||
regenerateSSOKey: (): Promise<Tenant | null> =>
|
||||
regenerateSSOKey(mongo, redis, tenantCache, tenant),
|
||||
});
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { isUndefined } from "lodash";
|
||||
|
||||
import { GQLLiveConfigurationTypeResolver } from "coral-server/graph/tenant/schema/__generated__/types";
|
||||
import * as settings from "coral-server/models/settings";
|
||||
|
||||
export type LiveConfigurationInput = settings.LiveConfiguration;
|
||||
|
||||
export const LiveConfiguration: GQLLiveConfigurationTypeResolver<
|
||||
LiveConfigurationInput
|
||||
> = {
|
||||
configurable: (source, args, ctx) =>
|
||||
Boolean(!ctx.config.get("disable_live_updates")),
|
||||
enabled: (source, args, ctx) => {
|
||||
if (ctx.config.get("disable_live_updates")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isUndefined(source.enabled)) {
|
||||
return ctx.tenant.live.enabled;
|
||||
}
|
||||
|
||||
return source.enabled;
|
||||
},
|
||||
};
|
||||
@@ -5,6 +5,7 @@ import { GQLStorySettingsTypeResolver } from "../schema/__generated__/types";
|
||||
export const StorySettings: GQLStorySettingsTypeResolver<
|
||||
story.StorySettings
|
||||
> = {
|
||||
live: s => s.live || {},
|
||||
moderation: (s, input, ctx) => s.moderation || ctx.tenant.moderation,
|
||||
premodLinksEnable: (s, input, ctx) =>
|
||||
s.premodLinksEnable || ctx.tenant.premodLinksEnable,
|
||||
|
||||
@@ -22,6 +22,7 @@ import { FeatureCommentPayload } from "./FeatureCommentPayload";
|
||||
import { Flag } from "./Flag";
|
||||
import { GoogleAuthIntegration } from "./GoogleAuthIntegration";
|
||||
import { Invite } from "./Invite";
|
||||
import { LiveConfiguration } from "./LiveConfiguration";
|
||||
import { ModerationQueue } from "./ModerationQueue";
|
||||
import { ModerationQueues } from "./ModerationQueues";
|
||||
import { Mutation } from "./Mutation";
|
||||
@@ -60,6 +61,7 @@ const Resolvers: GQLResolver = {
|
||||
Flag,
|
||||
GoogleAuthIntegration,
|
||||
Invite,
|
||||
LiveConfiguration,
|
||||
ModerationQueue,
|
||||
ModerationQueues,
|
||||
Mutation,
|
||||
|
||||
@@ -1086,6 +1086,12 @@ type Settings {
|
||||
"""
|
||||
locale: LOCALES!
|
||||
|
||||
"""
|
||||
live provides configuration options related to live updates for stories on
|
||||
this site.
|
||||
"""
|
||||
live: LiveConfiguration!
|
||||
|
||||
"""
|
||||
moderation is the moderation mode for all Stories on the site.
|
||||
"""
|
||||
@@ -2061,7 +2067,27 @@ type StoryMetadata {
|
||||
section: String
|
||||
}
|
||||
|
||||
"""
|
||||
LiveConfiguration provides configuration options related to live updates.
|
||||
"""
|
||||
type LiveConfiguration {
|
||||
"""
|
||||
configurable when false indicates that live updates cannot be modified.
|
||||
"""
|
||||
configurable: Boolean!
|
||||
|
||||
"""
|
||||
enabled when true will allow live updates.
|
||||
"""
|
||||
enabled: Boolean!
|
||||
}
|
||||
|
||||
type StorySettings {
|
||||
"""
|
||||
live provides configuration options related to live updates on this Story.
|
||||
"""
|
||||
live: LiveConfiguration!
|
||||
|
||||
"""
|
||||
moderation determines whether or not this is a PRE or POST moderated story.
|
||||
"""
|
||||
@@ -2921,6 +2947,12 @@ input StoryConfigurationInput {
|
||||
SettingsInput is the partial type of the Settings type for performing mutations.
|
||||
"""
|
||||
input SettingsInput {
|
||||
"""
|
||||
live provides configuration options related to live updates for stories on
|
||||
this site.
|
||||
"""
|
||||
live: LiveConfigurationInput
|
||||
|
||||
"""
|
||||
allowedDomains is the list of domains that stories can come from.
|
||||
"""
|
||||
@@ -3401,10 +3433,25 @@ input StoryMessageBoxInput {
|
||||
content: String
|
||||
}
|
||||
|
||||
"""
|
||||
LiveConfigurationInput provides configuration options related to live updates.
|
||||
"""
|
||||
input LiveConfigurationInput {
|
||||
"""
|
||||
enabled when true will allow live updates.
|
||||
"""
|
||||
enabled: Boolean
|
||||
}
|
||||
|
||||
"""
|
||||
UpdateStorySettings is the input required to update a Story's Settings.
|
||||
"""
|
||||
input UpdateStorySettings {
|
||||
"""
|
||||
live provides configuration options related to live updates on this Story.
|
||||
"""
|
||||
live: LiveConfigurationInput
|
||||
|
||||
"""
|
||||
moderation determines whether or not this is a PRE or POST moderated story.
|
||||
"""
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
import {
|
||||
CoralError,
|
||||
InternalError,
|
||||
LiveUpdatesDisabled,
|
||||
TenantNotFoundError,
|
||||
} from "coral-server/errors";
|
||||
import {
|
||||
@@ -35,6 +36,7 @@ import { getOperationMetadata } from "coral-server/graph/common/extensions/helpe
|
||||
import logger from "coral-server/logger";
|
||||
import { extractTokenFromRequest } from "coral-server/services/jwt";
|
||||
|
||||
import { userIsStaff } from "coral-server/models/user/helpers";
|
||||
import TenantContext, { TenantContextOptions } from "../context";
|
||||
|
||||
type OnConnectFn = (
|
||||
@@ -121,6 +123,17 @@ export function onConnect(options: OnConnectOptions): OnConnectFn {
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if live updates are disabled on the server, if they are,
|
||||
// we can block the websocket request here for non-staff users.
|
||||
if (options.config.get("disable_live_updates")) {
|
||||
// TODO: (wyattjoh) if the story settings can only disable, and not
|
||||
// enable live updates (as it takes precedence over global settings)
|
||||
// then we can add a check for `!tenant.live.enabled` here too.
|
||||
if (!opts.user || !userIsStaff(opts.user)) {
|
||||
throw new LiveUpdatesDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
// Extract the users clientID from the request.
|
||||
const clientID = extractClientID(connectionParams);
|
||||
if (clientID) {
|
||||
@@ -129,7 +142,11 @@ export function onConnect(options: OnConnectOptions): OnConnectFn {
|
||||
|
||||
return new TenantContext(opts);
|
||||
} catch (err) {
|
||||
logger.error({ err }, "could not setup websocket connection");
|
||||
if (err instanceof LiveUpdatesDisabled) {
|
||||
logger.info({ err }, "websocket connection rejected");
|
||||
} else {
|
||||
logger.error({ err }, "could not setup websocket connection");
|
||||
}
|
||||
|
||||
if (!(err instanceof CoralError)) {
|
||||
err = new InternalError(err, "could not setup websocket connection");
|
||||
|
||||
Reference in New Issue
Block a user