validates_im 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +48 -0
- data/LICENSE +1 -1
- data/README.md +109 -0
- data/lib/account_name_validator.rb +35 -31
- data/lib/aim_validator.rb +17 -10
- data/lib/discord_validator.rb +39 -0
- data/lib/matrix_validator.rb +63 -0
- data/lib/signal_validator.rb +37 -0
- data/lib/skype_validator.rb +18 -11
- data/lib/steam_validator.rb +16 -5
- data/lib/telegram_validator.rb +44 -0
- data/lib/validates_im/version.rb +5 -0
- data/lib/validates_im.rb +16 -7
- data/lib/xbox_live_validator.rb +24 -11
- data/lib/yahoo_im_validator.rb +20 -13
- data/validates_im.gemspec +44 -62
- metadata +66 -74
- data/.document +0 -5
- data/.gitignore +0 -25
- data/.rspec +0 -1
- data/Gemfile +0 -12
- data/Gemfile.lock +0 -50
- data/README.textile +0 -40
- data/Rakefile +0 -35
- data/VERSION +0 -1
- data/spec/account_name_validator_spec.rb +0 -115
- data/spec/spec_helper.rb +0 -10
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 5cfe1d609f713d30dcf5b90085dab8637eab5698c0f6e4353339a2dc6665837c
|
|
4
|
+
data.tar.gz: 6c88205ae65806151b99b58825268ccb6e8b6be226ab0060438c116ec8c93f65
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 90b9c447eedb4d79e1d03b61b3a9eaf9c8db9a1a8258461235b83a769223836fc7b160044d239a38f42187b7c643117bb77e55c0caeeab74dcbed8d521ee2fb1
|
|
7
|
+
data.tar.gz: c0a71cc4bcedc20b4d693afa6e989377219df7d365fb75e1c7576bb60803304ec306559f59dd7ed127522146d1b3bd3be5901013c07a389b1da98522913e4543
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [2.0.0] - 2026-05-14
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- `DiscordValidator` (`discord: true`) — modern Discord usernames (2-32 chars,
|
|
12
|
+
`a-z0-9._`, no leading/trailing or consecutive periods, no discriminator).
|
|
13
|
+
- `TelegramValidator` (`telegram: true`) — 5-32 chars, alphanumeric + underscore,
|
|
14
|
+
must start with a letter, cannot end with `_`. Optional leading `@` is stripped.
|
|
15
|
+
- `MatrixValidator` (`matrix: true`) — full Matrix user ID syntax
|
|
16
|
+
(`@localpart:domain.tld`) per the current Matrix specification; max 255 chars.
|
|
17
|
+
- `SignalValidator` (`signal: true`) — Signal usernames (2024+), of the form
|
|
18
|
+
`<base>.<digits>` with a 2+ digit discriminator.
|
|
19
|
+
- `min_length 3` / `max_length 12` on `XboxLiveValidator` so empty / overlong
|
|
20
|
+
gamertags now produce sensible errors instead of crashing on `nil[0]`.
|
|
21
|
+
- Modern, hand-written gemspec with `rubygems_mfa_required` metadata.
|
|
22
|
+
- `lib/validates_im/version.rb` exposing `ValidatesIm::VERSION`.
|
|
23
|
+
- GitHub Actions matrix CI across Ruby 3.1-3.4 and ActiveModel 7.0-8.0.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
- Validator regex anchors use `\A` and `\z` instead of `^` and `$`, closing a
|
|
27
|
+
multi-line bypass where an embedded newline would cause obviously-invalid
|
|
28
|
+
values to pass.
|
|
29
|
+
- Bumped minimum supported Ruby to 3.1, minimum ActiveModel/ActiveSupport to 6.1.
|
|
30
|
+
- Replaced the activerecord runtime dependency with `activemodel` (and
|
|
31
|
+
`activesupport`); the gem never required ActiveRecord.
|
|
32
|
+
- Replaced jeweler-driven packaging with a standard gemspec, `bin/console`,
|
|
33
|
+
`bin/setup`, modern `Gemfile` / `Rakefile`.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- `lib/validates_im.rb` no longer self-requires itself in an infinite loop.
|
|
37
|
+
- Removed duplicate `add_dependency` entries (activerecord, rspec, yard, jeweler)
|
|
38
|
+
and stale `README.textile` references in the gemspec.
|
|
39
|
+
- Gemfile now declares `redcarpet` consistently with the Rakefile's YARD setup
|
|
40
|
+
(previous mismatch with `RedCloth` in the gemspec).
|
|
41
|
+
|
|
42
|
+
### Removed
|
|
43
|
+
- Jeweler-managed gemspec template / `VERSION` text file.
|
|
44
|
+
- The legacy `.travis.yml` and old `ruby.yml` workflow (superseded by `ci.yml`).
|
|
45
|
+
|
|
46
|
+
## [1.1.0]
|
|
47
|
+
|
|
48
|
+
Previous release. See git history.
|
data/LICENSE
CHANGED
data/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
validates_im
|
|
2
|
+
============
|
|
3
|
+
|
|
4
|
+
[](https://github.com/RISCfuture/validates_im/actions/workflows/ci.yml)
|
|
5
|
+
[](https://rubygems.org/gems/validates_im)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
**Instant messenger account validators for ActiveModel / Rails**
|
|
9
|
+
|
|
10
|
+
`validates_im` is a small gem that gives you a collection of
|
|
11
|
+
`ActiveModel::EachValidator`s for common instant-messaging and gaming-service
|
|
12
|
+
account names. Drop one onto an attribute and your model will reject malformed
|
|
13
|
+
account IDs at validation time.
|
|
14
|
+
|
|
15
|
+
Supported services
|
|
16
|
+
------------------
|
|
17
|
+
|
|
18
|
+
Modern services:
|
|
19
|
+
|
|
20
|
+
| Validator | DSL key | Description |
|
|
21
|
+
|:-----------------------|:--------------|:-----------------------------------------------------------------------------|
|
|
22
|
+
| `DiscordValidator` | `discord:` | Discord usernames (post-2023 format, no discriminator) |
|
|
23
|
+
| `TelegramValidator` | `telegram:` | Telegram usernames (`@handle` style; leading `@` is stripped automatically) |
|
|
24
|
+
| `MatrixValidator` | `matrix:` | Matrix IDs of the form `@localpart:domain.tld` per the Matrix specification |
|
|
25
|
+
| `SignalValidator` | `signal:` | Signal usernames (`base.NN` with a 2+ digit discriminator) |
|
|
26
|
+
| `SteamValidator` | `steam:` | Steam account IDs |
|
|
27
|
+
| `XboxLiveValidator` | `xbox_live:` | Xbox Live gamertags |
|
|
28
|
+
|
|
29
|
+
Legacy services (kept for backwards compatibility; these services are largely
|
|
30
|
+
defunct):
|
|
31
|
+
|
|
32
|
+
| Validator | DSL key | Description |
|
|
33
|
+
|:----------------------|:-------------|:-------------------------------------|
|
|
34
|
+
| `AimValidator` | `aim:` | AOL Instant Messenger screen names |
|
|
35
|
+
| `YahooImValidator` | `yahoo_im:` | Yahoo! Messenger screen names |
|
|
36
|
+
| `SkypeValidator` | `skype:` | Skype account names |
|
|
37
|
+
|
|
38
|
+
Installation
|
|
39
|
+
------------
|
|
40
|
+
|
|
41
|
+
Add this line to your application's `Gemfile`:
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
gem "validates_im"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
And then execute:
|
|
48
|
+
|
|
49
|
+
```shell
|
|
50
|
+
bundle install
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Or install it yourself as:
|
|
54
|
+
|
|
55
|
+
```shell
|
|
56
|
+
gem install validates_im
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Requires Ruby 3.1+ and ActiveModel 6.1+. The gem works in any project that uses
|
|
60
|
+
ActiveModel validations — Rails is not required, just ActiveModel.
|
|
61
|
+
|
|
62
|
+
Usage
|
|
63
|
+
-----
|
|
64
|
+
|
|
65
|
+
The validators are standard `EachValidator`s. Use them via `validates`:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
class Account < ApplicationRecord
|
|
69
|
+
validates :discord_handle, discord: true, allow_blank: true
|
|
70
|
+
validates :telegram_handle, telegram: true, allow_blank: true
|
|
71
|
+
validates :matrix_id, matrix: true, allow_blank: true
|
|
72
|
+
validates :signal_username, signal: true, allow_blank: true
|
|
73
|
+
validates :steam_id, steam: true, allow_blank: true
|
|
74
|
+
validates :xbox_gamertag, xbox_live: true, allow_blank: true
|
|
75
|
+
end
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The DSL key for a validator is its class name with the `Validator` suffix
|
|
79
|
+
stripped and underscored — so `XboxLiveValidator` becomes `xbox_live:`.
|
|
80
|
+
|
|
81
|
+
Each validator supports the usual `:allow_nil`, `:allow_blank`, and `:message`
|
|
82
|
+
options. Error messages are localized via Rails i18n; the localization keys are
|
|
83
|
+
documented in each validator's class comment.
|
|
84
|
+
|
|
85
|
+
Writing your own validator
|
|
86
|
+
--------------------------
|
|
87
|
+
|
|
88
|
+
`AccountNameValidator` provides a small DSL for declarative account-name
|
|
89
|
+
validators. To add a hypothetical "Talkalot" service:
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
class TalkalotValidator < AccountNameValidator
|
|
93
|
+
min_length 5
|
|
94
|
+
max_length 64
|
|
95
|
+
valid_chars "A-Za-z0-9_"
|
|
96
|
+
first_char "A-Za-z"
|
|
97
|
+
|
|
98
|
+
add_validation(:no_double_underscore) { |value| !value.include?("__") }
|
|
99
|
+
end
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
For services whose IDs don't fit the simple "single account-name string" mould
|
|
103
|
+
(like Matrix's full `@user:server.tld` syntax), subclass
|
|
104
|
+
`ActiveModel::EachValidator` directly — see `MatrixValidator` for an example.
|
|
105
|
+
|
|
106
|
+
License
|
|
107
|
+
-------
|
|
108
|
+
|
|
109
|
+
MIT. See `LICENSE`.
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/core_ext/string/filters"
|
|
4
|
+
|
|
5
|
+
# Generic `EachValidator` that validates account names on various communication
|
|
2
6
|
# services such as Skype, Yahoo!, etc. This class provides a simple DSL for
|
|
3
7
|
# describing valid account names on these sites, performing all validation for
|
|
4
8
|
# you.
|
|
@@ -6,67 +10,68 @@
|
|
|
6
10
|
# Subclass this class and use the provided DSL to describe account names on a
|
|
7
11
|
# given site. An example for a fictional service called Talkalot:
|
|
8
12
|
#
|
|
9
|
-
#
|
|
13
|
+
# ```` ruby
|
|
10
14
|
# class TalkalotValidator < AccountNameValidator
|
|
11
15
|
# min_length 5
|
|
12
16
|
# max_length 64
|
|
13
17
|
# valid_chars "A-Z0-9_"
|
|
14
18
|
# end
|
|
15
|
-
#
|
|
19
|
+
# ````
|
|
16
20
|
#
|
|
17
21
|
# With your validator defined you can now use it in your Active Record models
|
|
18
|
-
# like any other
|
|
22
|
+
# like any other `EachValidator`:
|
|
19
23
|
#
|
|
20
|
-
#
|
|
24
|
+
# ```` ruby
|
|
21
25
|
# validates :talkalot_id,
|
|
22
26
|
# talkalot: true
|
|
23
|
-
#
|
|
27
|
+
# ````
|
|
24
28
|
#
|
|
25
29
|
# This class automatically handles the following options passed to the
|
|
26
|
-
#
|
|
30
|
+
# `validates` method:
|
|
27
31
|
#
|
|
28
|
-
# |
|
|
29
|
-
#
|
|
32
|
+
# | | |
|
|
33
|
+
# |:-------------|:--------------------------------|
|
|
34
|
+
# | `:allow_nil` | Allows `nil` values. |
|
|
35
|
+
# | `:message` | Provide a custom error message. |
|
|
30
36
|
#
|
|
31
37
|
# Error messages generated by this class are stored in the translation table.
|
|
32
38
|
# The localization keys used are generated by the
|
|
33
|
-
#
|
|
39
|
+
# `ActiveModel::Errors#generate_message` method (see its documentation for more
|
|
34
40
|
# information). The lastmost element of the localization key is the error
|
|
35
41
|
# message key. The error message key is a combination of a validator subclass's
|
|
36
42
|
# {.error_key_prefix} and the error key suffix for a given constraint.
|
|
37
43
|
#
|
|
38
44
|
# By default the error key prefix is the underscored
|
|
39
45
|
#
|
|
40
|
-
# As an example, for the
|
|
46
|
+
# As an example, for the `TalkalotValidator` example above, the error message
|
|
41
47
|
# key used in the event that a two-letter account name is given would be
|
|
42
|
-
#
|
|
48
|
+
# `:talkalot_too_short`. If you wanted to override the prefix, you could do:
|
|
43
49
|
#
|
|
44
|
-
#
|
|
50
|
+
# ```` ruby
|
|
45
51
|
# class TalkalotValidator < AccountNameValidator
|
|
46
52
|
# error_key_prefix :talky
|
|
47
53
|
# end
|
|
48
|
-
#
|
|
54
|
+
# ````
|
|
49
55
|
#
|
|
50
56
|
# In this case the error message key for a two-letter account name would be
|
|
51
|
-
#
|
|
57
|
+
# `:talky_too_short`. (You'd do this if Talkalot accounts were called "talkies,"
|
|
52
58
|
# for example.)
|
|
53
59
|
#
|
|
54
60
|
# @abstract Subclass this validator to perform your specific account name
|
|
55
61
|
# validations.
|
|
56
62
|
|
|
57
63
|
class AccountNameValidator < ActiveModel::EachValidator
|
|
58
|
-
|
|
64
|
+
class_attribute :validations
|
|
59
65
|
self.validations = Array.new
|
|
60
66
|
|
|
61
67
|
# @private
|
|
62
68
|
def validate_each(record, attribute, value)
|
|
63
|
-
return if options[:allow_nil]
|
|
64
|
-
return if options[:allow_blank]
|
|
69
|
+
return if options[:allow_nil] && value.nil?
|
|
70
|
+
return if options[:allow_blank] && value.blank?
|
|
65
71
|
return unless self.class.validations
|
|
66
|
-
self.class.validations.each { |block, key| record.errors.add(attribute, options[:message] || record.errors.generate_message(attribute, :"#{self.class.error_key_prefix}_#{key}")) if !block[value.to_s] }
|
|
67
|
-
end
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
self.class.validations.each { |block, key| record.errors.add(attribute, options[:message] || record.errors.generate_message(attribute, :"#{self.class.error_key_prefix}_#{key}")) unless block[value.to_s] }
|
|
74
|
+
end
|
|
70
75
|
|
|
71
76
|
# @overload error_key_prefix
|
|
72
77
|
# Returns the prefix for error message keys used by this class.
|
|
@@ -77,11 +82,9 @@ class AccountNameValidator < ActiveModel::EachValidator
|
|
|
77
82
|
# @param [Symbol] value The new error message key prefix.
|
|
78
83
|
|
|
79
84
|
def self.error_key_prefix(value=nil)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return @error_key_prefix || to_s.demodulize.sub(/Validator$/, '').underscore.to_sym
|
|
84
|
-
end
|
|
85
|
+
return @error_key_prefix || to_s.demodulize.sub(/Validator$/, "").underscore.to_sym unless value
|
|
86
|
+
|
|
87
|
+
@error_key_prefix = value
|
|
85
88
|
end
|
|
86
89
|
|
|
87
90
|
# Describes a custom restraint on account names.
|
|
@@ -89,12 +92,13 @@ class AccountNameValidator < ActiveModel::EachValidator
|
|
|
89
92
|
# @param [Symbol] key The error message key suffix to use.
|
|
90
93
|
# @yield [value] The custom validation.
|
|
91
94
|
# @yieldparam [String] value The value to validate. This will have been
|
|
92
|
-
# coerced into a
|
|
95
|
+
# coerced into a `String`.
|
|
93
96
|
# @yieldreturn [true, false] Whether or not the validation succeeded.
|
|
94
97
|
|
|
95
98
|
def self.add_validation(key, &block)
|
|
96
|
-
return unless
|
|
97
|
-
|
|
99
|
+
return unless block
|
|
100
|
+
|
|
101
|
+
self.validations += [[block, key]]
|
|
98
102
|
end
|
|
99
103
|
|
|
100
104
|
# Enforces a minimum length on account names. Uses the "too_short" error
|
|
@@ -122,7 +126,7 @@ class AccountNameValidator < ActiveModel::EachValidator
|
|
|
122
126
|
# format (e.g., "[A-Z0-9_]").
|
|
123
127
|
|
|
124
128
|
def self.valid_chars(charlist)
|
|
125
|
-
add_validation(:invalid_chars) { |value| value =~
|
|
129
|
+
add_validation(:invalid_chars) { |value| value =~ /\A[#{charlist}]+\z/ }
|
|
126
130
|
end
|
|
127
131
|
|
|
128
132
|
# Enforces a valid set of characters for the first character of the account
|
|
@@ -132,6 +136,6 @@ class AccountNameValidator < ActiveModel::EachValidator
|
|
|
132
136
|
# format (e.g., "[A-Z0-9_]").
|
|
133
137
|
|
|
134
138
|
def self.first_char(charlist)
|
|
135
|
-
add_validation(:invalid_first_char) { |value| value[0] =~
|
|
139
|
+
add_validation(:invalid_first_char) { |value| value[0] =~ /\A[#{charlist}]\z/ }
|
|
136
140
|
end
|
|
137
141
|
end
|
data/lib/aim_validator.rb
CHANGED
|
@@ -1,25 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Validates AOL Instant Messenger screen names. According to the AOL website:
|
|
2
4
|
#
|
|
3
|
-
#
|
|
5
|
+
# > 3-16 letters or numbers. It must start with a letter.
|
|
4
6
|
#
|
|
5
7
|
# The following error message keys are used to localize invalid screen names:
|
|
6
8
|
#
|
|
7
|
-
# |
|
|
8
|
-
#
|
|
9
|
-
# |
|
|
10
|
-
# |
|
|
9
|
+
# | | |
|
|
10
|
+
# |:-------------------------|:-----------------------------------------|
|
|
11
|
+
# | `aim_too_short` | Screen name is less than 3 characters. |
|
|
12
|
+
# | `aim_too_long` | Screen name is over 16 characters. |
|
|
13
|
+
# | `aim_invalid_chars` | Screen name contains invalid characters. |
|
|
14
|
+
# | `aim_invalid_first_char` | Screen name doesn't start with a letter. |
|
|
11
15
|
#
|
|
12
16
|
# @example
|
|
13
17
|
# validates :aim_screen_name, aim: true
|
|
14
18
|
#
|
|
15
|
-
#
|
|
19
|
+
# Options
|
|
20
|
+
# -------
|
|
16
21
|
#
|
|
17
|
-
# |
|
|
18
|
-
#
|
|
22
|
+
# | | |
|
|
23
|
+
# |:-------------|:-------------------------------------------------|
|
|
24
|
+
# | `:message` | A custom message to use if the email is invalid. |
|
|
25
|
+
# | `:allow_nil` | If true, `nil` values are allowed. |
|
|
19
26
|
|
|
20
27
|
class AimValidator < AccountNameValidator
|
|
21
28
|
min_length 3
|
|
22
29
|
max_length 16
|
|
23
|
-
valid_chars
|
|
24
|
-
first_char
|
|
30
|
+
valid_chars "A-Za-z0-9"
|
|
31
|
+
first_char "A-Za-z"
|
|
25
32
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Validates Discord usernames using the modern (post-2023) username format.
|
|
4
|
+
# Discord eliminated the four-digit `#1234` discriminator system in 2023; usernames
|
|
5
|
+
# are now globally unique and use the rules below:
|
|
6
|
+
#
|
|
7
|
+
# * 2-32 characters long
|
|
8
|
+
# * Lowercase letters (`a`-`z`), digits (`0`-`9`), underscore (`_`), and period (`.`)
|
|
9
|
+
# * No consecutive periods (`..`)
|
|
10
|
+
# * Cannot start or end with a period
|
|
11
|
+
#
|
|
12
|
+
# The following error message keys are used to localize invalid usernames:
|
|
13
|
+
#
|
|
14
|
+
# | | |
|
|
15
|
+
# |:-----------------------------|:--------------------------------------------------------|
|
|
16
|
+
# | `discord_too_short` | Username is less than 2 characters. |
|
|
17
|
+
# | `discord_too_long` | Username is over 32 characters. |
|
|
18
|
+
# | `discord_invalid_chars` | Username contains characters outside `[a-z0-9._]`. |
|
|
19
|
+
# | `discord_invalid_format` | Username has consecutive periods or starts/ends with a period. |
|
|
20
|
+
#
|
|
21
|
+
# @example
|
|
22
|
+
# validates :discord, discord: true
|
|
23
|
+
#
|
|
24
|
+
# Options
|
|
25
|
+
# -------
|
|
26
|
+
#
|
|
27
|
+
# | | |
|
|
28
|
+
# |:-------------|:-------------------------------------------------|
|
|
29
|
+
# | `:message` | A custom message to use if the username is invalid. |
|
|
30
|
+
# | `:allow_nil` | If true, `nil` values are allowed. |
|
|
31
|
+
|
|
32
|
+
class DiscordValidator < AccountNameValidator
|
|
33
|
+
min_length 2
|
|
34
|
+
max_length 32
|
|
35
|
+
valid_chars "a-z0-9._"
|
|
36
|
+
add_validation(:invalid_format) do |value|
|
|
37
|
+
!value.include?("..") && !value.start_with?(".") && !value.end_with?(".")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Validates Matrix user IDs in the form `@localpart:domain.tld` per the Matrix
|
|
4
|
+
# specification (https://spec.matrix.org/latest/appendices/#user-identifiers).
|
|
5
|
+
#
|
|
6
|
+
# * Begins with `@`.
|
|
7
|
+
# * Localpart consists of lowercase letters `a`-`z`, digits `0`-`9`, and any of
|
|
8
|
+
# `-`, `_`, `.`, `=`, `/`, `+`.
|
|
9
|
+
# * `:` separator between the localpart and the server name (domain).
|
|
10
|
+
# * The server name is a hostname (with optional port).
|
|
11
|
+
# * The entire ID must be 255 characters or fewer.
|
|
12
|
+
#
|
|
13
|
+
# Historical Matrix IDs allowed additional characters in the localpart; this
|
|
14
|
+
# validator enforces the current ("grammar") rules from the spec.
|
|
15
|
+
#
|
|
16
|
+
# The following error message keys are used to localize invalid IDs:
|
|
17
|
+
#
|
|
18
|
+
# | | |
|
|
19
|
+
# |:-------------------------|:--------------------------------------|
|
|
20
|
+
# | `matrix_too_long` | ID is over 255 characters. |
|
|
21
|
+
# | `matrix_invalid_format` | ID does not match `@localpart:domain`. |
|
|
22
|
+
#
|
|
23
|
+
# @example
|
|
24
|
+
# validates :matrix_id, matrix: true
|
|
25
|
+
#
|
|
26
|
+
# Options
|
|
27
|
+
# -------
|
|
28
|
+
#
|
|
29
|
+
# | | |
|
|
30
|
+
# |:-------------|:-------------------------------------------------|
|
|
31
|
+
# | `:message` | A custom message to use if the ID is invalid. |
|
|
32
|
+
# | `:allow_nil` | If true, `nil` values are allowed. |
|
|
33
|
+
|
|
34
|
+
class MatrixValidator < ActiveModel::EachValidator
|
|
35
|
+
MAX_LENGTH = 255
|
|
36
|
+
|
|
37
|
+
# Localpart per the Matrix spec, restricted to the documented character set.
|
|
38
|
+
LOCALPART = %r{[a-z0-9._=/+\-]+}.freeze
|
|
39
|
+
|
|
40
|
+
# A reasonably-strict hostname or IP literal, optionally followed by `:port`.
|
|
41
|
+
HOSTNAME_LABEL = /[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?/.freeze
|
|
42
|
+
HOSTNAME = /#{HOSTNAME_LABEL}(?:\.#{HOSTNAME_LABEL})*/.freeze
|
|
43
|
+
IPV4 = /(?:\d{1,3}\.){3}\d{1,3}/.freeze
|
|
44
|
+
IPV6 = /\[[0-9A-Fa-f:.]+\]/.freeze
|
|
45
|
+
SERVERNAME = /(?:#{IPV6}|#{IPV4}|#{HOSTNAME})(?::\d{1,5})?/.freeze
|
|
46
|
+
|
|
47
|
+
FORMAT = /\A@#{LOCALPART}:#{SERVERNAME}\z/.freeze
|
|
48
|
+
|
|
49
|
+
def validate_each(record, attribute, value)
|
|
50
|
+
return if options[:allow_nil] && value.nil?
|
|
51
|
+
return if options[:allow_blank] && value.blank?
|
|
52
|
+
|
|
53
|
+
str = value.to_s
|
|
54
|
+
|
|
55
|
+
if str.length > MAX_LENGTH
|
|
56
|
+
record.errors.add(attribute, options[:message] || record.errors.generate_message(attribute, :matrix_too_long))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
unless str.match?(FORMAT)
|
|
60
|
+
record.errors.add(attribute, options[:message] || record.errors.generate_message(attribute, :matrix_invalid_format))
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Validates Signal usernames. Signal introduced usernames in 2024; they consist
|
|
4
|
+
# of a base name and a numeric discriminator separated by a period:
|
|
5
|
+
#
|
|
6
|
+
# <base>.<digits>
|
|
7
|
+
#
|
|
8
|
+
# * Base: starts with a letter, contains letters, digits, and underscores.
|
|
9
|
+
# * Discriminator: two or more digits (leading zeros allowed, e.g. `0123`).
|
|
10
|
+
# * Combined length 3-32 characters (matching Signal's UI constraints).
|
|
11
|
+
#
|
|
12
|
+
# The following error message keys are used to localize invalid usernames:
|
|
13
|
+
#
|
|
14
|
+
# | | |
|
|
15
|
+
# |:-----------------------------|:---------------------------------------------------------------|
|
|
16
|
+
# | `signal_too_short` | Username is less than 3 characters. |
|
|
17
|
+
# | `signal_too_long` | Username is over 32 characters. |
|
|
18
|
+
# | `signal_invalid_format` | Username doesn't match `<base>.<digits>` with a valid base. |
|
|
19
|
+
#
|
|
20
|
+
# @example
|
|
21
|
+
# validates :signal_username, signal: true
|
|
22
|
+
#
|
|
23
|
+
# Options
|
|
24
|
+
# -------
|
|
25
|
+
#
|
|
26
|
+
# | | |
|
|
27
|
+
# |:-------------|:-------------------------------------------------|
|
|
28
|
+
# | `:message` | A custom message to use if the username is invalid. |
|
|
29
|
+
# | `:allow_nil` | If true, `nil` values are allowed. |
|
|
30
|
+
|
|
31
|
+
class SignalValidator < AccountNameValidator
|
|
32
|
+
FORMAT = /\A[A-Za-z][A-Za-z0-9_]*\.\d{2,}\z/.freeze
|
|
33
|
+
|
|
34
|
+
min_length 3
|
|
35
|
+
max_length 32
|
|
36
|
+
add_validation(:invalid_format) { |value| value.match?(FORMAT) }
|
|
37
|
+
end
|
data/lib/skype_validator.rb
CHANGED
|
@@ -1,26 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Validates Skype screen names. From the Skype website:
|
|
2
4
|
#
|
|
3
|
-
#
|
|
4
|
-
# letters and numbers (no spaces or special characters).
|
|
5
|
+
# > It must be between 6-32 characters, start with a letter and contain only
|
|
6
|
+
# > letters and numbers (no spaces or special characters).
|
|
5
7
|
#
|
|
6
8
|
# The following error message keys are used to localize invalid screen names.
|
|
7
9
|
#
|
|
8
|
-
# |
|
|
9
|
-
#
|
|
10
|
-
# |
|
|
11
|
-
# |
|
|
10
|
+
# | | |
|
|
11
|
+
# |:---------------------------|:----------------------------------------|
|
|
12
|
+
# | `skype_too_short` | Skype name is less than 6 characters. |
|
|
13
|
+
# | `skype_too_long` | Skype name is over 32 characters. |
|
|
14
|
+
# | `skype_invalid_chars` | Skype name contains invalid characters. |
|
|
15
|
+
# | `skype_invalid_first_char` | Skype name doesn't start with a letter. |
|
|
12
16
|
#
|
|
13
17
|
# @example
|
|
14
18
|
# validates :skype_name, skype: true
|
|
15
19
|
#
|
|
16
|
-
#
|
|
20
|
+
# Options
|
|
21
|
+
# -------
|
|
17
22
|
#
|
|
18
|
-
# |
|
|
19
|
-
#
|
|
23
|
+
# | | |
|
|
24
|
+
# |:-------------|:-------------------------------------------------|
|
|
25
|
+
# | `:message` | A custom message to use if the email is invalid. |
|
|
26
|
+
# | `:allow_nil` | If true, `nil` values are allowed. |
|
|
20
27
|
|
|
21
28
|
class SkypeValidator < AccountNameValidator
|
|
22
29
|
min_length 6
|
|
23
30
|
max_length 32
|
|
24
|
-
valid_chars
|
|
25
|
-
first_char
|
|
31
|
+
valid_chars "A-Za-z0-9"
|
|
32
|
+
first_char "A-Za-z"
|
|
26
33
|
end
|
data/lib/steam_validator.rb
CHANGED
|
@@ -1,18 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# Validates steam account IDs. Steam IDs are between 3 and 63 characters long
|
|
2
4
|
# and consist of letters, numbers, or underscores.
|
|
3
5
|
#
|
|
4
6
|
# The following error message keys are used to localize invalid screen names.
|
|
5
7
|
#
|
|
6
|
-
# |
|
|
7
|
-
#
|
|
8
|
-
# |
|
|
9
|
-
# |
|
|
8
|
+
# | | |
|
|
9
|
+
# |:----------------------|:--------------------------------------|
|
|
10
|
+
# | `steam_too_short` | Steam ID is less than 6 characters. |
|
|
11
|
+
# | `steam_too_long` | Steam ID is over 32 characters. |
|
|
12
|
+
# | `steam_invalid_chars` | Steam ID contains invalid characters. |
|
|
10
13
|
#
|
|
11
14
|
# @example
|
|
12
15
|
# validates :steam_id, steam: true
|
|
16
|
+
#
|
|
17
|
+
# Options
|
|
18
|
+
# -------
|
|
19
|
+
#
|
|
20
|
+
# | | |
|
|
21
|
+
# |:-------------|:-------------------------------------------------|
|
|
22
|
+
# | `:message` | A custom message to use if the email is invalid. |
|
|
23
|
+
# | `:allow_nil` | If true, `nil` values are allowed. |
|
|
13
24
|
|
|
14
25
|
class SteamValidator < AccountNameValidator
|
|
15
26
|
min_length 3
|
|
16
27
|
max_length 63
|
|
17
|
-
valid_chars
|
|
28
|
+
valid_chars "A-Za-z0-9_"
|
|
18
29
|
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Validates Telegram usernames. Telegram usernames are 5-32 characters of
|
|
4
|
+
# alphanumerics and underscores; they must start with a letter and cannot end
|
|
5
|
+
# with an underscore. Username lookups are case-insensitive. A leading `@` is
|
|
6
|
+
# stripped before validation.
|
|
7
|
+
#
|
|
8
|
+
# The following error message keys are used to localize invalid usernames:
|
|
9
|
+
#
|
|
10
|
+
# | | |
|
|
11
|
+
# |:-------------------------------|:------------------------------------------------------|
|
|
12
|
+
# | `telegram_too_short` | Username is less than 5 characters. |
|
|
13
|
+
# | `telegram_too_long` | Username is over 32 characters. |
|
|
14
|
+
# | `telegram_invalid_chars` | Username contains characters outside `[A-Za-z0-9_]`. |
|
|
15
|
+
# | `telegram_invalid_first_char` | Username doesn't start with a letter. |
|
|
16
|
+
# | `telegram_trailing_underscore` | Username ends with an underscore. |
|
|
17
|
+
#
|
|
18
|
+
# @example
|
|
19
|
+
# validates :telegram, telegram: true
|
|
20
|
+
#
|
|
21
|
+
# Options
|
|
22
|
+
# -------
|
|
23
|
+
#
|
|
24
|
+
# | | |
|
|
25
|
+
# |:-------------|:-------------------------------------------------|
|
|
26
|
+
# | `:message` | A custom message to use if the username is invalid. |
|
|
27
|
+
# | `:allow_nil` | If true, `nil` values are allowed. |
|
|
28
|
+
|
|
29
|
+
class TelegramValidator < AccountNameValidator
|
|
30
|
+
min_length 5
|
|
31
|
+
max_length 32
|
|
32
|
+
valid_chars "A-Za-z0-9_"
|
|
33
|
+
first_char "A-Za-z"
|
|
34
|
+
add_validation(:trailing_underscore) { |value| !value.end_with?("_") }
|
|
35
|
+
|
|
36
|
+
# Overrides {AccountNameValidator#validate_each} to strip an optional leading
|
|
37
|
+
# `@` before applying validations.
|
|
38
|
+
def validate_each(record, attribute, value)
|
|
39
|
+
if value.is_a?(String) && value.start_with?("@")
|
|
40
|
+
value = value[1..]
|
|
41
|
+
end
|
|
42
|
+
super
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/validates_im.rb
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
|
|
5
|
-
require
|
|
6
|
-
|
|
7
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_model"
|
|
4
|
+
|
|
5
|
+
require "validates_im/version"
|
|
6
|
+
|
|
7
|
+
require "account_name_validator"
|
|
8
|
+
require "aim_validator"
|
|
9
|
+
require "discord_validator"
|
|
10
|
+
require "matrix_validator"
|
|
11
|
+
require "signal_validator"
|
|
12
|
+
require "skype_validator"
|
|
13
|
+
require "steam_validator"
|
|
14
|
+
require "telegram_validator"
|
|
15
|
+
require "xbox_live_validator"
|
|
16
|
+
require "yahoo_im_validator"
|