2021-04-19 17:42:19 +00:00
|
|
|
/*
|
|
|
|
GoToSocial
|
|
|
|
Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package util
|
|
|
|
|
2021-05-08 12:25:55 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"regexp"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
maximumUsernameLength = 64
|
|
|
|
maximumEmojiShortcodeLength = 30
|
|
|
|
maximumHashtagLength = 30
|
|
|
|
)
|
2021-04-19 17:42:19 +00:00
|
|
|
|
|
|
|
var (
|
2021-08-29 10:03:08 +00:00
|
|
|
mentionNameRegexString = `^@(\w+)(?:@([a-zA-Z0-9_\-\.:]+)?)$`
|
2021-05-15 09:58:11 +00:00
|
|
|
// mention name regex captures the username and domain part from a mention string
|
|
|
|
// such as @whatever_user@example.org, returning whatever_user and example.org (without the @ symbols)
|
|
|
|
mentionNameRegex = regexp.MustCompile(mentionNameRegexString)
|
|
|
|
|
2021-04-19 17:42:19 +00:00
|
|
|
// mention regex can be played around with here: https://regex101.com/r/qwM9D3/1
|
2021-07-29 11:18:22 +00:00
|
|
|
mentionFinderRegexString = `(?:\B)(@\w+(?:@[a-zA-Z0-9_\-\.]+)?)(?:\B)?`
|
2021-05-08 12:25:55 +00:00
|
|
|
mentionFinderRegex = regexp.MustCompile(mentionFinderRegexString)
|
|
|
|
|
2021-07-29 11:18:22 +00:00
|
|
|
// hashtag regex can be played with here: https://regex101.com/r/bPxeca/1
|
|
|
|
hashtagFinderRegexString = fmt.Sprintf(`(?:^|\n|\s)(#[a-zA-Z0-9]{1,%d})(?:\b)`, maximumHashtagLength)
|
|
|
|
// HashtagFinderRegex finds possible hashtags in a string.
|
|
|
|
// It returns just the string part of the hashtag, not the # symbol.
|
|
|
|
HashtagFinderRegex = regexp.MustCompile(hashtagFinderRegexString)
|
2021-05-08 12:25:55 +00:00
|
|
|
|
2021-07-29 11:18:22 +00:00
|
|
|
emojiShortcodeRegexString = fmt.Sprintf(`\w{2,%d}`, maximumEmojiShortcodeLength)
|
2021-05-08 12:25:55 +00:00
|
|
|
emojiShortcodeValidationRegex = regexp.MustCompile(fmt.Sprintf("^%s$", emojiShortcodeRegexString))
|
|
|
|
|
|
|
|
// emoji regex can be played with here: https://regex101.com/r/478XGM/1
|
2021-07-29 11:18:22 +00:00
|
|
|
emojiFinderRegexString = fmt.Sprintf(`(?:\B)?:(%s):(?:\B)?`, emojiShortcodeRegexString)
|
2021-05-08 12:25:55 +00:00
|
|
|
emojiFinderRegex = regexp.MustCompile(emojiFinderRegexString)
|
|
|
|
|
|
|
|
// usernameRegexString defines an acceptable username on this instance
|
|
|
|
usernameRegexString = fmt.Sprintf(`[a-z0-9_]{2,%d}`, maximumUsernameLength)
|
|
|
|
// usernameValidationRegex can be used to validate usernames of new signups
|
|
|
|
usernameValidationRegex = regexp.MustCompile(fmt.Sprintf(`^%s$`, usernameRegexString))
|
|
|
|
|
|
|
|
userPathRegexString = fmt.Sprintf(`^?/%s/(%s)$`, UsersPath, usernameRegexString)
|
|
|
|
// userPathRegex parses a path that validates and captures the username part from eg /users/example_username
|
|
|
|
userPathRegex = regexp.MustCompile(userPathRegexString)
|
|
|
|
|
2021-06-26 14:21:40 +00:00
|
|
|
userPublicKeyPathRegexString = fmt.Sprintf(`^?/%s/(%s)/%s`, UsersPath, usernameRegexString, PublicKeyPath)
|
2021-06-27 11:58:59 +00:00
|
|
|
userPublicKeyPathRegex = regexp.MustCompile(userPublicKeyPathRegexString)
|
2021-06-26 14:21:40 +00:00
|
|
|
|
2021-05-08 12:25:55 +00:00
|
|
|
inboxPathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s$`, UsersPath, usernameRegexString, InboxPath)
|
|
|
|
// inboxPathRegex parses a path that validates and captures the username part from eg /users/example_username/inbox
|
|
|
|
inboxPathRegex = regexp.MustCompile(inboxPathRegexString)
|
|
|
|
|
|
|
|
outboxPathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s$`, UsersPath, usernameRegexString, OutboxPath)
|
|
|
|
// outboxPathRegex parses a path that validates and captures the username part from eg /users/example_username/outbox
|
|
|
|
outboxPathRegex = regexp.MustCompile(outboxPathRegexString)
|
|
|
|
|
|
|
|
actorPathRegexString = fmt.Sprintf(`^?/%s/(%s)$`, ActorsPath, usernameRegexString)
|
|
|
|
// actorPathRegex parses a path that validates and captures the username part from eg /actors/example_username
|
|
|
|
actorPathRegex = regexp.MustCompile(actorPathRegexString)
|
|
|
|
|
|
|
|
followersPathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s$`, UsersPath, usernameRegexString, FollowersPath)
|
|
|
|
// followersPathRegex parses a path that validates and captures the username part from eg /users/example_username/followers
|
|
|
|
followersPathRegex = regexp.MustCompile(followersPathRegexString)
|
|
|
|
|
|
|
|
followingPathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s$`, UsersPath, usernameRegexString, FollowingPath)
|
|
|
|
// followingPathRegex parses a path that validates and captures the username part from eg /users/example_username/following
|
|
|
|
followingPathRegex = regexp.MustCompile(followingPathRegexString)
|
|
|
|
|
2021-06-13 16:42:28 +00:00
|
|
|
followPathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s/(%s)$`, UsersPath, usernameRegexString, FollowPath, ulidRegexString)
|
|
|
|
// followPathRegex parses a path that validates and captures the username part and the ulid part
|
|
|
|
// from eg /users/example_username/follow/01F7XT5JZW1WMVSW1KADS8PVDH
|
|
|
|
followPathRegex = regexp.MustCompile(followPathRegexString)
|
|
|
|
|
|
|
|
ulidRegexString = `[0123456789ABCDEFGHJKMNPQRSTVWXYZ]{26}`
|
2021-08-29 14:52:23 +00:00
|
|
|
ulidRegex = regexp.MustCompile(fmt.Sprintf(`^%s$`, ulidRegexString))
|
2021-05-08 12:25:55 +00:00
|
|
|
|
2021-05-24 16:49:48 +00:00
|
|
|
likedPathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s$`, UsersPath, usernameRegexString, LikedPath)
|
|
|
|
// likedPathRegex parses a path that validates and captures the username part from eg /users/example_username/liked
|
|
|
|
likedPathRegex = regexp.MustCompile(likedPathRegexString)
|
|
|
|
|
2021-06-13 16:42:28 +00:00
|
|
|
likePathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s/(%s)$`, UsersPath, usernameRegexString, LikedPath, ulidRegexString)
|
|
|
|
// likePathRegex parses a path that validates and captures the username part and the ulid part
|
|
|
|
// from eg /users/example_username/like/01F7XT5JZW1WMVSW1KADS8PVDH
|
2021-05-24 16:49:48 +00:00
|
|
|
likePathRegex = regexp.MustCompile(likePathRegexString)
|
|
|
|
|
2021-06-13 16:42:28 +00:00
|
|
|
statusesPathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s/(%s)$`, UsersPath, usernameRegexString, StatusesPath, ulidRegexString)
|
|
|
|
// statusesPathRegex parses a path that validates and captures the username part and the ulid part
|
|
|
|
// from eg /users/example_username/statuses/01F7XT5JZW1WMVSW1KADS8PVDH
|
2021-05-08 12:25:55 +00:00
|
|
|
// The regex can be played with here: https://regex101.com/r/G9zuxQ/1
|
|
|
|
statusesPathRegex = regexp.MustCompile(statusesPathRegexString)
|
2021-07-11 14:22:21 +00:00
|
|
|
|
|
|
|
blockPathRegexString = fmt.Sprintf(`^/?%s/(%s)/%s/(%s)$`, UsersPath, usernameRegexString, BlocksPath, ulidRegexString)
|
|
|
|
// blockPathRegex parses a path that validates and captures the username part and the ulid part
|
|
|
|
// from eg /users/example_username/blocks/01F7XT5JZW1WMVSW1KADS8PVDH
|
|
|
|
blockPathRegex = regexp.MustCompile(blockPathRegexString)
|
2021-04-19 17:42:19 +00:00
|
|
|
)
|