You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/session/apis/open_group_api/utils/OpenGroupUtils.ts

118 lines
4.0 KiB
TypeScript

import _ from 'lodash';
import { OpenGroupV2Room } from '../../../../data/opengroups';
import { OpenGroupRequestCommonType } from '../opengroupV2/ApiUtil';
Open group regex fixes (#2058) * Open group URL regex fixes - Capital letters in room tokens were not being accepted (it eventually gets lower-cased internally, which works fine, but that happens *after* the URL is tested for acceptability). - `-` in room was not being allowed (it is and always has been on SOGS, session-android, and session-ios). - single-letter room ids are valid, but only 2+ letter ids were being accepted. - complete URL regex wasn't anchored so something like `garbagehttps://example.com/room?public_key=<64hex>moregarbage` was being accepted in the GUI input (it fails later when other code tries to parse it as a URL). - removed `m` modifier from open group regex: without anchors it wasn't doing anything anyway, but *with* anchors it would still allow leading/trailing garbage if delineated by newlines. - public key regex was accepting g-z letters, and not accepting A-F. - various regex cleanups: - use non-capture groups (?:...) rather than capturing groups (...) - avoid repetition in host segment matching - tightened up host pattern matching a bit: - DNS host segments have a max length of 63 - Limit port max length to 5, and disallow starting with 0 * Show an error when the open group URL is invalid It's quite disconcerting when you have a bad open group URL and try to add it and the join button just "doesn't work" without any feedback at all. Fix it to show an error message. (There is already an i18n entry for this because this same message is thrown if the URL can't be parsed later on).
3 years ago
const protocolRegex = new RegExp('https?://');
const dot = '\\.';
const qMark = '\\?';
Open group regex fixes (#2058) * Open group URL regex fixes - Capital letters in room tokens were not being accepted (it eventually gets lower-cased internally, which works fine, but that happens *after* the URL is tested for acceptability). - `-` in room was not being allowed (it is and always has been on SOGS, session-android, and session-ios). - single-letter room ids are valid, but only 2+ letter ids were being accepted. - complete URL regex wasn't anchored so something like `garbagehttps://example.com/room?public_key=<64hex>moregarbage` was being accepted in the GUI input (it fails later when other code tries to parse it as a URL). - removed `m` modifier from open group regex: without anchors it wasn't doing anything anyway, but *with* anchors it would still allow leading/trailing garbage if delineated by newlines. - public key regex was accepting g-z letters, and not accepting A-F. - various regex cleanups: - use non-capture groups (?:...) rather than capturing groups (...) - avoid repetition in host segment matching - tightened up host pattern matching a bit: - DNS host segments have a max length of 63 - Limit port max length to 5, and disallow starting with 0 * Show an error when the open group URL is invalid It's quite disconcerting when you have a bad open group URL and try to add it and the join button just "doesn't work" without any feedback at all. Fix it to show an error message. (There is already an i18n entry for this because this same message is thrown if the URL can't be parsed later on).
3 years ago
const hostSegment = '[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?';
const hostnameRegex = new RegExp(`(?:${hostSegment}${dot})+${hostSegment}`);
const portRegex = ':[1-9][0-9]{0,4}';
Open group regex fixes (#2058) * Open group URL regex fixes - Capital letters in room tokens were not being accepted (it eventually gets lower-cased internally, which works fine, but that happens *after* the URL is tested for acceptability). - `-` in room was not being allowed (it is and always has been on SOGS, session-android, and session-ios). - single-letter room ids are valid, but only 2+ letter ids were being accepted. - complete URL regex wasn't anchored so something like `garbagehttps://example.com/room?public_key=<64hex>moregarbage` was being accepted in the GUI input (it fails later when other code tries to parse it as a URL). - removed `m` modifier from open group regex: without anchors it wasn't doing anything anyway, but *with* anchors it would still allow leading/trailing garbage if delineated by newlines. - public key regex was accepting g-z letters, and not accepting A-F. - various regex cleanups: - use non-capture groups (?:...) rather than capturing groups (...) - avoid repetition in host segment matching - tightened up host pattern matching a bit: - DNS host segments have a max length of 63 - Limit port max length to 5, and disallow starting with 0 * Show an error when the open group URL is invalid It's quite disconcerting when you have a bad open group URL and try to add it and the join button just "doesn't work" without any feedback at all. Fix it to show an error message. (There is already an i18n entry for this because this same message is thrown if the URL can't be parsed later on).
3 years ago
// roomIds allow up to 64 ascii numbers, letters, '_', or '-' chars
export const roomIdV2Regex = '[0-9a-zA-Z_-]{1,64}';
export const publicKeyRegex = '[0-9a-fA-F]{64}';
export const publicKeyParam = 'public_key=';
export const openGroupV2ServerUrlRegex = new RegExp(
Open group regex fixes (#2058) * Open group URL regex fixes - Capital letters in room tokens were not being accepted (it eventually gets lower-cased internally, which works fine, but that happens *after* the URL is tested for acceptability). - `-` in room was not being allowed (it is and always has been on SOGS, session-android, and session-ios). - single-letter room ids are valid, but only 2+ letter ids were being accepted. - complete URL regex wasn't anchored so something like `garbagehttps://example.com/room?public_key=<64hex>moregarbage` was being accepted in the GUI input (it fails later when other code tries to parse it as a URL). - removed `m` modifier from open group regex: without anchors it wasn't doing anything anyway, but *with* anchors it would still allow leading/trailing garbage if delineated by newlines. - public key regex was accepting g-z letters, and not accepting A-F. - various regex cleanups: - use non-capture groups (?:...) rather than capturing groups (...) - avoid repetition in host segment matching - tightened up host pattern matching a bit: - DNS host segments have a max length of 63 - Limit port max length to 5, and disallow starting with 0 * Show an error when the open group URL is invalid It's quite disconcerting when you have a bad open group URL and try to add it and the join button just "doesn't work" without any feedback at all. Fix it to show an error message. (There is already an i18n entry for this because this same message is thrown if the URL can't be parsed later on).
3 years ago
`(?:${protocolRegex.source})?${hostnameRegex.source}(?:${portRegex})?`
);
/**
* Regex to use to check if a string is a v2open completeURL with pubkey.
* Be aware that the /g flag is not set as .test() will otherwise return alternating result
*
* see https://stackoverflow.com/a/9275499/1680951
*/
export const openGroupV2CompleteURLRegex = new RegExp(
Open group regex fixes (#2058) * Open group URL regex fixes - Capital letters in room tokens were not being accepted (it eventually gets lower-cased internally, which works fine, but that happens *after* the URL is tested for acceptability). - `-` in room was not being allowed (it is and always has been on SOGS, session-android, and session-ios). - single-letter room ids are valid, but only 2+ letter ids were being accepted. - complete URL regex wasn't anchored so something like `garbagehttps://example.com/room?public_key=<64hex>moregarbage` was being accepted in the GUI input (it fails later when other code tries to parse it as a URL). - removed `m` modifier from open group regex: without anchors it wasn't doing anything anyway, but *with* anchors it would still allow leading/trailing garbage if delineated by newlines. - public key regex was accepting g-z letters, and not accepting A-F. - various regex cleanups: - use non-capture groups (?:...) rather than capturing groups (...) - avoid repetition in host segment matching - tightened up host pattern matching a bit: - DNS host segments have a max length of 63 - Limit port max length to 5, and disallow starting with 0 * Show an error when the open group URL is invalid It's quite disconcerting when you have a bad open group URL and try to add it and the join button just "doesn't work" without any feedback at all. Fix it to show an error message. (There is already an i18n entry for this because this same message is thrown if the URL can't be parsed later on).
3 years ago
`^${openGroupV2ServerUrlRegex.source}\/${roomIdV2Regex}${qMark}${publicKeyParam}${publicKeyRegex}$`
);
/**
* Just a constant to have less `publicChat:` everywhere.
* This is the prefix used to identify our open groups in the conversation database (v1 or v2)
* Note: It does already have the ':' included
*/
export const openGroupPrefix = 'publicChat:';
/**
* Just a regex to match a public chat (i.e. a string starting with publicChat:)
*/
export const openGroupPrefixRegex = new RegExp(`^${openGroupPrefix}`);
export const openGroupV2ConversationIdRegex = new RegExp(
`${openGroupPrefix}${roomIdV2Regex}@${openGroupV2ServerUrlRegex.source}`
);
/**
* This function returns a full url on an open group v2 room used for sync messages for instance.
* This is basically what the QRcode encodes
*
*/
export function getCompleteUrlFromRoom(roomInfos: OpenGroupV2Room) {
if (
_.isEmpty(roomInfos.serverUrl) ||
_.isEmpty(roomInfos.roomId) ||
_.isEmpty(roomInfos.serverPublicKey)
) {
throw new Error('getCompleteUrlFromRoom needs serverPublicKey, roomid and serverUrl to be set');
}
// serverUrl has the port and protocol already
return `${roomInfos.serverUrl}/${roomInfos.roomId}?${publicKeyParam}${roomInfos.serverPublicKey}`;
}
/**
* Prefix server with https:// if it's not already prefixed with http or https.
*/
export function prefixify(server: string, hasSSL: boolean = true): string {
const hasPrefix = server.match('^https?://');
if (hasPrefix) {
return server;
}
return `http${hasSSL ? 's' : ''}://${server}`;
}
/**
* No sql access. Just how our open groupv2 url looks like.
* ServerUrl can have the protocol and port included, or not
* @returns `${openGroupPrefix}${roomId}@${serverUrl}`
*/
export function getOpenGroupV2ConversationId(serverUrl: string, roomId: string) {
if (!roomId.match(`^${roomIdV2Regex}$`)) {
throw new Error('getOpenGroupV2ConversationId: Invalid roomId');
}
if (!serverUrl.match(openGroupV2ServerUrlRegex)) {
throw new Error('getOpenGroupV2ConversationId: Invalid serverUrl');
}
return `${openGroupPrefix}${roomId}@${serverUrl}`;
}
/**
* No sql access. Just plain string logic
*/
export function getOpenGroupV2FromConversationId(
conversationId: string
): OpenGroupRequestCommonType {
if (isOpenGroupV2(conversationId)) {
const atIndex = conversationId.indexOf('@');
const roomId = conversationId.slice(openGroupPrefix.length, atIndex);
const serverUrl = conversationId.slice(atIndex + 1);
return {
serverUrl,
roomId,
};
}
throw new Error('Not a v2 open group convo id');
}
/**
* Check if this conversation id corresponds to an OpenGroupV2 conversation.
* No access to database are made. Only regex matches
* @param conversationId the convo id to evaluate
* @returns true if this conversation id matches the Opengroupv2 conversation id regex
*/
export function isOpenGroupV2(conversationId: string) {
return openGroupV2ConversationIdRegex.test(conversationId);
}