This repository has been archived by the owner on Sep 11, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 833
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Polls: sync push rules on changes to account_data (#10287)
* basic sync setup * formatting * get loudest value for synced rules * more types * test synced rules in notifications settings * type fixes * noimplicitany fixes * remove debug * tidying * extract updatePushRuleActions fn to utils * extract update synced rules * just synchronise in one place? * monitor account data changes AND trigger changes sync in notifications form * lint * setup LoggedInView test with enough mocks * test rule syncing in LoggedInView * strict fixes * more comments * one more comment
- Loading branch information
Kerry
authored
Mar 9, 2023
1 parent
4c6f8ad
commit cef821c
Showing
5 changed files
with
525 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
Copyright 2023 The Matrix.org Foundation C.I.C. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
import { MatrixClient } from "matrix-js-sdk/src/client"; | ||
import { MatrixEvent, EventType } from "matrix-js-sdk/src/matrix"; | ||
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor"; | ||
import { RuleId, IAnnotatedPushRule } from "matrix-js-sdk/src/@types/PushRules"; | ||
import { logger } from "matrix-js-sdk/src/logger"; | ||
|
||
import { VectorPushRulesDefinitions, VectorPushRuleDefinition } from "../../notifications"; | ||
import { updateExistingPushRulesWithActions } from "./updatePushRuleActions"; | ||
|
||
const pushRuleAndKindToAnnotated = ( | ||
ruleAndKind: ReturnType<PushProcessor["getPushRuleAndKindById"]>, | ||
): IAnnotatedPushRule | undefined => | ||
ruleAndKind | ||
? { | ||
...ruleAndKind.rule, | ||
kind: ruleAndKind.kind, | ||
} | ||
: undefined; | ||
|
||
/** | ||
* Checks that any synced rules that exist a given rule are in sync | ||
* And updates any that are out of sync | ||
* Ignores ruleIds that do not exist for the user | ||
* @param matrixClient - cli | ||
* @param pushProcessor - processor used to retrieve current state of rules | ||
* @param ruleId - primary rule | ||
* @param definition - VectorPushRuleDefinition of the primary rule | ||
*/ | ||
const monitorSyncedRule = async ( | ||
matrixClient: MatrixClient, | ||
pushProcessor: PushProcessor, | ||
ruleId: RuleId | string, | ||
definition: VectorPushRuleDefinition, | ||
): Promise<void> => { | ||
const primaryRule = pushRuleAndKindToAnnotated(pushProcessor.getPushRuleAndKindById(ruleId)); | ||
|
||
if (!primaryRule) { | ||
return; | ||
} | ||
const syncedRules: IAnnotatedPushRule[] | undefined = definition.syncedRuleIds | ||
?.map((ruleId) => pushRuleAndKindToAnnotated(pushProcessor.getPushRuleAndKindById(ruleId))) | ||
.filter((n?: IAnnotatedPushRule): n is IAnnotatedPushRule => Boolean(n)); | ||
|
||
// no synced rules to manage | ||
if (!syncedRules?.length) { | ||
return; | ||
} | ||
|
||
const primaryRuleVectorState = definition.ruleToVectorState(primaryRule); | ||
|
||
const outOfSyncRules = syncedRules.filter( | ||
(syncedRule) => definition.ruleToVectorState(syncedRule) !== primaryRuleVectorState, | ||
); | ||
|
||
if (outOfSyncRules.length) { | ||
await updateExistingPushRulesWithActions( | ||
matrixClient, | ||
// eslint-disable-next-line camelcase, @typescript-eslint/naming-convention | ||
outOfSyncRules.map(({ rule_id }) => rule_id), | ||
primaryRule.actions, | ||
); | ||
} | ||
}; | ||
|
||
/** | ||
* On changes to m.push_rules account data, | ||
* check that synced push rules are in sync with their primary rule, | ||
* and update any out of sync rules. | ||
* synced rules are defined in VectorPushRulesDefinitions | ||
* If updating a rule fails for any reason, | ||
* the error is caught and handled silently | ||
* @param accountDataEvent - MatrixEvent | ||
* @param matrixClient - cli | ||
* @returns Resolves when updates are complete | ||
*/ | ||
export const monitorSyncedPushRules = async ( | ||
accountDataEvent: MatrixEvent | undefined, | ||
matrixClient: MatrixClient, | ||
): Promise<void> => { | ||
if (accountDataEvent?.getType() !== EventType.PushRules) { | ||
return; | ||
} | ||
const pushProcessor = new PushProcessor(matrixClient); | ||
|
||
Object.entries(VectorPushRulesDefinitions).forEach(async ([ruleId, definition]) => { | ||
try { | ||
await monitorSyncedRule(matrixClient, pushProcessor, ruleId, definition); | ||
} catch (error) { | ||
logger.error(`Failed to fully synchronise push rules for ${ruleId}`, error); | ||
} | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/* | ||
Copyright 2023 The Matrix.org Foundation C.I.C. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
import { MatrixClient } from "matrix-js-sdk/src/client"; | ||
import { IPushRule, PushRuleAction, PushRuleKind } from "matrix-js-sdk/src/matrix"; | ||
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor"; | ||
|
||
/** | ||
* Sets the actions for a given push rule id and kind | ||
* When actions are falsy, disables the rule | ||
* @param matrixClient - cli | ||
* @param ruleId - rule id to update | ||
* @param kind - PushRuleKind | ||
* @param actions - push rule actions to set for rule | ||
*/ | ||
export const updatePushRuleActions = async ( | ||
matrixClient: MatrixClient, | ||
ruleId: IPushRule["rule_id"], | ||
kind: PushRuleKind, | ||
actions?: PushRuleAction[], | ||
): Promise<void> => { | ||
if (!actions) { | ||
await matrixClient.setPushRuleEnabled("global", kind, ruleId, false); | ||
} else { | ||
await matrixClient.setPushRuleActions("global", kind, ruleId, actions); | ||
await matrixClient.setPushRuleEnabled("global", kind, ruleId, true); | ||
} | ||
}; | ||
|
||
interface PushRuleAndKind { | ||
rule: IPushRule; | ||
kind: PushRuleKind; | ||
} | ||
|
||
/** | ||
* Update push rules with given actions | ||
* Where they already exist for current user | ||
* Rules are updated sequentially and stop at first error | ||
* @param matrixClient - cli | ||
* @param ruleIds - RuleIds of push rules to attempt to set actions for | ||
* @param actions - push rule actions to set for rule | ||
* @returns resolves when all rules have been updated | ||
* @returns rejects when a rule update fails | ||
*/ | ||
export const updateExistingPushRulesWithActions = async ( | ||
matrixClient: MatrixClient, | ||
ruleIds?: IPushRule["rule_id"][], | ||
actions?: PushRuleAction[], | ||
): Promise<void> => { | ||
const pushProcessor = new PushProcessor(matrixClient); | ||
|
||
const rules: PushRuleAndKind[] | undefined = ruleIds | ||
?.map((ruleId) => pushProcessor.getPushRuleAndKindById(ruleId)) | ||
.filter((n: PushRuleAndKind | null): n is PushRuleAndKind => Boolean(n)); | ||
|
||
if (!rules?.length) { | ||
return; | ||
} | ||
for (const { kind, rule } of rules) { | ||
await updatePushRuleActions(matrixClient, rule.rule_id, kind, actions); | ||
} | ||
}; |
Oops, something went wrong.