Skip to content
6 changes: 3 additions & 3 deletions apps/meteor/app/custom-oauth/server/custom_oauth_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { LDAP } from '@rocket.chat/core-services';
import { Logger } from '@rocket.chat/logger';
import { Users } from '@rocket.chat/models';
import { serverFetch as fetch } from '@rocket.chat/server-fetch';
import { isAbsoluteURL } from '@rocket.chat/tools';
import { Accounts } from 'meteor/accounts-base';
import { Match, check } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
Expand All @@ -10,7 +11,6 @@ import { ServiceConfiguration } from 'meteor/service-configuration';
import _ from 'underscore';

import { normalizers, fromTemplate, renameInvalidProperties } from './transform_helpers';
import { isURL } from '../../../lib/utils/isURL';
import { client } from '../../../server/database/utils';
import { callbacks } from '../../../server/lib/callbacks';
import { saveUserIdentity } from '../../lib/server/functions/saveUserIdentity';
Expand Down Expand Up @@ -93,11 +93,11 @@ export class CustomOAuth {
this.identityTokenSentVia = this.tokenSentVia;
}

if (!isURL(this.tokenPath)) {
if (!isAbsoluteURL(this.tokenPath)) {
this.tokenPath = this.serverURL + this.tokenPath;
}

if (!isURL(this.identityPath)) {
if (!isAbsoluteURL(this.identityPath)) {
this.identityPath = this.serverURL + this.identityPath;
}

Expand Down
6 changes: 3 additions & 3 deletions apps/meteor/app/lib/server/functions/sendMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { AppEvents, Apps } from '@rocket.chat/apps';
import { Message } from '@rocket.chat/core-services';
import type { IMessage, IRoom } from '@rocket.chat/core-typings';
import { Messages } from '@rocket.chat/models';
import { isAbsoluteURL } from '@rocket.chat/tools';
import { Match, check } from 'meteor/check';

import { parseUrlsInMessage } from './parseUrlsInMessage';
import { isRelativeURL } from '../../../../lib/utils/isRelativeURL';
import { isURL } from '../../../../lib/utils/isURL';
import { hasPermissionAsync } from '../../../authorization/server/functions/hasPermission';
import { FileUpload } from '../../../file-upload/server';
import { settings } from '../../../settings/server';
Expand All @@ -33,7 +33,7 @@ type SendMessageOptions = {
const validFullURLParam = Match.Where((value) => {
check(value, String);

if (!isURL(value) && !value.startsWith(FileUpload.getPath())) {
if (!isAbsoluteURL(value) && !value.startsWith(FileUpload.getPath())) {
throw new Error('Invalid href value provided');
}

Expand All @@ -47,7 +47,7 @@ const validFullURLParam = Match.Where((value) => {
const validPartialURLParam = Match.Where((value) => {
check(value, String);

if (!isRelativeURL(value) && !isURL(value) && !value.startsWith(FileUpload.getPath())) {
if (!isRelativeURL(value) && !isAbsoluteURL(value) && !value.startsWith(FileUpload.getPath())) {
throw new Error('Invalid href value provided');
}

Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/app/utils/lib/getURL.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { escapeRegExp } from '@rocket.chat/string-helpers';
import { isAbsoluteURL } from '@rocket.chat/tools';

import { isURL } from '../../../lib/utils/isURL';
import { ltrim, rtrim, trim } from '../../../lib/utils/stringUtils';

function getCloudUrl(
Expand Down Expand Up @@ -41,7 +41,7 @@ export const _getURL = (
{ cdn, full, cloud, cloud_route, cloud_params, _cdn_prefix, _root_url_path_prefix, _site_url }: Record<string, any>,
deeplinkUrl?: string,
): string => {
if (isURL(path)) {
if (isAbsoluteURL(path)) {
return path;
}

Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/client/lib/customOAuth/CustomOAuth.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { OAuthConfiguration, OauthConfig } from '@rocket.chat/core-typings';
import { Random } from '@rocket.chat/random';
import { capitalize } from '@rocket.chat/string-helpers';
import { isAbsoluteURL } from '@rocket.chat/tools';
import { Accounts } from 'meteor/accounts-base';
import { Meteor } from 'meteor/meteor';
import { OAuth } from 'meteor/oauth';

import { isURL } from '../../../lib/utils/isURL';
import type { IOAuthProvider } from '../../definitions/IOAuthProvider';
import { createOAuthTotpLoginMethod } from '../../meteor/login/oauth';
import { overrideLoginMethod, type LoginCallback } from '../2fa/overrideLoginMethod';
Expand Down Expand Up @@ -48,7 +48,7 @@ export class CustomOAuth<TServiceName extends string = string> implements IOAuth
this.scope = options.scope ?? 'openid';
this.responseType = options.responseType || 'code';

if (!isURL(this.authorizePath)) {
if (!isAbsoluteURL(this.authorizePath)) {
this.authorizePath = this.serverURL + this.authorizePath;
}
}
Expand Down
4 changes: 0 additions & 4 deletions apps/meteor/lib/utils/isURL.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { isOEmbedUrlWithMetadata } from '@rocket.chat/core-typings';
import { Logger } from '@rocket.chat/logger';
import { OEmbedCache, Messages } from '@rocket.chat/models';
import { serverFetch as fetch } from '@rocket.chat/server-fetch';
import { isAbsoluteURL } from '@rocket.chat/tools';
import he from 'he';
import iconv from 'iconv-lite';
import ipRangeCheck from 'ip-range-check';
Expand All @@ -18,7 +19,6 @@ import { camelCase } from 'lodash';

import { settings } from '../../../../app/settings/server';
import { Info } from '../../../../app/utils/rocketchat.info';
import { isURL } from '../../../../lib/utils/isURL';
import { afterParseUrlContent, beforeGetUrlContent } from '../lib/oembed/providers';

const MAX_EXTERNAL_URL_PREVIEWS = 5;
Expand Down Expand Up @@ -182,7 +182,7 @@ const getUrlContent = async (urlObj: URL, redirectCount = 5): Promise<OEmbedUrlC
const parseUrl = async function (url: string): Promise<{ urlPreview: MessageUrl; foundMeta: boolean }> {
const parsedUrlObject: MessageUrl = { url, meta: {} };
let foundMeta = false;
if (!isURL(url)) {
if (!isAbsoluteURL(url)) {
return { urlPreview: parsedUrlObject, foundMeta };
}

Expand Down
22 changes: 0 additions & 22 deletions apps/meteor/tests/unit/lib/utils/isURL.spec.ts

This file was deleted.

1 change: 1 addition & 0 deletions packages/tools/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export * from './validateEmail';
export * from './truncateString';
export * from './isTruthy';
export * from './getHeader';
export * from './isAbsoluteURL';
27 changes: 27 additions & 0 deletions packages/tools/src/isAbsoluteURL.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { isAbsoluteURL } from './isAbsoluteURL';

describe('isAbsoluteURL', () => {
test.each([
['/', false],
['test', false],
['test/test', false],
['.', false],
['./test', false],
['/absolute/path', false],
['relative/path?query=1', false],
['ftp://example.com', false],
])('should return false for non-absolute URL %# (%s)', (input, expected) => {
expect(isAbsoluteURL(input)).toBe(expected);
});

test.each([
['https://rocket.chat', true],
['http://rocket.chat', true],
['https://example.com/path?query=1#hash', true],
['http://localhost:3000', true],
['data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', true],
['data:text/plain;charset=utf-8,Hello', true],
])('should return true for absolute URL %# (%s)', (input, expected) => {
expect(isAbsoluteURL(input)).toBe(expected);
});
});
1 change: 1 addition & 0 deletions packages/tools/src/isAbsoluteURL.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const isAbsoluteURL = (str: string): boolean => /^(https?:\/\/|data:)/.test(str);
Loading