mirror of
https://github.com/hanzoai/team.git
synced 2026-09-30 01:57:35 +00:00
Push Proxy Authentication (#34211)
* Initial Implementation of Push Proxy Authentication * Include Config Listener for Leader plus delete startup function as job scheduler runs on initialization * Remove push proxy auth from local imports * Add push proxy auth to external imports * Add push proxy auth error messages * Update error codes * Fix enterprise dep definition * make i18n-extract * Mock System store Get * m * m * m * m * Update serverID header * Add install type env var to docker * Update Push Proxy config with new options Global, US, Germany and Japan. Previous configurations will keep working * use model.SafeDereference * Delete token when new push proxy URL is empty * ServerID header only if auth token is available --------- Co-authored-by: Daniel Schalla <[email protected]> Co-authored-by: Nick Misasi <[email protected]> Co-authored-by: Mattermost Build <[email protected]>
This commit is contained in:
committed by
GitHub
co-authored by
Daniel Schalla
Nick Misasi
Mattermost Build
parent
8b09ce4f29
commit
86caa528f6
@@ -352,7 +352,7 @@ const defaultServerConfig: AdminConfig = {
|
||||
SendPushNotifications: true,
|
||||
PushNotificationServer: 'https://push-test.mattermost.com',
|
||||
PushNotificationServerType: 'custom',
|
||||
PushNotificationServerLocation: 'us',
|
||||
PushNotificationServerLocation: 'global',
|
||||
PushNotificationContents: 'full',
|
||||
PushNotificationBuffer: 1000,
|
||||
EnableEmailBatching: false,
|
||||
|
||||
@@ -41,6 +41,7 @@ FROM gcr.io/distroless/base-debian12
|
||||
# Some ENV variables
|
||||
ENV PATH="/mattermost/bin:${PATH}"
|
||||
ENV MM_SERVICESETTINGS_ENABLELOCALMODE="true"
|
||||
ENV MM_INSTALL_TYPE="docker"
|
||||
|
||||
# Copy over metadata files needed by runtime
|
||||
COPY --from=builder /etc/mime.types /etc
|
||||
|
||||
@@ -42,6 +42,7 @@ FROM cgr.dev/mattermost.com/glibc-openssl-fips:15@sha256:7947eecc0d82fa3bc661aac
|
||||
# Some ENV variables
|
||||
ENV PATH="/mattermost/bin:${PATH}"
|
||||
ENV MM_SERVICESETTINGS_ENABLELOCALMODE="true"
|
||||
ENV MM_INSTALL_TYPE="docker"
|
||||
|
||||
# Copy over metadata files needed by runtime
|
||||
COPY --from=builder /etc/mime.types /etc
|
||||
|
||||
@@ -134,6 +134,43 @@ func NewChannels(s *Server) (*Channels, error) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if pushProxyInterface != nil {
|
||||
app := New(ServerConnector(ch))
|
||||
s.PushProxy = pushProxyInterface(app)
|
||||
|
||||
// Add config listener to regenerate token when push proxy URL changes
|
||||
app.AddConfigListener(func(oldCfg, newCfg *model.Config) {
|
||||
// Only cluster leader should regenerate to avoid duplicate requests
|
||||
if !app.IsLeader() {
|
||||
return
|
||||
}
|
||||
|
||||
oldURL := model.SafeDereference(oldCfg.EmailSettings.PushNotificationServer)
|
||||
newURL := model.SafeDereference(newCfg.EmailSettings.PushNotificationServer)
|
||||
|
||||
// If push proxy URL changed
|
||||
if oldURL != newURL {
|
||||
if newURL != "" {
|
||||
// URL changed to a new value, regenerate token
|
||||
s.Log().Info("Push notification server URL changed, regenerating auth token",
|
||||
mlog.String("old_url", oldURL),
|
||||
mlog.String("new_url", newURL))
|
||||
|
||||
if err := s.PushProxy.GenerateAuthToken(); err != nil {
|
||||
s.Log().Error("Failed to regenerate auth token after config change", mlog.Err(err))
|
||||
}
|
||||
} else if oldURL != "" {
|
||||
// URL was cleared, delete the old token
|
||||
s.Log().Info("Push notification server URL cleared, removing auth token")
|
||||
if err := s.PushProxy.DeleteAuthToken(); err != nil {
|
||||
s.Log().Error("Failed to delete auth token after URL cleared", mlog.Err(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if accessControlServiceInterface != nil {
|
||||
app := New(ServerConnector(ch))
|
||||
ch.AccessControl = accessControlServiceInterface(app)
|
||||
|
||||
@@ -110,6 +110,12 @@ func RegisterJobsAccessControlSyncJobInterface(f func(*Server) ejobs.AccessContr
|
||||
jobsAccessControlSyncJobInterface = f
|
||||
}
|
||||
|
||||
var pushProxyInterface func(*App) einterfaces.PushProxyInterface
|
||||
|
||||
func RegisterPushProxyInterface(f func(*App) einterfaces.PushProxyInterface) {
|
||||
pushProxyInterface = f
|
||||
}
|
||||
|
||||
func (s *Server) initEnterprise() {
|
||||
if cloudInterface != nil {
|
||||
s.Cloud = cloudInterface(s)
|
||||
|
||||
@@ -31,7 +31,15 @@ func (a *App) canSendPushNotifications() bool {
|
||||
}
|
||||
|
||||
pushServer := *a.Config().EmailSettings.PushNotificationServer
|
||||
if license := a.Srv().License(); pushServer == model.MHPNS && (license == nil || !*license.Features.MHPNS) {
|
||||
// Check for MHPNS servers (both current and legacy DNS aliases)
|
||||
isMHPNSServer := pushServer == model.MHPNS ||
|
||||
pushServer == model.MHPNSLegacyUS ||
|
||||
pushServer == model.MHPNSLegacyDE ||
|
||||
pushServer == model.MHPNSGlobal ||
|
||||
pushServer == model.MHPNSUS ||
|
||||
pushServer == model.MHPNSEU ||
|
||||
pushServer == model.MHPNSAP
|
||||
if license := a.Srv().License(); isMHPNSServer && (license == nil || !*license.Features.MHPNS) {
|
||||
a.Log().LogM(mlog.MlvlNotificationWarn, "Push notifications are disabled - license missing",
|
||||
mlog.String("status", model.NotificationStatusNotSent),
|
||||
mlog.String("reason", "push_disabled_license"),
|
||||
|
||||
@@ -494,6 +494,14 @@ func (a *App) rawSendToPushProxy(msg *model.PushNotification) (model.PushRespons
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Add auth token and server ID headers if available
|
||||
if a.Srv().PushProxy != nil {
|
||||
if authToken := a.Srv().PushProxy.GetAuthToken(); authToken != "" {
|
||||
request.Header.Set("X-Mattermost-Auth", authToken)
|
||||
request.Header.Set("X-Mattermost-ServerID", a.ServerId())
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := a.Srv().pushNotificationClient.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -563,6 +571,14 @@ func (a *App) SendAckToPushProxy(rctx request.CTX, ack *model.PushNotificationAc
|
||||
return fmt.Errorf("failed to create request: %w", err)
|
||||
}
|
||||
|
||||
// Add auth token and server ID headers if available
|
||||
if a.Srv().PushProxy != nil {
|
||||
if authToken := a.Srv().PushProxy.GetAuthToken(); authToken != "" {
|
||||
request.Header.Set("X-Mattermost-Auth", authToken)
|
||||
request.Header.Set("X-Mattermost-ServerID", a.ServerId())
|
||||
}
|
||||
}
|
||||
|
||||
resp, err := a.Srv().pushNotificationClient.Do(request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to send: %w", err)
|
||||
|
||||
@@ -1422,6 +1422,7 @@ func TestSendAckToPushProxy(t *testing.T) {
|
||||
mockSystemStore.On("GetByName", "UpgradedFromTE").Return(&model.System{Name: "UpgradedFromTE", Value: "false"}, nil)
|
||||
mockSystemStore.On("GetByName", "InstallationDate").Return(&model.System{Name: "InstallationDate", Value: "10"}, nil)
|
||||
mockSystemStore.On("GetByName", "FirstServerRunTimestamp").Return(&model.System{Name: "FirstServerRunTimestamp", Value: "10"}, nil)
|
||||
mockSystemStore.On("Get").Return(model.StringMap{model.SystemServerId: model.NewId()}, nil)
|
||||
|
||||
mockStore.On("User").Return(&mockUserStore)
|
||||
mockStore.On("Post").Return(&mockPostStore)
|
||||
|
||||
@@ -144,6 +144,7 @@ type Server struct {
|
||||
Cloud einterfaces.CloudInterface
|
||||
IPFiltering einterfaces.IPFilteringInterface
|
||||
OutgoingOAuthConnection einterfaces.OutgoingOAuthConnectionInterface
|
||||
PushProxy einterfaces.PushProxyInterface
|
||||
|
||||
ch *Channels
|
||||
}
|
||||
@@ -1453,6 +1454,11 @@ func (s *Server) initJobs() {
|
||||
s.Jobs.RegisterJobType(model.JobTypeAccessControlSync, builder.MakeWorker(), builder.MakeScheduler())
|
||||
}
|
||||
|
||||
if pushProxyInterface != nil {
|
||||
builder := pushProxyInterface(New(ServerConnector(s.Channels())))
|
||||
s.Jobs.RegisterJobType(model.JobTypePushProxyAuth, builder.MakeWorker(), builder.MakeScheduler())
|
||||
}
|
||||
|
||||
s.Jobs.RegisterJobType(
|
||||
model.JobTypeMigrations,
|
||||
migrations.MakeWorker(s.Jobs, s.Store()),
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package einterfaces
|
||||
|
||||
import (
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
ejobs "github.com/mattermost/mattermost/server/v8/einterfaces/jobs"
|
||||
)
|
||||
|
||||
type PushProxyInterface interface {
|
||||
// GetAuthToken returns the current auth token
|
||||
// Returns empty string if not available or enterprise is not enabled
|
||||
GetAuthToken() string
|
||||
|
||||
// GenerateAuthToken generates and stores an authentication token
|
||||
GenerateAuthToken() *model.AppError
|
||||
|
||||
// DeleteAuthToken deletes the stored authentication token
|
||||
DeleteAuthToken() *model.AppError
|
||||
|
||||
// MakeWorker creates a worker for the auth token generation job
|
||||
MakeWorker() model.Worker
|
||||
|
||||
// MakeScheduler creates a scheduler for the auth token generation job
|
||||
MakeScheduler() ejobs.Scheduler
|
||||
}
|
||||
@@ -41,6 +41,8 @@ import (
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/message_export/actiance_export"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/push_proxy"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/message_export/csv_export"
|
||||
// Needed to ensure the init() method in the EE gets run
|
||||
_ "github.com/mattermost/enterprise/message_export/global_relay_export"
|
||||
|
||||
@@ -8752,6 +8752,54 @@
|
||||
"id": "ent.outgoing_oauth_connections.update_connection.audience_invalid",
|
||||
"translation": "The provided audience is invalid: {{ .Error }}"
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.delete.app_error",
|
||||
"translation": "Failed to delete push proxy auth token."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.bad_status.app_error",
|
||||
"translation": "Failed to get auth token from push proxy server."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.create_request.app_error",
|
||||
"translation": "Failed to create HTTP request for push proxy auth."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.empty_token.app_error",
|
||||
"translation": "Push proxy returned empty auth token."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.encrypt.app_error",
|
||||
"translation": "Failed to encrypt payload for push proxy auth."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.http_request.app_error",
|
||||
"translation": "Failed to send HTTP request to push proxy."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.marshal.app_error",
|
||||
"translation": "Failed to marshal payload for push proxy auth."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.marshal_request.app_error",
|
||||
"translation": "Failed to marshal request body for push proxy auth."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.no_key.app_error",
|
||||
"translation": "No encryption key available for push proxy auth."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.parse_response.app_error",
|
||||
"translation": "Failed to parse response from push proxy auth endpoint."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.generate.save_system.app_error",
|
||||
"translation": "Failed to save auth token."
|
||||
},
|
||||
{
|
||||
"id": "ent.push_proxy.worker.interface_nil.app_error",
|
||||
"translation": "Push proxy interface is nil."
|
||||
},
|
||||
{
|
||||
"id": "ent.saml.attribute.app_error",
|
||||
"translation": "SAML login was unsuccessful because one of the attributes is incorrect. Please contact your System Administrator."
|
||||
|
||||
@@ -44,6 +44,7 @@ const (
|
||||
JobTypeDeleteDmsPreferencesMigration = "delete_dms_preferences_migration"
|
||||
JobTypeMobileSessionMetadata = "mobile_session_metadata"
|
||||
JobTypeAccessControlSync = "access_control_sync"
|
||||
JobTypePushProxyAuth = "push_proxy_auth"
|
||||
|
||||
JobStatusPending = "pending"
|
||||
JobStatusInProgress = "in_progress"
|
||||
|
||||
@@ -26,7 +26,16 @@ const (
|
||||
// with the push notifications
|
||||
CategoryCanReply = "CAN_REPLY"
|
||||
|
||||
MHPNS = "https://push.mattermost.com"
|
||||
// Push notification server URLs
|
||||
// Legacy URLs are DNS aliases that automatically route to the regional endpoints
|
||||
MHPNSLegacyUS = "https://push.mattermost.com"
|
||||
MHPNSLegacyDE = "https://hpns-de.mattermost.com"
|
||||
// Current regional URLs
|
||||
MHPNSGlobal = "https://global.push.mattermost.com"
|
||||
MHPNSUS = "https://us.push.mattermost.com"
|
||||
MHPNSEU = "https://eu.push.mattermost.com"
|
||||
MHPNSAP = "https://ap.push.mattermost.com"
|
||||
MHPNS = MHPNSUS // Legacy constant for backwards compatibility
|
||||
|
||||
PushSendPrepare = "Prepared to send"
|
||||
PushSendSuccess = "Successful"
|
||||
|
||||
@@ -20,6 +20,7 @@ const (
|
||||
SystemFirstAdminRole = "FirstAdminRole"
|
||||
SystemFirstServerRunTimestampKey = "FirstServerRunTimestamp"
|
||||
SystemClusterEncryptionKey = "ClusterEncryptionKey"
|
||||
SystemPushProxyAuthToken = "PushProxyAuthToken"
|
||||
SystemUpgradedFromTeId = "UpgradedFromTE"
|
||||
SystemWarnMetricNumberOfTeams5 = "warn_metric_number_of_teams_5"
|
||||
SystemWarnMetricNumberOfChannels50 = "warn_metric_number_of_channels_50"
|
||||
|
||||
+17
-3
@@ -50,6 +50,12 @@ exports[`components/PushSettings should match snapshot, licensed 1`] = `
|
||||
}
|
||||
/>
|
||||
<Memo(DropdownSetting)
|
||||
helpText={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
defaultMessage="Location of the push notification server. Global uses geobalancing to route requests to the nearest server for optimal performance."
|
||||
id="admin.email.pushServerLocationHelp"
|
||||
/>
|
||||
}
|
||||
id="pushNotificationServerLocation"
|
||||
label={
|
||||
<Memo(MemoizedFormattedMessage)
|
||||
@@ -59,9 +65,13 @@ exports[`components/PushSettings should match snapshot, licensed 1`] = `
|
||||
}
|
||||
onChange={[Function]}
|
||||
setByEnv={false}
|
||||
value="us"
|
||||
value="global"
|
||||
values={
|
||||
Array [
|
||||
Object {
|
||||
"text": "Global",
|
||||
"value": "global",
|
||||
},
|
||||
Object {
|
||||
"text": "US",
|
||||
"value": "us",
|
||||
@@ -70,6 +80,10 @@ exports[`components/PushSettings should match snapshot, licensed 1`] = `
|
||||
"text": "Germany",
|
||||
"value": "de",
|
||||
},
|
||||
Object {
|
||||
"text": "Japan",
|
||||
"value": "jp",
|
||||
},
|
||||
]
|
||||
}
|
||||
/>
|
||||
@@ -129,7 +143,7 @@ exports[`components/PushSettings should match snapshot, licensed 1`] = `
|
||||
}
|
||||
}
|
||||
setByEnv={false}
|
||||
value="https://push.mattermost.com"
|
||||
value="https://global.push.mattermost.com"
|
||||
/>
|
||||
<AdminTextSetting
|
||||
helpText={
|
||||
@@ -260,7 +274,7 @@ exports[`components/PushSettings should match snapshot, unlicensed 1`] = `
|
||||
}
|
||||
}
|
||||
setByEnv={false}
|
||||
value="https://push.mattermost.com"
|
||||
value="https://global.push.mattermost.com"
|
||||
/>
|
||||
<AdminTextSetting
|
||||
helpText={
|
||||
|
||||
@@ -13,7 +13,7 @@ describe('components/PushSettings', () => {
|
||||
test('should match snapshot, licensed', () => {
|
||||
const config = {
|
||||
EmailSettings: {
|
||||
PushNotificationServer: 'https://push.mattermost.com',
|
||||
PushNotificationServer: 'https://global.push.mattermost.com',
|
||||
PushNotificationServerType: 'mhpns',
|
||||
SendPushNotifications: true,
|
||||
},
|
||||
@@ -41,7 +41,7 @@ describe('components/PushSettings', () => {
|
||||
test('should match snapshot, unlicensed', () => {
|
||||
const config = {
|
||||
EmailSettings: {
|
||||
PushNotificationServer: 'https://push.mattermost.com',
|
||||
PushNotificationServer: 'https://global.push.mattermost.com',
|
||||
PushNotificationServerType: 'mhpns',
|
||||
SendPushNotifications: true,
|
||||
},
|
||||
|
||||
@@ -34,12 +34,16 @@ const PUSH_NOTIFICATIONS_OFF = 'off';
|
||||
const PUSH_NOTIFICATIONS_MHPNS = 'mhpns';
|
||||
const PUSH_NOTIFICATIONS_MTPNS = 'mtpns';
|
||||
const PUSH_NOTIFICATIONS_CUSTOM = 'custom';
|
||||
const PUSH_NOTIFICATIONS_LOCATION_GLOBAL = 'global';
|
||||
const PUSH_NOTIFICATIONS_LOCATION_US = 'us';
|
||||
const PUSH_NOTIFICATIONS_LOCATION_DE = 'de';
|
||||
const PUSH_NOTIFICATIONS_LOCATION_JP = 'jp';
|
||||
|
||||
const PUSH_NOTIFICATIONS_SERVER_DIC = {
|
||||
[PUSH_NOTIFICATIONS_LOCATION_GLOBAL]: Constants.MHPNS_GLOBAL,
|
||||
[PUSH_NOTIFICATIONS_LOCATION_US]: Constants.MHPNS_US,
|
||||
[PUSH_NOTIFICATIONS_LOCATION_DE]: Constants.MHPNS_DE,
|
||||
[PUSH_NOTIFICATIONS_LOCATION_JP]: Constants.MHPNS_JP,
|
||||
};
|
||||
|
||||
const DROPDOWN_ID_SERVER_TYPE = 'pushNotificationServerType';
|
||||
@@ -112,19 +116,31 @@ class PushSettings extends OLDAdminSettings<Props, State> {
|
||||
getStateFromConfig(config: Props['config']) {
|
||||
let pushNotificationServerType: EmailSettings['PushNotificationServerType'] = PUSH_NOTIFICATIONS_CUSTOM;
|
||||
let agree = false;
|
||||
let pushNotificationServerLocation: EmailSettings['PushNotificationServerLocation'] = PUSH_NOTIFICATIONS_LOCATION_US;
|
||||
let pushNotificationServerLocation: EmailSettings['PushNotificationServerLocation'] = PUSH_NOTIFICATIONS_LOCATION_GLOBAL;
|
||||
if (!config.EmailSettings.SendPushNotifications) {
|
||||
pushNotificationServerType = PUSH_NOTIFICATIONS_OFF;
|
||||
} else if (config.EmailSettings.PushNotificationServer === Constants.MHPNS_US &&
|
||||
} else if (config.EmailSettings.PushNotificationServer === Constants.MHPNS_GLOBAL &&
|
||||
this.props.license.IsLicensed === 'true' && this.props.license.MHPNS === 'true') {
|
||||
pushNotificationServerType = PUSH_NOTIFICATIONS_MHPNS;
|
||||
pushNotificationServerLocation = PUSH_NOTIFICATIONS_LOCATION_GLOBAL;
|
||||
agree = true;
|
||||
} else if ((config.EmailSettings.PushNotificationServer === Constants.MHPNS_US ||
|
||||
config.EmailSettings.PushNotificationServer === Constants.MHPNS_LEGACY_US) &&
|
||||
this.props.license.IsLicensed === 'true' && this.props.license.MHPNS === 'true') {
|
||||
pushNotificationServerType = PUSH_NOTIFICATIONS_MHPNS;
|
||||
pushNotificationServerLocation = PUSH_NOTIFICATIONS_LOCATION_US;
|
||||
agree = true;
|
||||
} else if (config.EmailSettings.PushNotificationServer === Constants.MHPNS_DE &&
|
||||
} else if ((config.EmailSettings.PushNotificationServer === Constants.MHPNS_DE ||
|
||||
config.EmailSettings.PushNotificationServer === Constants.MHPNS_LEGACY_DE) &&
|
||||
this.props.license.IsLicensed === 'true' && this.props.license.MHPNS === 'true') {
|
||||
pushNotificationServerType = PUSH_NOTIFICATIONS_MHPNS;
|
||||
pushNotificationServerLocation = PUSH_NOTIFICATIONS_LOCATION_DE;
|
||||
agree = true;
|
||||
} else if (config.EmailSettings.PushNotificationServer === Constants.MHPNS_JP &&
|
||||
this.props.license.IsLicensed === 'true' && this.props.license.MHPNS === 'true') {
|
||||
pushNotificationServerType = PUSH_NOTIFICATIONS_MHPNS;
|
||||
pushNotificationServerLocation = PUSH_NOTIFICATIONS_LOCATION_JP;
|
||||
agree = true;
|
||||
} else if (config.EmailSettings.PushNotificationServer === Constants.MTPNS) {
|
||||
pushNotificationServerType = PUSH_NOTIFICATIONS_MTPNS;
|
||||
}
|
||||
@@ -313,8 +329,10 @@ class PushSettings extends OLDAdminSettings<Props, State> {
|
||||
let locationDropdown;
|
||||
if (this.state.pushNotificationServerType === PUSH_NOTIFICATIONS_MHPNS) {
|
||||
const pushNotificationServerLocations = [
|
||||
{value: PUSH_NOTIFICATIONS_LOCATION_GLOBAL, text: this.props.intl.formatMessage({id: 'admin.email.pushServerLocationGlobal', defaultMessage: 'Global'})},
|
||||
{value: PUSH_NOTIFICATIONS_LOCATION_US, text: this.props.intl.formatMessage({id: 'admin.email.pushServerLocationUS', defaultMessage: 'US'})},
|
||||
{value: PUSH_NOTIFICATIONS_LOCATION_DE, text: this.props.intl.formatMessage({id: 'admin.email.pushServerLocationDE', defaultMessage: 'Germany'})},
|
||||
{value: PUSH_NOTIFICATIONS_LOCATION_JP, text: this.props.intl.formatMessage({id: 'admin.email.pushServerLocationJP', defaultMessage: 'Japan'})},
|
||||
];
|
||||
|
||||
locationDropdown = (
|
||||
@@ -327,6 +345,12 @@ class PushSettings extends OLDAdminSettings<Props, State> {
|
||||
defaultMessage='Push Notification Server location:'
|
||||
/>
|
||||
}
|
||||
helpText={
|
||||
<FormattedMessage
|
||||
id='admin.email.pushServerLocationHelp'
|
||||
defaultMessage='Location of the push notification server. Global uses geobalancing to route requests to the nearest server for optimal performance.'
|
||||
/>
|
||||
}
|
||||
value={this.state.pushNotificationServerLocation}
|
||||
onChange={this.handleDropdownChange}
|
||||
setByEnv={this.isPushNotificationServerSetByEnv()}
|
||||
|
||||
@@ -981,6 +981,9 @@
|
||||
"admin.email.pushOffHelp": "Please see <link>documentation on push notifications</link> to learn more about setup options.",
|
||||
"admin.email.pushServerEx": "E.g.: \"https://push-test.mattermost.com\"",
|
||||
"admin.email.pushServerLocationDE": "Germany",
|
||||
"admin.email.pushServerLocationGlobal": "Global",
|
||||
"admin.email.pushServerLocationHelp": "Location of the push notification server. Global uses geobalancing to route requests to the nearest server for optimal performance.",
|
||||
"admin.email.pushServerLocationJP": "Japan",
|
||||
"admin.email.pushServerLocationTitle": "Push Notification Server location:",
|
||||
"admin.email.pushServerLocationUS": "US",
|
||||
"admin.email.pushServerTitle": "Push Notification Server:",
|
||||
|
||||
@@ -2065,8 +2065,12 @@ export const Constants = {
|
||||
EMOJI_PATH: '/static/emoji',
|
||||
RECENT_EMOJI_KEY: 'recentEmojis',
|
||||
DEFAULT_WEBHOOK_LOGO: logoWebhook,
|
||||
MHPNS_US: 'https://push.mattermost.com',
|
||||
MHPNS_DE: 'https://hpns-de.mattermost.com',
|
||||
MHPNS_LEGACY_US: 'https://push.mattermost.com',
|
||||
MHPNS_LEGACY_DE: 'https://hpns-de.mattermost.com',
|
||||
MHPNS_GLOBAL: 'https://global.push.mattermost.com',
|
||||
MHPNS_US: 'https://us.push.mattermost.com',
|
||||
MHPNS_DE: 'https://eu.push.mattermost.com',
|
||||
MHPNS_JP: 'https://ap.push.mattermost.com',
|
||||
MTPNS: 'https://push-test.mattermost.com',
|
||||
MAX_PREV_MSGS: 100,
|
||||
POST_COLLAPSE_TIMEOUT: 1000 * 60 * 5, // five minutes
|
||||
|
||||
@@ -596,7 +596,7 @@ export type EmailSettings = {
|
||||
SendPushNotifications: boolean;
|
||||
PushNotificationServer: string;
|
||||
PushNotificationServerType: 'off' | 'mhpns' | 'mtpns' | 'custom';
|
||||
PushNotificationServerLocation: 'us' | 'de';
|
||||
PushNotificationServerLocation: 'global' | 'us' | 'de' | 'jp';
|
||||
PushNotificationContents: string;
|
||||
PushNotificationBuffer: number;
|
||||
EnableEmailBatching: boolean;
|
||||
|
||||
Reference in New Issue
Block a user