validates_im 1.1.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 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/README.md ADDED
@@ -0,0 +1,109 @@
1
+ validates_im
2
+ ============
3
+
4
+ [![CI](https://github.com/RISCfuture/validates_im/actions/workflows/ci.yml/badge.svg)](https://github.com/RISCfuture/validates_im/actions/workflows/ci.yml)
5
+ [![Gem Version](https://img.shields.io/gem/v/validates_im.svg)](https://rubygems.org/gems/validates_im)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](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
- # Generic @EachValidator@ that validates account names on various communication
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,49 +10,51 @@
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
- # <pre><code>
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
- # </code></pre>
19
+ # ````
16
20
  #
17
21
  # With your validator defined you can now use it in your Active Record models
18
- # like any other @EachValidator@:
22
+ # like any other `EachValidator`:
19
23
  #
20
- # <pre><code>
24
+ # ```` ruby
21
25
  # validates :talkalot_id,
22
26
  # talkalot: true
23
- # </code></pre>
27
+ # ````
24
28
  #
25
29
  # This class automatically handles the following options passed to the
26
- # @validates@ method:
30
+ # `validates` method:
27
31
  #
28
- # | @:allow_nil@ | Allows @nil@ values. |
29
- # | @:message@ | Provide a custom error message. |
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
- # @ActiveModel::Errors#generate_message@ method (see its documentation for more
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 @TalkalotValidator@ example above, the error message
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
- # @:talkalot_too_short@. If you wanted to override the prefix, you could do:
48
+ # `:talkalot_too_short`. If you wanted to override the prefix, you could do:
43
49
  #
44
- # <pre><code>
50
+ # ```` ruby
45
51
  # class TalkalotValidator < AccountNameValidator
46
52
  # error_key_prefix :talky
47
53
  # end
48
- # </code></pre>
54
+ # ````
49
55
  #
50
56
  # In this case the error message key for a two-letter account name would be
51
- # @:talky_too_short@. (You'd do this if Talkalot accounts were called "talkies,"
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
@@ -60,13 +66,12 @@ class AccountNameValidator < ActiveModel::EachValidator
60
66
 
61
67
  # @private
62
68
  def validate_each(record, attribute, value)
63
- return if options[:allow_nil] and value.nil?
64
- return if options[:allow_blank] and value.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
- protected
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
- if value then
81
- @error_key_prefix = value
82
- else
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 @String@.
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 block_given?
97
- self.validations += [[ block, key ]]
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 =~ /^[#{charlist}]+$/ }
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] =~ /^[#{charlist}]$/ }
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
- # bq. 3-16 letters or numbers. It must start with a letter.
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
- # | @aim_too_short@ | Screen name is less than 3 characters. |
8
- # | @aim_too_long@ | Screen name is over 16 characters. |
9
- # | @aim_invalid_chars@ | Screen name contains invalid characters. |
10
- # | @aim_invalid_first_char@ | Screen name doesn't start with a letter. |
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
- # h2. Options
19
+ # Options
20
+ # -------
16
21
  #
17
- # | @:message@ | A custom message to use if the email is invalid. |
18
- # | @:allow_nil@ | If true, @nil@ values are allowed. |
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 'A-Za-z0-9'
24
- first_char 'A-Za-z'
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
@@ -1,26 +1,33 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Validates Skype screen names. From the Skype website:
2
4
  #
3
- # bq. It must be between 6-32 characters, start with a letter and contain only
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
- # | @skype_too_short@ | Skype name is less than 6 characters. |
9
- # | @skype_too_long@ | Skype name is over 32 characters. |
10
- # | @skype_invalid_chars@ | Skype name contains invalid characters. |
11
- # | @skype_invalid_first_char@ | Skype name doesn't start with a letter. |
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
- # h2. Options
20
+ # Options
21
+ # -------
17
22
  #
18
- # | @:message@ | A custom message to use if the email is invalid. |
19
- # | @:allow_nil@ | If true, @nil@ values are allowed. |
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 'A-Za-z0-9'
25
- first_char 'A-Za-z'
31
+ valid_chars "A-Za-z0-9"
32
+ first_char "A-Za-z"
26
33
  end
@@ -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
- # | @steam_too_short@ | Steam ID is less than 6 characters. |
7
- # | @steam_too_long@ | Steam ID is over 32 characters. |
8
- # | @steam_invalid_chars@ | Steam ID contains invalid characters. |
9
- # | @steam_invalid_first_char@ | Steam ID doesn't start with a letter. |
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 'A-Za-z0-9_'
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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ValidatesIm
4
+ VERSION = "2.0.0"
5
+ end
data/lib/validates_im.rb CHANGED
@@ -1,7 +1,16 @@
1
- require 'account_name_validator'
2
- require 'aim_validator'
3
- require 'skype_validator'
4
- require 'steam_validator'
5
- require 'validates_im'
6
- require 'xbox_live_validator'
7
- require 'yahoo_im_validator'
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"
@@ -1,23 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Validates Xbox Live gamertags. From the Xbox Live website:
2
4
  #
3
- # bq. Gamertags can only contain letters, numbers, and spaces, and can't begin
4
- # with a number.
5
+ # > Gamertags can only contain letters, numbers, and spaces, and can't begin
6
+ # > with a number.
5
7
  #
6
- # In addition we discovered that they have no minimum length but are no more
7
- # than 15 characters, and also cannot start with a space.
8
+ # Xbox gamertags are 3-12 characters and cannot start with a space.
8
9
  #
9
10
  # The following error message keys are used to localize invalid screen names.
10
11
  #
11
- # | @xbox_too_long@ | Gamertag is over 15 characters. |
12
- # | @xbox_invalid_chars@ | Gamertag contains invalid characters. |
13
- # | @xbox_invalid_first_char@ | Gamertag doesn't start with a letter. |
12
+ # | | |
13
+ # |:--------------------------|:--------------------------------------|
14
+ # | `xbox_too_short` | Gamertag is under 3 characters. |
15
+ # | `xbox_too_long` | Gamertag is over 12 characters. |
16
+ # | `xbox_invalid_chars` | Gamertag contains invalid characters. |
17
+ # | `xbox_invalid_first_char` | Gamertag doesn't start with a letter. |
14
18
  #
15
19
  # @example
16
20
  # validates :steam_account, steam: true
21
+ #
22
+ # Options
23
+ # -------
24
+ #
25
+ # | | |
26
+ # |:-------------|:-------------------------------------------------|
27
+ # | `:message` | A custom message to use if the email is invalid. |
28
+ # | `:allow_nil` | If true, `nil` values are allowed. |
17
29
 
18
30
  class XboxLiveValidator < AccountNameValidator
19
- error_key_prefix 'xbox'
20
- max_length 15
21
- valid_chars 'A-Za-z0-9 '
22
- first_char 'A-Za-z'
31
+ error_key_prefix "xbox"
32
+ min_length 3
33
+ max_length 12
34
+ valid_chars "A-Za-z0-9 "
35
+ first_char "A-Za-z"
23
36
  end
@@ -1,30 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Validates Yahoo! Instant Messenger screen names. According to the Yahoo!
2
4
  # website:
3
5
  #
4
- # bq. Use 4 to 32 characters and start with a letter. You may use letters,
5
- # numbers, underscores, and one dot (.).
6
+ # > Use 4 to 32 characters and start with a letter. You may use letters,
7
+ # > numbers, underscores, and one dot (.).
6
8
  #
7
9
  # The following error message keys are used to localize invalid screen names:
8
10
  #
9
- # | @yim_too_short@ | Screen name is less than 3 characters. |
10
- # | @yim_too_long@ | Screen name is over 16 characters. |
11
- # | @yim_invalid_chars@ | Screen name contains invalid characters. |
12
- # | @yim_invalid_first_char@ | Screen name doesn't start with a letter. |
13
- # | @yim_multiple_periods@ | Screen name has more than one period in it. |
11
+ # | | |
12
+ # |:-------------------------|:--------------------------------------------|
13
+ # | `yim_too_short` | Screen name is fewer than 3 characters. |
14
+ # | `yim_too_long` | Screen name is over 16 characters. |
15
+ # | `yim_invalid_chars` | Screen name contains invalid characters. |
16
+ # | `yim_invalid_first_char` | Screen name doesn't start with a letter. |
17
+ # | `yim_multiple_periods` | Screen name has more than one period in it. |
14
18
  #
15
19
  # @example
16
20
  # validates :yim_sn, yahoo_im: true
17
21
  #
18
- # h2. Options
22
+ # Options
23
+ # -------
19
24
  #
20
- # | @:message@ | A custom message to use if the email is invalid. |
21
- # | @:allow_nil@ | If true, @nil@ values are allowed. |
25
+ # | | |
26
+ # |:-------------|:-------------------------------------------------|
27
+ # | `:message` | A custom message to use if the email is invalid. |
28
+ # | `:allow_nil` | If true, `nil` values are allowed. |
22
29
 
23
30
  class YahooImValidator < AccountNameValidator
24
- error_key_prefix 'yim'
31
+ error_key_prefix "yim"
25
32
  min_length 4
26
33
  max_length 32
27
34
  valid_chars 'A-Za-z0-9_\\.'
28
- first_char 'A-Za-z'
29
- add_validation(:multiple_periods) { |value| value.count('.') < 2 }
35
+ first_char "A-Za-z"
36
+ add_validation(:multiple_periods) { |value| value.count(".") < 2 }
30
37
  end
data/validates_im.gemspec CHANGED
@@ -1,63 +1,45 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
-
6
- Gem::Specification.new do |s|
7
- s.name = %q{validates_im}
8
- s.version = "1.1.0"
9
-
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = [%q{Tim Morgan}]
12
- s.date = %q{2011-08-31}
13
- s.description = %q{Adds ActiveModel validators for common instant messaging services like Skype and AIM.}
14
- s.email = %q{git@timothymorgan.info}
15
- s.extra_rdoc_files = [
16
- "LICENSE",
17
- "README.textile"
18
- ]
19
- s.files = [
20
- "LICENSE",
21
- "README.textile",
22
- "lib/account_name_validator.rb",
23
- "lib/aim_validator.rb",
24
- "lib/skype_validator.rb",
25
- "lib/steam_validator.rb",
26
- "lib/validates_im.rb",
27
- "lib/xbox_live_validator.rb",
28
- "lib/yahoo_im_validator.rb",
29
- "validates_im.gemspec"
30
- ]
31
- s.homepage = %q{http://github.com/riscfuture/validates_im}
32
- s.require_paths = [%q{lib}]
33
- s.rubygems_version = %q{1.8.9}
34
- s.summary = %q{A set of Rails validators for common instant messaging services}
35
-
36
- if s.respond_to? :specification_version then
37
- s.specification_version = 3
38
-
39
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
40
- s.add_runtime_dependency(%q<activerecord>, [">= 3.1"])
41
- s.add_development_dependency(%q<jeweler>, [">= 0"])
42
- s.add_development_dependency(%q<yard>, [">= 0"])
43
- s.add_development_dependency(%q<RedCloth>, [">= 0"])
44
- s.add_development_dependency(%q<rspec>, [">= 0"])
45
- s.add_runtime_dependency(%q<activerecord>, [">= 3.0"])
46
- else
47
- s.add_dependency(%q<activerecord>, [">= 3.1"])
48
- s.add_dependency(%q<jeweler>, [">= 0"])
49
- s.add_dependency(%q<yard>, [">= 0"])
50
- s.add_dependency(%q<RedCloth>, [">= 0"])
51
- s.add_dependency(%q<rspec>, [">= 0"])
52
- s.add_dependency(%q<activerecord>, [">= 3.0"])
53
- end
54
- else
55
- s.add_dependency(%q<activerecord>, [">= 3.1"])
56
- s.add_dependency(%q<jeweler>, [">= 0"])
57
- s.add_dependency(%q<yard>, [">= 0"])
58
- s.add_dependency(%q<RedCloth>, [">= 0"])
59
- s.add_dependency(%q<rspec>, [">= 0"])
60
- s.add_dependency(%q<activerecord>, [">= 3.0"])
61
- end
62
- end
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/validates_im/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "validates_im"
7
+ spec.version = ValidatesIm::VERSION
8
+ spec.authors = ["Tim Morgan"]
9
+ spec.email = "git@timothymorgan.info"
10
+
11
+ spec.summary = "A set of Rails validators for common instant messaging services"
12
+ spec.description = "Adds ActiveModel validators for common instant messaging services like Discord, Telegram, Matrix, and Signal (as well as legacy services like AIM, Yahoo!, and Skype)."
13
+ spec.homepage = "https://github.com/riscfuture/validates_im"
14
+ spec.license = "MIT"
15
+
16
+ spec.required_ruby_version = ">= 3.1"
63
17
 
18
+ spec.metadata = {
19
+ "homepage_uri" => spec.homepage,
20
+ "source_code_uri" => "#{spec.homepage}/tree/master",
21
+ "changelog_uri" => "#{spec.homepage}/blob/master/CHANGELOG.md",
22
+ "bug_tracker_uri" => "#{spec.homepage}/issues",
23
+ "rubygems_mfa_required" => "true"
24
+ }
25
+
26
+ spec.files = Dir.chdir(__dir__) do
27
+ candidates =
28
+ if system("git rev-parse --is-inside-work-tree > /dev/null 2>&1")
29
+ `git ls-files -z`.split("\x0").reject do |f|
30
+ f.start_with?(".github/", "spec/", ".idea/", ".claude/", "bin/") ||
31
+ f.match?(/\A(?:Gemfile|Gemfile\.lock|Rakefile|\.rspec|\.rubocop\.yml|\.travis\.yml|\.ruby-(?:gemset|version)|\.gitignore|\.document)/)
32
+ end
33
+ else
34
+ Dir["lib/**/*.rb"] + %w[LICENSE README.md CHANGELOG.md validates_im.gemspec]
35
+ end
36
+ candidates.select { |f| File.exist?(f) } +
37
+ Dir["lib/**/*.rb"].reject { |f| candidates.include?(f) } +
38
+ %w[CHANGELOG.md].reject { |f| candidates.include?(f) || !File.exist?(f) }
39
+ end.uniq
40
+
41
+ spec.require_paths = ["lib"]
42
+
43
+ spec.add_dependency "activemodel", ">= 6.1"
44
+ spec.add_dependency "activesupport", ">= 6.1"
45
+ end
metadata CHANGED
@@ -1,126 +1,90 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validates_im
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
5
- prerelease:
4
+ version: 2.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Tim Morgan
9
- autorequire:
10
8
  bindir: bin
11
9
  cert_chain: []
12
- date: 2011-08-31 00:00:00.000000000Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
13
11
  dependencies:
14
12
  - !ruby/object:Gem::Dependency
15
- name: activerecord
16
- requirement: &2167709520 !ruby/object:Gem::Requirement
17
- none: false
13
+ name: activemodel
14
+ requirement: !ruby/object:Gem::Requirement
18
15
  requirements:
19
- - - ! '>='
16
+ - - ">="
20
17
  - !ruby/object:Gem::Version
21
- version: '3.1'
18
+ version: '6.1'
22
19
  type: :runtime
23
20
  prerelease: false
24
- version_requirements: *2167709520
25
- - !ruby/object:Gem::Dependency
26
- name: jeweler
27
- requirement: &2167708860 !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
33
- type: :development
34
- prerelease: false
35
- version_requirements: *2167708860
36
- - !ruby/object:Gem::Dependency
37
- name: yard
38
- requirement: &2167708280 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: '0'
44
- type: :development
45
- prerelease: false
46
- version_requirements: *2167708280
47
- - !ruby/object:Gem::Dependency
48
- name: RedCloth
49
- requirement: &2167707660 !ruby/object:Gem::Requirement
50
- none: false
21
+ version_requirements: !ruby/object:Gem::Requirement
51
22
  requirements:
52
- - - ! '>='
23
+ - - ">="
53
24
  - !ruby/object:Gem::Version
54
- version: '0'
55
- type: :development
56
- prerelease: false
57
- version_requirements: *2167707660
25
+ version: '6.1'
58
26
  - !ruby/object:Gem::Dependency
59
- name: rspec
60
- requirement: &2167707060 !ruby/object:Gem::Requirement
61
- none: false
27
+ name: activesupport
28
+ requirement: !ruby/object:Gem::Requirement
62
29
  requirements:
63
- - - ! '>='
30
+ - - ">="
64
31
  - !ruby/object:Gem::Version
65
- version: '0'
66
- type: :development
32
+ version: '6.1'
33
+ type: :runtime
67
34
  prerelease: false
68
- version_requirements: *2167707060
69
- - !ruby/object:Gem::Dependency
70
- name: activerecord
71
- requirement: &2167706460 !ruby/object:Gem::Requirement
72
- none: false
35
+ version_requirements: !ruby/object:Gem::Requirement
73
36
  requirements:
74
- - - ! '>='
37
+ - - ">="
75
38
  - !ruby/object:Gem::Version
76
- version: '3.0'
77
- type: :runtime
78
- prerelease: false
79
- version_requirements: *2167706460
39
+ version: '6.1'
80
40
  description: Adds ActiveModel validators for common instant messaging services like
81
- Skype and AIM.
41
+ Discord, Telegram, Matrix, and Signal (as well as legacy services like AIM, Yahoo!,
42
+ and Skype).
82
43
  email: git@timothymorgan.info
83
44
  executables: []
84
45
  extensions: []
85
- extra_rdoc_files:
86
- - LICENSE
87
- - README.textile
46
+ extra_rdoc_files: []
88
47
  files:
48
+ - CHANGELOG.md
89
49
  - LICENSE
90
- - README.textile
50
+ - README.md
91
51
  - lib/account_name_validator.rb
92
52
  - lib/aim_validator.rb
53
+ - lib/discord_validator.rb
54
+ - lib/matrix_validator.rb
55
+ - lib/signal_validator.rb
93
56
  - lib/skype_validator.rb
94
57
  - lib/steam_validator.rb
58
+ - lib/telegram_validator.rb
95
59
  - lib/validates_im.rb
60
+ - lib/validates_im/version.rb
96
61
  - lib/xbox_live_validator.rb
97
62
  - lib/yahoo_im_validator.rb
98
63
  - validates_im.gemspec
99
- homepage: http://github.com/riscfuture/validates_im
100
- licenses: []
101
- post_install_message:
64
+ homepage: https://github.com/riscfuture/validates_im
65
+ licenses:
66
+ - MIT
67
+ metadata:
68
+ homepage_uri: https://github.com/riscfuture/validates_im
69
+ source_code_uri: https://github.com/riscfuture/validates_im/tree/master
70
+ changelog_uri: https://github.com/riscfuture/validates_im/blob/master/CHANGELOG.md
71
+ bug_tracker_uri: https://github.com/riscfuture/validates_im/issues
72
+ rubygems_mfa_required: 'true'
102
73
  rdoc_options: []
103
74
  require_paths:
104
75
  - lib
105
76
  required_ruby_version: !ruby/object:Gem::Requirement
106
- none: false
107
77
  requirements:
108
- - - ! '>='
78
+ - - ">="
109
79
  - !ruby/object:Gem::Version
110
- version: '0'
111
- segments:
112
- - 0
113
- hash: 221433530893937633
80
+ version: '3.1'
114
81
  required_rubygems_version: !ruby/object:Gem::Requirement
115
- none: false
116
82
  requirements:
117
- - - ! '>='
83
+ - - ">="
118
84
  - !ruby/object:Gem::Version
119
85
  version: '0'
120
86
  requirements: []
121
- rubyforge_project:
122
- rubygems_version: 1.8.9
123
- signing_key:
124
- specification_version: 3
87
+ rubygems_version: 4.0.11
88
+ specification_version: 4
125
89
  summary: A set of Rails validators for common instant messaging services
126
90
  test_files: []
data/README.textile DELETED
@@ -1,40 +0,0 @@
1
- h1. validates_im -- Instant messenger account validations for ActiveRecord
2
-
3
- | *Author* | Tim Morgan |
4
- | *Version* | 1.1 (Aug 31, 2011) |
5
- | *License* | Released under the MIT license. |
6
-
7
- h2. About
8
-
9
- @validates_im@ is a simple gem that gives you some @EachValidators@ that you can
10
- use to validate instant messenger account names in your Rails 3.0 application.
11
- Validators are provided for the most common IM services, like AIM, Yahoo! IM,
12
- and Skype.
13
-
14
- h2. Installation
15
-
16
- *Important Note:* This gem is for Rails 3 only.
17
-
18
- To install, simply add this gem to your Rails project's @Gemfile@:
19
-
20
- <pre><code>
21
- gem 'validates_im'
22
- </code></pre>
23
-
24
- h2. Usage
25
-
26
- The IM validators are @EachValidators@, meant to be used with the @validates@
27
- method. An example:
28
-
29
- <pre><code>
30
- validates :screen_name,
31
- aim: true,
32
- presence: true
33
- </code></pre>
34
-
35
- The name of the symbol key is taken from the name of the validator; as such, The
36
- @XboxLiveValidator@ would be invoked using @:xbox_live@. See the
37
- {AccountNameValidator} class docs for more information.
38
-
39
- The localization keys for validation errors are listed in the documentation for
40
- each validator class.