feat(mobx): migrate trusted links

This commit is contained in:
Paul Makles 2021-12-17 10:20:55 +00:00
parent 120e6a35d8
commit 89dda8fe82
7 changed files with 57 additions and 12 deletions

View file

@ -146,6 +146,7 @@
"revolt.js": "5.1.0-alpha.15", "revolt.js": "5.1.0-alpha.15",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"sass": "^1.35.1", "sass": "^1.35.1",
"shade-blend-color": "^1.0.0",
"styled-components": "^5.3.0", "styled-components": "^5.3.0",
"typescript": "^4.4.2", "typescript": "^4.4.2",
"ulid": "^2.3.0", "ulid": "^2.3.0",

View file

@ -15,7 +15,7 @@ import { useContext, useEffect, useMemo, useState } from "preact/hooks";
import { internalSubscribe } from "../../lib/eventEmitter"; import { internalSubscribe } from "../../lib/eventEmitter";
import { determineLink } from "../../lib/links"; import { determineLink } from "../../lib/links";
import { getState } from "../../redux"; import { useApplicationState } from "../../mobx/State";
import { Action } from "../../components/ui/Modal"; import { Action } from "../../components/ui/Modal";
@ -132,6 +132,7 @@ interface Props {
export default function Intermediate(props: Props) { export default function Intermediate(props: Props) {
const [screen, openScreen] = useState<Screen>({ id: "none" }); const [screen, openScreen] = useState<Screen>({ id: "none" });
const settings = useApplicationState().settings;
const history = useHistory(); const history = useHistory();
const value = { const value = {
@ -154,10 +155,11 @@ export default function Intermediate(props: Props) {
return true; return true;
} }
case "external": { case "external": {
const { trustedLinks } = getState();
if ( if (
!trusted && !trusted &&
!trustedLinks.domains?.includes(link.url.hostname) !settings.security.isTrustedOrigin(
link.url.hostname,
)
) { ) {
openScreen({ openScreen({
id: "external_link_prompt", id: "external_link_prompt",

View file

@ -1,5 +1,6 @@
import { Text } from "preact-i18n"; import { Text } from "preact-i18n";
import { useApplicationState } from "../../../mobx/State";
import { dispatch } from "../../../redux"; import { dispatch } from "../../../redux";
import Modal from "../../../components/ui/Modal"; import Modal from "../../../components/ui/Modal";
@ -13,6 +14,7 @@ interface Props {
export function ExternalLinkModal({ onClose, link }: Props) { export function ExternalLinkModal({ onClose, link }: Props) {
const { openLink } = useIntermediate(); const { openLink } = useIntermediate();
const settings = useApplicationState().settings;
return ( return (
<Modal <Modal
@ -39,13 +41,10 @@ export function ExternalLinkModal({ onClose, link }: Props) {
onClick: () => { onClick: () => {
try { try {
const url = new URL(link); const url = new URL(link);
dispatch({ settings.security.addTrustedOrigin(url.hostname);
type: "TRUSTED_LINKS_ADD_DOMAIN",
domain: url.hostname,
});
} catch (e) {} } catch (e) {}
openLink(link); openLink(link, true);
onClose(); onClose();
}, },
plain: true, plain: true,

View file

@ -9,6 +9,7 @@ import { EmojiPack } from "../../components/common/Emoji";
import Persistent from "../interfaces/Persistent"; import Persistent from "../interfaces/Persistent";
import Store from "../interfaces/Store"; import Store from "../interfaces/Store";
import SAudio, { SoundOptions } from "./helpers/SAudio"; import SAudio, { SoundOptions } from "./helpers/SAudio";
import SSecurity from "./helpers/SSecurity";
import STheme from "./helpers/STheme"; import STheme from "./helpers/STheme";
interface ISettings { interface ISettings {
@ -24,6 +25,8 @@ interface ISettings {
"appearance:theme:font": Fonts; "appearance:theme:font": Fonts;
"appearance:theme:monoFont": MonospaceFonts; "appearance:theme:monoFont": MonospaceFonts;
"appearance:theme:css": string; "appearance:theme:css": string;
"security:trustedOrigins": string[];
} }
/** /**
@ -34,6 +37,7 @@ export default class Settings implements Store, Persistent<ISettings> {
theme: STheme; theme: STheme;
sounds: SAudio; sounds: SAudio;
security: SSecurity;
/** /**
* Construct new Settings store. * Construct new Settings store.
@ -44,6 +48,7 @@ export default class Settings implements Store, Persistent<ISettings> {
this.theme = new STheme(this); this.theme = new STheme(this);
this.sounds = new SAudio(this); this.sounds = new SAudio(this);
this.security = new SSecurity(this);
} }
get id() { get id() {

View file

@ -1,10 +1,10 @@
import { makeAutoObservable, computed, action } from "mobx"; import { makeAutoObservable, computed, action } from "mobx";
import call_join from "../../../assets/sounds/call_join.mp3";
import call_leave from "../../../assets/sounds/call_leave.mp3";
import message from "../../../assets/sounds/message.mp3";
import outbound from "../../../assets/sounds/outbound.mp3";
import Settings from "../Settings"; import Settings from "../Settings";
import call_join from "./call_join.mp3";
import call_leave from "./call_leave.mp3";
import message from "./message.mp3";
import outbound from "./outbound.mp3";
export type Sounds = "message" | "outbound" | "call_join" | "call_leave"; export type Sounds = "message" | "outbound" | "call_join" | "call_leave";

View file

@ -0,0 +1,33 @@
import { makeAutoObservable, computed, action } from "mobx";
import Settings from "../Settings";
/**
* Helper class for changing security options.
*/
export default class SSecurity {
private settings: Settings;
/**
* Construct a new security helper.
* @param settings Settings parent class
*/
constructor(settings: Settings) {
this.settings = settings;
makeAutoObservable(this);
}
@action addTrustedOrigin(origin: string) {
this.settings.set("security:trustedOrigins", [
...(this.settings.get("security:trustedOrigins") ?? []).filter(
(x) => x !== origin,
),
origin,
]);
}
@computed isTrustedOrigin(origin: string) {
console.log(this.settings.get("security:trustedOrigins"), origin);
return this.settings.get("security:trustedOrigins")?.includes(origin);
}
}

View file

@ -3877,6 +3877,11 @@ serialize-javascript@^4.0.0:
dependencies: dependencies:
randombytes "^2.1.0" randombytes "^2.1.0"
shade-blend-color@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shade-blend-color/-/shade-blend-color-1.0.0.tgz#cfa10d3673a22ba31d552a0e793b708bc24be0bc"
integrity sha512-Tnp/ppF5h3YhPCpeHiZJ2DRnvmo4luu9qpMhuksCT+QInIXJ9alA3Vd9klfEi+RY8Oh7MaK5vzH/qcLo892L1g==
shallowequal@^1.1.0: shallowequal@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"