diff --git a/keyserver/src/creators/invite-link-creator.js b/keyserver/src/creators/invite-link-creator.js --- a/keyserver/src/creators/invite-link-creator.js +++ b/keyserver/src/creators/invite-link-creator.js @@ -3,7 +3,10 @@ import Filter from 'bad-words'; import uuid from 'uuid'; -import { inviteLinkBlobHash } from 'lib/shared/invite-links.js'; +import { + inviteLinkBlobHash, + inviteSecretRegex, +} from 'lib/shared/invite-links.js'; import type { CreateOrUpdatePublicLinkRequest, InviteLink, @@ -33,14 +36,13 @@ import { thisKeyserverID } from '../user/identity.js'; import { getAndAssertKeyserverURLFacts } from '../utils/urls.js'; -const secretRegex = /^[a-zA-Z0-9]+$/; const badWordsFilter = new Filter(); async function createOrUpdatePublicLink( viewer: Viewer, request: CreateOrUpdatePublicLinkRequest, ): Promise { - if (!secretRegex.test(request.name)) { + if (!inviteSecretRegex.test(request.name)) { throw new ServerError('invalid_characters'); } if (badWordsFilter.isProfane(request.name)) { diff --git a/keyserver/src/responders/website-responders.js b/keyserver/src/responders/website-responders.js --- a/keyserver/src/responders/website-responders.js +++ b/keyserver/src/responders/website-responders.js @@ -10,6 +10,7 @@ import { promisify } from 'util'; import stores from 'lib/facts/stores.js'; +import { inviteSecretRegex } from 'lib/shared/invite-links.js'; import getTitle from 'web/title/get-title.js'; import { waitForStream } from '../utils/json-stream.js'; @@ -200,8 +201,6 @@ `); } -const inviteSecretRegex = /^[a-z0-9]+$/i; - // On native, if this responder is called, it means that the app isn't // installed. async function inviteResponder(req: $Request, res: $Response): Promise { diff --git a/lib/shared/invite-links.js b/lib/shared/invite-links.js --- a/lib/shared/invite-links.js +++ b/lib/shared/invite-links.js @@ -45,9 +45,17 @@ return null; } +const inviteSecretRegexString = '[a-zA-Z0-9]+'; +const inviteSecretRegex: RegExp = new RegExp( + `^${inviteSecretRegexString}$`, + 'i', +); + export { inviteLinkErrorMessages, defaultErrorMessage, inviteLinkBlobHash, getKeyserverOverrideForAnInviteLink, + inviteSecretRegexString, + inviteSecretRegex, }; diff --git a/lib/utils/url-utils.js b/lib/utils/url-utils.js --- a/lib/utils/url-utils.js +++ b/lib/utils/url-utils.js @@ -9,6 +9,7 @@ pendingThreadIDRegex, tUserID, } from './validation-utils.js'; +import { inviteSecretRegexString } from '../shared/invite-links.js'; type MutableURLInfo = { year?: number, @@ -79,7 +80,7 @@ 'i', ); const inviteLinkRegex = new RegExp( - '(/|^)handle/invite/([a-zA-Z0-9]+)(/|$)', + `(/|^)handle/invite/(${inviteSecretRegexString})(/|$)`, 'i', ); const qrCodeLoginRegex = new RegExp('(/|^)qr-code(/|$)', 'i');