Skip to content

Commit 71460e4

Browse files
authored
Cleanup of some of the changes (#745)
<!-- Please read https://github.com/SableClient/Sable/blob/dev/CONTRIBUTING.md before submitting your pull request --> ### Description Fixes the issues with the sizing of the user-hero, small saving issue, previews now showing when put in the [](), and matrix.to links being added to link-previews even though they reasonably shouldn't. It also fixes the matrix.to links to be made with a trailing / to avoid weird tricks in the usage of them for malicious purposes This is general maintenance however so does not really need a changeset because its just a bunch of extremely small changes Fixes #740 #### Type of change - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update ### Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings ### AI disclosure: - [ ] Partially AI assisted (clarify which code was AI assisted and briefly explain what it does). - [ ] Fully AI generated (explain what all the generated code does in moderate detail). <!-- Write any explanation required here, but do not generate the explanation using AI!! You must prove you understand what the code in this PR does. --> I had a nightmare that the new version shipped incomplete code
2 parents 02573cd + 38f0b9f commit 71460e4

7 files changed

Lines changed: 60 additions & 55 deletions

File tree

src/app/components/editor/output.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { isUserId } from '$utils/matrix';
88
import type { CustomElement } from './slate';
99
import { BlockType } from './types';
1010
import { getMarkdownCodeSpanRanges, isInsideMarkdownCodeSpan } from './utils';
11+
import { MATRIX_TO_BASE } from '$plugins/matrix-to';
1112

1213
export type OutputOptions = {
1314
/**
@@ -294,6 +295,8 @@ export const getLinks = (serialized: Descendant | Descendant[]): string[] | unde
294295
continue;
295296
}
296297

298+
if (url.startsWith(MATRIX_TO_BASE)) continue;
299+
297300
finalList.add(url);
298301
}
299302

src/app/components/message/MsgTypeRenderers.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
import { MessageTextBody } from './layout';
3838
import { unwrapForwardedContent } from './modals/MessageForward';
3939
import { LINKINPUTREGEX } from '$components/editor';
40+
import { MATRIX_TO_BASE } from '$plugins/matrix-to';
4041

4142
export interface BundleContent extends IPreviewUrlResponse {
4243
matched_url: string;
@@ -118,7 +119,7 @@ const getUrlsFromContent = (
118119
const safeHtml = customBody
119120
.replace(/<pre[^>]*>.*?<\/pre>/gs, '')
120121
.replace(/<code[^>]*>.*?<\/code>/gs, '');
121-
const safeText = safeHtml.replace(/<[^>]*>/g, '');
122+
const safeText = safeHtml.replace(/<[^a][^>]*>/g, '');
122123
const safeUrlsMatch = safeText.match(LINKINPUTREGEX);
123124
let safeUrls = safeUrlsMatch ? [...new Set(safeUrlsMatch)] : [];
124125
safeUrls = safeUrls.map(
@@ -129,7 +130,7 @@ const getUrlsFromContent = (
129130
url
130131
);
131132
const safeUrlsSet = new Set(safeUrls);
132-
urls = urls.filter((url) => safeUrlsSet.has(url));
133+
urls = urls.filter((url) => safeUrlsSet.has(url) && !url.startsWith(MATRIX_TO_BASE));
133134
}
134135

135136
let bundleContent = content['com.beeper.linkpreviews'] as BundleContent[];

src/app/components/user-profile/UserRoomProfile.tsx

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -631,42 +631,42 @@ export function UserRoomProfile({ userId, initialProfile }: Readonly<UserRoomPro
631631
/>
632632
)}
633633
</Box>
634-
</Box>
635-
{ignored && <IgnoredUserAlert />}
636-
{member && membership === bannedMembership && (
637-
<UserBanAlert
638-
userId={userId}
639-
reason={member.events.member?.getContent().reason}
640-
canUnban={canUnban}
641-
bannedBy={member.events.member?.getSender()}
642-
ts={member.events.member?.getTs()}
643-
/>
644-
)}
645-
{member &&
646-
membership === leftMembership &&
647-
member.events.member &&
648-
member.events.member.getSender() !== userId && (
649-
<UserKickAlert
634+
{ignored && <IgnoredUserAlert />}
635+
{member && membership === bannedMembership && (
636+
<UserBanAlert
637+
userId={userId}
638+
reason={member.events.member?.getContent().reason}
639+
canUnban={canUnban}
640+
bannedBy={member.events.member?.getSender()}
641+
ts={member.events.member?.getTs()}
642+
/>
643+
)}
644+
{member &&
645+
membership === leftMembership &&
646+
member.events.member &&
647+
member.events.member.getSender() !== userId && (
648+
<UserKickAlert
649+
reason={member.events.member?.getContent().reason}
650+
kickedBy={member.events.member?.getSender()}
651+
ts={member.events.member?.getTs()}
652+
/>
653+
)}
654+
{member && membership === invitedMembership && (
655+
<UserInviteAlert
656+
userId={userId}
650657
reason={member.events.member?.getContent().reason}
651-
kickedBy={member.events.member?.getSender()}
658+
canKick={canKickUser}
659+
invitedBy={member.events.member?.getSender()}
652660
ts={member.events.member?.getTs()}
653661
/>
654662
)}
655-
{member && membership === invitedMembership && (
656-
<UserInviteAlert
663+
<UserModeration
657664
userId={userId}
658-
reason={member.events.member?.getContent().reason}
659-
canKick={canKickUser}
660-
invitedBy={member.events.member?.getSender()}
661-
ts={member.events.member?.getTs()}
665+
canInvite={canInvite && membership === leftMembership}
666+
canKick={canKickUser && membership === joinedMembership}
667+
canBan={canBanUser && membership !== bannedMembership}
662668
/>
663-
)}
664-
<UserModeration
665-
userId={userId}
666-
canInvite={canInvite && membership === leftMembership}
667-
canKick={canKickUser && membership === joinedMembership}
668-
canBan={canBanUser && membership !== bannedMembership}
669-
/>
669+
</Box>
670670
</Box>
671671
</Box>
672672
);

src/app/features/room/message/MessageEditor.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ export const MessageEditor = as<'div', MessageEditorProps>(
148148
const isHidden =
149149
(bundleContent?.length === 0 ||
150150
bundleContent.filter((b) => s.includes(b.matched_url)).length === 0) &&
151-
strippedS.match(LINKINPUTREGEX) !== null;
151+
strippedS.match(LINKINPUTREGEX) !== null &&
152+
strippedS.startsWith('https://matrix.to/');
152153
newBody += `${isHidden ? (isHTML && ((s.startsWith('<a') && `&lt;${s[0]}`) || `${s[0]}&lt;`)) || `${s[0]}<` : s[0]}${strippedS}${isHidden ? (isHTML && '&gt;') || '>' : ''}`;
153154
});
154155
return newBody;

src/app/features/settings/account/Profile.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,7 @@ function ProfileExtended({ profile, userId }: Readonly<ProfileProps>) {
642642
onSave={(color) =>
643643
handleSaveField('chat.commet.profile_color_scheme', {
644644
color,
645-
brightness: profile?.heroColorScheme?.brightness,
645+
brightness: color ? profile?.heroColorScheme?.brightness : null,
646646
})
647647
}
648648
/>

src/app/plugins/matrix-to.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('getMatrixToUser', () => {
2525
});
2626

2727
it('uses custom base when configured', () => {
28-
setMatrixToBase('https://matrix.example.org');
28+
setMatrixToBase('https://matrix.example.org/');
2929
expect(getMatrixToUser('@alice:example.com')).toBe(
3030
'https://matrix.example.org/#/@alice:example.com'
3131
);
@@ -51,7 +51,7 @@ describe('getMatrixToRoom', () => {
5151
});
5252

5353
it('uses custom base when configured', () => {
54-
setMatrixToBase('https://matrix.example.org');
54+
setMatrixToBase('https://matrix.example.org/');
5555
expect(getMatrixToRoom('#general:example.com')).toBe(
5656
'https://matrix.example.org/#/#general:example.com'
5757
);
@@ -72,7 +72,7 @@ describe('getMatrixToRoomEvent', () => {
7272
});
7373

7474
it('uses custom base when configured', () => {
75-
setMatrixToBase('https://matrix.example.org');
75+
setMatrixToBase('https://matrix.example.org/');
7676
expect(getMatrixToRoomEvent('!room:example.com', '$event123')).toBe(
7777
'https://matrix.example.org/#/!room:example.com/$event123'
7878
);
@@ -97,12 +97,12 @@ describe('testMatrixTo', () => {
9797
});
9898

9999
it('matches custom base URLs after setMatrixToBase', () => {
100-
setMatrixToBase('https://matrix.example.org');
100+
setMatrixToBase('https://matrix.example.org/');
101101
expect(testMatrixTo('https://matrix.example.org/#/@alice:example.com')).toBe(true);
102102
});
103103

104104
it('still matches standard matrix.to after setMatrixToBase (cross-client compat)', () => {
105-
setMatrixToBase('https://matrix.example.org');
105+
setMatrixToBase('https://matrix.example.org/');
106106
expect(testMatrixTo('https://matrix.to/#/@alice:example.com')).toBe(true);
107107
});
108108
});
@@ -121,14 +121,14 @@ describe('parseMatrixToUser', () => {
121121
});
122122

123123
it('parses user links from custom base', () => {
124-
setMatrixToBase('https://matrix.example.org');
124+
setMatrixToBase('https://matrix.example.org/');
125125
expect(parseMatrixToUser('https://matrix.example.org/#/@alice:example.com')).toBe(
126126
'@alice:example.com'
127127
);
128128
});
129129

130130
it('parses standard matrix.to user links even after custom base is set', () => {
131-
setMatrixToBase('https://matrix.example.org');
131+
setMatrixToBase('https://matrix.example.org/');
132132
expect(parseMatrixToUser('https://matrix.to/#/@alice:example.com')).toBe('@alice:example.com');
133133
});
134134
});
@@ -166,15 +166,15 @@ describe('parseMatrixToRoom', () => {
166166
});
167167

168168
it('parses room links from custom base', () => {
169-
setMatrixToBase('https://matrix.example.org');
169+
setMatrixToBase('https://matrix.example.org/');
170170
expect(parseMatrixToRoom('https://matrix.example.org/#/!room:example.com')).toEqual({
171171
roomIdOrAlias: '!room:example.com',
172172
viaServers: undefined,
173173
});
174174
});
175175

176176
it('still parses standard matrix.to room links after custom base is set', () => {
177-
setMatrixToBase('https://matrix.example.org');
177+
setMatrixToBase('https://matrix.example.org/');
178178
expect(parseMatrixToRoom('https://matrix.to/#/!room:example.com')).toEqual({
179179
roomIdOrAlias: '!room:example.com',
180180
viaServers: undefined,
@@ -210,7 +210,7 @@ describe('parseMatrixToRoomEvent', () => {
210210
});
211211

212212
it('parses event links from custom base', () => {
213-
setMatrixToBase('https://matrix.example.org');
213+
setMatrixToBase('https://matrix.example.org/');
214214
expect(
215215
parseMatrixToRoomEvent('https://matrix.example.org/#/!room:example.com/$event123')
216216
).toEqual({
@@ -221,7 +221,7 @@ describe('parseMatrixToRoomEvent', () => {
221221
});
222222

223223
it('still parses standard matrix.to event links after custom base is set', () => {
224-
setMatrixToBase('https://matrix.example.org');
224+
setMatrixToBase('https://matrix.example.org/');
225225
expect(parseMatrixToRoomEvent('https://matrix.to/#/!room:example.com/$event123')).toEqual({
226226
roomIdOrAlias: '!room:example.com',
227227
eventId: '$event123',

src/app/plugins/matrix-to.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
let MATRIX_TO_BASE = 'https://matrix.to';
1+
export let MATRIX_TO_BASE = 'https://matrix.to/';
22

33
/**
44
* Override the default matrix.to base URL (configurable per deployment).
55
* Must be called before any getMatrixTo* functions are used.
66
*/
77
export const setMatrixToBase = (baseUrl?: string): void => {
8-
MATRIX_TO_BASE = baseUrl ? baseUrl.replace(/\/$/, '') : 'https://matrix.to';
8+
MATRIX_TO_BASE = baseUrl ? baseUrl.replace(/\/?$/, '/') : 'https://matrix.to/';
99
};
1010

11-
export const getMatrixToUser = (userId: string): string => `${MATRIX_TO_BASE}/#/${userId}`;
11+
export const getMatrixToUser = (userId: string): string => `${MATRIX_TO_BASE}#/${userId}`;
1212

1313
const withViaServers = (fragment: string, viaServers: string[]): string =>
1414
`${fragment}?${viaServers.map((server) => `via=${server}`).join('&')}`;
@@ -20,7 +20,7 @@ export const getMatrixToRoom = (roomIdOrAlias: string, viaServers?: string[]): s
2020
fragment = withViaServers(fragment, viaServers);
2121
}
2222

23-
return `${MATRIX_TO_BASE}/#/${fragment}`;
23+
return `${MATRIX_TO_BASE}#/${fragment}`;
2424
};
2525

2626
export const getMatrixToRoomEvent = (
@@ -34,7 +34,7 @@ export const getMatrixToRoomEvent = (
3434
fragment = withViaServers(fragment, viaServers);
3535
}
3636

37-
return `${MATRIX_TO_BASE}/#/${fragment}`;
37+
return `${MATRIX_TO_BASE}#/${fragment}`;
3838
};
3939

4040
export type MatrixToRoom = {
@@ -65,16 +65,16 @@ const getMatchRegexes = () => {
6565
if (cachedRegexBase === MATRIX_TO_BASE && cachedRegexes) return cachedRegexes;
6666
cachedRegexBase = MATRIX_TO_BASE;
6767
// Use https? so both http:// and https://matrix.to are accepted (original behaviour).
68-
const standard = `https?://${escapeForRegex('matrix.to')}`;
68+
const standard = `https?://${escapeForRegex('matrix.to/')}`;
6969
const b =
70-
MATRIX_TO_BASE !== 'https://matrix.to'
70+
MATRIX_TO_BASE !== 'https://matrix.to/'
7171
? `(?:${standard}|${escapeForRegex(MATRIX_TO_BASE)})`
7272
: standard;
7373
cachedRegexes = {
7474
any: new RegExp(`^${b}\\S*$`),
75-
user: new RegExp(`^${b}/#/(@[^:\\s]+:[^?/\\s]+)\\/?$`),
76-
room: new RegExp(`^${b}/#/([#!][^?/\\s]+)\\/?(\\?[\\S]*)?$`),
77-
event: new RegExp(`^${b}/#/([#!][^?/\\s]+)/(\\$[^?/\\s]+)\\/?([?\\S]*)?$`),
75+
user: new RegExp(`^${b}#/(@[^:\\s]+:[^?/\\s]+)\\/?$`),
76+
room: new RegExp(`^${b}#/([#!][^?/\\s]+)\\/?(\\?[\\S]*)?$`),
77+
event: new RegExp(`^${b}#/([#!][^?/\\s]+)/(\\$[^?/\\s]+)\\/?([?\\S]*)?$`),
7878
};
7979
return cachedRegexes;
8080
};

0 commit comments

Comments
 (0)