net-imap 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/test.yml +2 -2
- data/LICENSE.txt +62 -0
- data/Rakefile +7 -0
- data/lib/net/imap/authenticators/cram_md5.rb +6 -4
- data/lib/net/imap/authenticators/digest_md5.rb +11 -7
- data/lib/net/imap/authenticators/login.rb +4 -1
- data/lib/net/imap/authenticators.rb +10 -7
- data/lib/net/imap/command_data.rb +2 -0
- data/lib/net/imap/data_encoding.rb +59 -0
- data/lib/net/imap/errors.rb +59 -0
- data/lib/net/imap/flags.rb +192 -34
- data/lib/net/imap/response_parser.rb +3 -7
- data/lib/net/imap.rb +33 -136
- data/net-imap.gemspec +6 -6
- metadata +10 -8
- data/bin/console +0 -14
- data/bin/setup +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a91d908ae16db12c507a6cf5c0e5eef57e18c97473b2a13a0ab14cf655e9bcb7
|
4
|
+
data.tar.gz: 1bdab36cf0779d14e2f414e00aee90d95d2584bfc8d591c11d5104b4071bebb8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65133026b0746efbdc55a64bd1091da0524e5b922672767f334cec1d0357b31b973380bc8e787ff2430b831375f52050004d718b6308fa9203c9f6710ac2444b
|
7
|
+
data.tar.gz: 7e5e9fcac352549585e38b5a86b0198cc1c5996ad129cf9e53ca92f2ef63ea4b37d26ab8c5efd641b19711b2ea04e42622ead203c3afcaa8d420ceaaaa9893c8
|
data/.github/workflows/test.yml
CHANGED
@@ -7,7 +7,7 @@ jobs:
|
|
7
7
|
name: build (${{ matrix.ruby }} / ${{ matrix.os }})
|
8
8
|
strategy:
|
9
9
|
matrix:
|
10
|
-
ruby: [ '3.
|
10
|
+
ruby: [ head, '3.1', '3.0', '2.7' ]
|
11
11
|
os: [ ubuntu-latest, macos-latest ]
|
12
12
|
experimental: [false]
|
13
13
|
include:
|
@@ -20,7 +20,7 @@ jobs:
|
|
20
20
|
runs-on: ${{ matrix.os }}
|
21
21
|
continue-on-error: ${{ matrix.experimental }}
|
22
22
|
steps:
|
23
|
-
- uses: actions/checkout@
|
23
|
+
- uses: actions/checkout@v3
|
24
24
|
- name: Set up Ruby
|
25
25
|
uses: ruby/setup-ruby@v1
|
26
26
|
with:
|
data/LICENSE.txt
CHANGED
@@ -20,3 +20,65 @@ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
20
20
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
21
21
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
22
22
|
SUCH DAMAGE.
|
23
|
+
|
24
|
+
-------------------------------------------------------------------------
|
25
|
+
|
26
|
+
This software includes documentation which has been copied from the relevant
|
27
|
+
RFCs. The copied documentation is covered by the following licenses:
|
28
|
+
|
29
|
+
RFC 3501 (Editor: M. Crispin)
|
30
|
+
Full Copyright Statement
|
31
|
+
|
32
|
+
Copyright (C) The Internet Society (2003). All Rights Reserved.
|
33
|
+
|
34
|
+
This document and translations of it may be copied and furnished to
|
35
|
+
others, and derivative works that comment on or otherwise explain it
|
36
|
+
or assist in its implementation may be prepared, copied, published
|
37
|
+
and distributed, in whole or in part, without restriction of any
|
38
|
+
kind, provided that the above copyright notice and this paragraph are
|
39
|
+
included on all such copies and derivative works. However, this
|
40
|
+
document itself may not be modified in any way, such as by removing
|
41
|
+
the copyright notice or references to the Internet Society or other
|
42
|
+
Internet organizations, except as needed for the purpose of
|
43
|
+
developing Internet standards in which case the procedures for
|
44
|
+
copyrights defined in the Internet Standards process must be
|
45
|
+
followed, or as required to translate it into languages other than
|
46
|
+
English.
|
47
|
+
|
48
|
+
The limited permissions granted above are perpetual and will not be
|
49
|
+
revoked by the Internet Society or its successors or assigns. v This
|
50
|
+
document and the information contained herein is provided on an "AS
|
51
|
+
IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
|
52
|
+
FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
53
|
+
LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL
|
54
|
+
NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY
|
55
|
+
OR FITNESS FOR A PARTICULAR PURPOSE.
|
56
|
+
|
57
|
+
|
58
|
+
RFC9051 (Editors: A. Melnikov, B. Leiba)
|
59
|
+
Copyright Notice
|
60
|
+
|
61
|
+
Copyright (c) 2021 IETF Trust and the persons identified as the
|
62
|
+
document authors. All rights reserved.
|
63
|
+
|
64
|
+
This document is subject to BCP 78 and the IETF Trust's Legal
|
65
|
+
Provisions Relating to IETF Documents
|
66
|
+
(https://trustee.ietf.org/license-info) in effect on the date of
|
67
|
+
publication of this document. Please review these documents
|
68
|
+
carefully, as they describe your rights and restrictions with respect
|
69
|
+
to this document. Code Components extracted from this document must
|
70
|
+
include Simplified BSD License text as described in Section 4.e of
|
71
|
+
the Trust Legal Provisions and are provided without warranty as
|
72
|
+
described in the Simplified BSD License.
|
73
|
+
|
74
|
+
This document may contain material from IETF Documents or IETF
|
75
|
+
Contributions published or made publicly available before November
|
76
|
+
10, 2008. The person(s) controlling the copyright in some of this
|
77
|
+
material may not have granted the IETF Trust the right to allow
|
78
|
+
modifications of such material outside the IETF Standards Process.
|
79
|
+
Without obtaining an adequate license from the person(s) controlling
|
80
|
+
the copyright in such materials, this document may not be modified
|
81
|
+
outside the IETF Standards Process, and derivative works of it may
|
82
|
+
not be created outside the IETF Standards Process, except to format
|
83
|
+
it for publication as an RFC or to translate it into languages other
|
84
|
+
than English.
|
data/Rakefile
CHANGED
@@ -7,4 +7,11 @@ Rake::TestTask.new(:test) do |t|
|
|
7
7
|
t.test_files = FileList["test/**/test_*.rb"]
|
8
8
|
end
|
9
9
|
|
10
|
+
task :sync_tool do
|
11
|
+
require 'fileutils'
|
12
|
+
FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib"
|
13
|
+
FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib"
|
14
|
+
FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib"
|
15
|
+
end
|
16
|
+
|
10
17
|
task :default => :test
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "digest/md5"
|
4
|
-
|
5
3
|
# Authenticator for the "+CRAM-MD5+" SASL mechanism, specified in
|
6
4
|
# RFC2195[https://tools.ietf.org/html/rfc2195]. See Net::IMAP#authenticate.
|
7
5
|
#
|
@@ -23,7 +21,11 @@ class Net::IMAP::CramMD5Authenticator
|
|
23
21
|
|
24
22
|
private
|
25
23
|
|
26
|
-
def initialize(user, password)
|
24
|
+
def initialize(user, password, warn_deprecation: true, **_ignored)
|
25
|
+
if warn_deprecation
|
26
|
+
warn "WARNING: CRAM-MD5 mechanism is deprecated." # TODO: recommend SCRAM
|
27
|
+
end
|
28
|
+
require "digest/md5"
|
27
29
|
@user = user
|
28
30
|
@password = password
|
29
31
|
end
|
@@ -45,5 +47,5 @@ class Net::IMAP::CramMD5Authenticator
|
|
45
47
|
return Digest::MD5.hexdigest(k_opad + digest)
|
46
48
|
end
|
47
49
|
|
48
|
-
Net::IMAP.add_authenticator "
|
50
|
+
Net::IMAP.add_authenticator "CRAM-MD5", self
|
49
51
|
end
|
@@ -1,8 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "digest/md5"
|
4
|
-
require "strscan"
|
5
|
-
|
6
3
|
# Net::IMAP authenticator for the "`DIGEST-MD5`" SASL mechanism type, specified
|
7
4
|
# in RFC2831(https://tools.ietf.org/html/rfc2831). See Net::IMAP#authenticate.
|
8
5
|
#
|
@@ -29,8 +26,8 @@ class Net::IMAP::DigestMD5Authenticator
|
|
29
26
|
sparams[k] = v
|
30
27
|
end
|
31
28
|
|
32
|
-
raise DataFormatError, "Bad Challenge: '#{challenge}'" unless c.
|
33
|
-
raise Error, "Server does not support auth (qop = #{sparams['qop'].join(',')})" unless sparams['qop'].include?("auth")
|
29
|
+
raise Net::IMAP::DataFormatError, "Bad Challenge: '#{challenge}'" unless c.eos?
|
30
|
+
raise Net::IMAP::Error, "Server does not support auth (qop = #{sparams['qop'].join(',')})" unless sparams['qop'].include?("auth")
|
34
31
|
|
35
32
|
response = {
|
36
33
|
:nonce => sparams['nonce'],
|
@@ -77,11 +74,18 @@ class Net::IMAP::DigestMD5Authenticator
|
|
77
74
|
end
|
78
75
|
end
|
79
76
|
|
80
|
-
def initialize(user, password, authname = nil)
|
77
|
+
def initialize(user, password, authname = nil, warn_deprecation: true)
|
78
|
+
if warn_deprecation
|
79
|
+
warn "WARNING: DIGEST-MD5 SASL mechanism was deprecated by RFC6331."
|
80
|
+
# TODO: recommend SCRAM instead.
|
81
|
+
end
|
82
|
+
require "digest/md5"
|
83
|
+
require "strscan"
|
81
84
|
@user, @password, @authname = user, password, authname
|
82
85
|
@nc, @stage = {}, STAGE_ONE
|
83
86
|
end
|
84
87
|
|
88
|
+
|
85
89
|
private
|
86
90
|
|
87
91
|
STAGE_ONE = :stage_one
|
@@ -100,7 +104,7 @@ class Net::IMAP::DigestMD5Authenticator
|
|
100
104
|
def qdval(k, v)
|
101
105
|
return if k.nil? or v.nil?
|
102
106
|
if %w"username authzid realm nonce cnonce digest-uri qop".include? k
|
103
|
-
v.gsub
|
107
|
+
v = v.gsub(/([\\"])/, "\\\1")
|
104
108
|
return '%s="%s"' % [k, v]
|
105
109
|
else
|
106
110
|
return '%s=%s' % [k, v]
|
@@ -33,7 +33,10 @@ class Net::IMAP::LoginAuthenticator
|
|
33
33
|
STATE_USER = :USER
|
34
34
|
STATE_PASSWORD = :PASSWORD
|
35
35
|
|
36
|
-
def initialize(user, password)
|
36
|
+
def initialize(user, password, warn_deprecation: true, **_ignored)
|
37
|
+
if warn_deprecation
|
38
|
+
warn "WARNING: LOGIN SASL mechanism is deprecated. Use PLAIN instead."
|
39
|
+
end
|
37
40
|
@user = user
|
38
41
|
@password = password
|
39
42
|
@state = STATE_USER
|
@@ -19,13 +19,15 @@ module Net::IMAP::Authenticators
|
|
19
19
|
|
20
20
|
# Builds an authenticator for Net::IMAP#authenticate. +args+ will be passed
|
21
21
|
# directly to the chosen authenticator's +#initialize+.
|
22
|
-
def authenticator(
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
def authenticator(mechanism, *authargs, **properties, &callback)
|
23
|
+
authenticator = authenticators.fetch(mechanism.upcase) do
|
24
|
+
raise ArgumentError, 'unknown auth type - "%s"' % mechanism
|
25
|
+
end
|
26
|
+
if authenticator.respond_to?(:new)
|
27
|
+
authenticator.new(*authargs, **properties, &callback)
|
28
|
+
else
|
29
|
+
authenticator.call(*authargs, **properties, &callback)
|
27
30
|
end
|
28
|
-
authenticators[auth_type].new(*args)
|
29
31
|
end
|
30
32
|
|
31
33
|
private
|
@@ -38,7 +40,8 @@ end
|
|
38
40
|
|
39
41
|
Net::IMAP.extend Net::IMAP::Authenticators
|
40
42
|
|
41
|
-
require_relative "authenticators/login"
|
42
43
|
require_relative "authenticators/plain"
|
44
|
+
|
45
|
+
require_relative "authenticators/login"
|
43
46
|
require_relative "authenticators/cram_md5"
|
44
47
|
require_relative "authenticators/digest_md5"
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "errors"
|
4
|
+
|
3
5
|
module Net
|
4
6
|
class IMAP < Protocol
|
5
7
|
|
@@ -43,5 +45,62 @@ module Net
|
|
43
45
|
return time.strftime('%d-%b-%Y %H:%M %z')
|
44
46
|
end
|
45
47
|
|
48
|
+
# Common validators of number and nz_number types
|
49
|
+
module NumValidator # :nodoc
|
50
|
+
module_function
|
51
|
+
|
52
|
+
# Check is passed argument valid 'number' in RFC 3501 terminology
|
53
|
+
def valid_number?(num)
|
54
|
+
# [RFC 3501]
|
55
|
+
# number = 1*DIGIT
|
56
|
+
# ; Unsigned 32-bit integer
|
57
|
+
# ; (0 <= n < 4,294,967,296)
|
58
|
+
num >= 0 && num < 4294967296
|
59
|
+
end
|
60
|
+
|
61
|
+
# Check is passed argument valid 'nz_number' in RFC 3501 terminology
|
62
|
+
def valid_nz_number?(num)
|
63
|
+
# [RFC 3501]
|
64
|
+
# nz-number = digit-nz *DIGIT
|
65
|
+
# ; Non-zero unsigned 32-bit integer
|
66
|
+
# ; (0 < n < 4,294,967,296)
|
67
|
+
num != 0 && valid_number?(num)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Check is passed argument valid 'mod_sequence_value' in RFC 4551 terminology
|
71
|
+
def valid_mod_sequence_value?(num)
|
72
|
+
# mod-sequence-value = 1*DIGIT
|
73
|
+
# ; Positive unsigned 64-bit integer
|
74
|
+
# ; (mod-sequence)
|
75
|
+
# ; (1 <= n < 18,446,744,073,709,551,615)
|
76
|
+
num >= 1 && num < 18446744073709551615
|
77
|
+
end
|
78
|
+
|
79
|
+
# Ensure argument is 'number' or raise DataFormatError
|
80
|
+
def ensure_number(num)
|
81
|
+
return if valid_number?(num)
|
82
|
+
|
83
|
+
msg = "number must be unsigned 32-bit integer: #{num}"
|
84
|
+
raise DataFormatError, msg
|
85
|
+
end
|
86
|
+
|
87
|
+
# Ensure argument is 'nz_number' or raise DataFormatError
|
88
|
+
def ensure_nz_number(num)
|
89
|
+
return if valid_nz_number?(num)
|
90
|
+
|
91
|
+
msg = "nz_number must be non-zero unsigned 32-bit integer: #{num}"
|
92
|
+
raise DataFormatError, msg
|
93
|
+
end
|
94
|
+
|
95
|
+
# Ensure argument is 'mod_sequence_value' or raise DataFormatError
|
96
|
+
def ensure_mod_sequence_value(num)
|
97
|
+
return if valid_mod_sequence_value?(num)
|
98
|
+
|
99
|
+
msg = "mod_sequence_value must be unsigned 64-bit integer: #{num}"
|
100
|
+
raise DataFormatError, msg
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
46
105
|
end
|
47
106
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class IMAP < Protocol
|
5
|
+
|
6
|
+
# Superclass of IMAP errors.
|
7
|
+
class Error < StandardError
|
8
|
+
end
|
9
|
+
|
10
|
+
# Error raised when data is in the incorrect format.
|
11
|
+
class DataFormatError < Error
|
12
|
+
end
|
13
|
+
|
14
|
+
# Error raised when a response from the server is non-parseable.
|
15
|
+
class ResponseParseError < Error
|
16
|
+
end
|
17
|
+
|
18
|
+
# Superclass of all errors used to encapsulate "fail" responses
|
19
|
+
# from the server.
|
20
|
+
class ResponseError < Error
|
21
|
+
|
22
|
+
# The response that caused this error
|
23
|
+
attr_accessor :response
|
24
|
+
|
25
|
+
def initialize(response)
|
26
|
+
@response = response
|
27
|
+
|
28
|
+
super @response.data.text
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
# Error raised upon a "NO" response from the server, indicating
|
34
|
+
# that the client command could not be completed successfully.
|
35
|
+
class NoResponseError < ResponseError
|
36
|
+
end
|
37
|
+
|
38
|
+
# Error raised upon a "BAD" response from the server, indicating
|
39
|
+
# that the client command violated the IMAP protocol, or an internal
|
40
|
+
# server failure has occurred.
|
41
|
+
class BadResponseError < ResponseError
|
42
|
+
end
|
43
|
+
|
44
|
+
# Error raised upon a "BYE" response from the server, indicating
|
45
|
+
# that the client is not being allowed to login, or has been timed
|
46
|
+
# out due to inactivity.
|
47
|
+
class ByeResponseError < ResponseError
|
48
|
+
end
|
49
|
+
|
50
|
+
# Error raised upon an unknown response from the server.
|
51
|
+
class UnknownResponseError < ResponseError
|
52
|
+
end
|
53
|
+
|
54
|
+
RESPONSE_ERRORS = Hash.new(ResponseError)
|
55
|
+
RESPONSE_ERRORS["NO"] = NoResponseError
|
56
|
+
RESPONSE_ERRORS["BAD"] = BadResponseError
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
data/lib/net/imap/flags.rb
CHANGED
@@ -3,74 +3,232 @@
|
|
3
3
|
module Net
|
4
4
|
class IMAP < Protocol
|
5
5
|
|
6
|
-
#
|
6
|
+
# -------------------------------------------------------------------------
|
7
|
+
# :section: Message Flags: system flags
|
7
8
|
#
|
8
|
-
#
|
9
|
+
# A message has a list of zero or more named tokens, known as "flags",
|
10
|
+
# associated with it. A flag is set by its addition to this list and is
|
11
|
+
# cleared by its removal. There are two types of flags in IMAP4rev2: system
|
12
|
+
# flags and keywords. A flag of either type can be permanent or
|
13
|
+
# session-only.
|
14
|
+
#
|
15
|
+
# A "system flag" is a message flag name that is predefined in the IMAP
|
16
|
+
# specification and begins with "\". +Net::IMAP+ returns all system flags
|
17
|
+
# as symbols, without the "\" prefix.
|
18
|
+
#
|
19
|
+
# The descriptions here were copied from the IMAP4rev2 specification:
|
20
|
+
# [RFC-9051 § 2.3.2](https://www.rfc-editor.org/rfc/rfc9051.html#section-2.3.2)
|
21
|
+
#
|
22
|
+
# See [RFC-3501 § 2.3.2](https://www.rfc-editor.org/rfc/rfc3501.html#section-2.3.2)
|
23
|
+
# for a description of the flags message attribute and system flag semantics
|
24
|
+
# in IMAP4rev1.
|
25
|
+
# -------------------------------------------------------------------------
|
26
|
+
|
27
|
+
# Flag indicating a message has been read.
|
9
28
|
SEEN = :Seen
|
10
29
|
|
11
|
-
# :category: Message Flags
|
12
|
-
#
|
13
30
|
# Flag indicating a message has been answered.
|
14
31
|
ANSWERED = :Answered
|
15
32
|
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# Flag indicating a message has been flagged for special or urgent
|
33
|
+
# A message flag indicating a message has been flagged for special or urgent
|
19
34
|
# attention.
|
35
|
+
#
|
36
|
+
# Also a mailbox special use attribute, which indicates that this mailbox
|
37
|
+
# presents all messages marked in some way as "important". When this
|
38
|
+
# special use is supported, it is likely to represent a virtual mailbox
|
39
|
+
# collecting messages (from other mailboxes) that are marked with the
|
40
|
+
# "\Flagged" message flag.
|
20
41
|
FLAGGED = :Flagged
|
21
42
|
|
22
|
-
# :category: Message Flags
|
23
|
-
#
|
24
43
|
# Flag indicating a message has been marked for deletion. This
|
25
44
|
# will occur when the mailbox is closed or expunged.
|
26
45
|
DELETED = :Deleted
|
27
46
|
|
28
|
-
# :category: Message Flags
|
29
|
-
#
|
30
47
|
# Flag indicating a message is only a draft or work-in-progress version.
|
31
48
|
DRAFT = :Draft
|
32
49
|
|
33
|
-
# :category: Message Flags
|
34
|
-
#
|
35
50
|
# Flag indicating that the message is "recent," meaning that this
|
36
51
|
# session is the first session in which the client has been notified
|
37
52
|
# of this message.
|
53
|
+
#
|
54
|
+
# This flag was defined by
|
55
|
+
# IMAP4rev1 [RFC-3501](https://www.rfc-editor.org/rfc/rfc3501.html),
|
56
|
+
# and has been deprecated by
|
57
|
+
# IMAP4rev2 [RFC-9051](https://www.rfc-editor.org/rfc/rfc9051.html).
|
38
58
|
RECENT = :Recent
|
39
59
|
|
40
|
-
#
|
60
|
+
# -------------------------------------------------------------------------
|
61
|
+
# :section: Mailbox Name Attributes, Base attributes
|
62
|
+
# Mailbox name attributes will be returned in LIST responses. Base
|
63
|
+
# attributes must be returned according to the server's capabilities.
|
41
64
|
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
|
65
|
+
# IMAP4 specifies that all mailbox name attributes, including future
|
66
|
+
# extensions, begin with "\". +Net::IMAP+ returns all mailbox attributes as
|
67
|
+
# symbols, without the "\" prefix.
|
68
|
+
#
|
69
|
+
# The descriptions here were copied from the IMAP4rev2 specification:
|
70
|
+
# [RFC9051 § 7.3.1](https://www.rfc-editor.org/rfc/rfc9051.html#section-7.3.1).
|
71
|
+
#
|
72
|
+
# Other mailbox name attributes can be found in the [IANA IMAP Mailbox Name
|
73
|
+
# Attributes registry](https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml)].
|
74
|
+
# -------------------------------------------------------------------------
|
75
|
+
|
76
|
+
# The "\NonExistent" attribute indicates that a mailbox name does not refer
|
77
|
+
# to an existing mailbox. Note that this attribute is not meaningful by
|
78
|
+
# itself, as mailbox names that match the canonical LIST pattern but don't
|
79
|
+
# exist must not be returned unless one of the two conditions listed below
|
80
|
+
# is also satisfied:
|
81
|
+
#
|
82
|
+
# 1. The mailbox name also satisfies the selection criteria (for example,
|
83
|
+
# it is subscribed and the "SUBSCRIBED" selection option has been
|
84
|
+
# specified).
|
85
|
+
#
|
86
|
+
# 2. "RECURSIVEMATCH" has been specified, and the mailbox name has at least
|
87
|
+
# one descendant mailbox name that does not match the LIST pattern and
|
88
|
+
# does match the selection criteria.
|
89
|
+
#
|
90
|
+
# In practice, this means that the "\NonExistent" attribute is usually
|
91
|
+
# returned with one or more of "\Subscribed", "\Remote", "\HasChildren", or
|
92
|
+
# the CHILDINFO extended data item.
|
93
|
+
#
|
94
|
+
# The client must treat the presence of the \NonExistent attribute as if the
|
95
|
+
# \NoSelect attribute was also sent by the server
|
96
|
+
NONEXISTENT = :NonExistent
|
45
97
|
|
46
|
-
#
|
98
|
+
# Mailbox attribute indicating it is not possible for any child levels of
|
99
|
+
# hierarchy to exist under this name; no child levels exist now and none can
|
100
|
+
# be created in the future children.
|
47
101
|
#
|
48
|
-
#
|
102
|
+
# The client must treat the presence of the \NoInferiors attribute as if the
|
103
|
+
# \HasNoChildren attribute was also sent by the server
|
104
|
+
NOINFERIORS = :Noinferiors
|
105
|
+
|
106
|
+
# Mailbox attribute indicating it is not possible to use this name as a
|
107
|
+
# selectable mailbox.
|
49
108
|
NOSELECT = :Noselect
|
50
109
|
|
51
|
-
#
|
110
|
+
# The presence of this attribute indicates that the mailbox has child
|
111
|
+
# mailboxes. A server SHOULD NOT set this attribute if there are child
|
112
|
+
# mailboxes and the user does not have permission to access any of them. In
|
113
|
+
# this case, \HasNoChildren SHOULD be used. In many cases, however, a server
|
114
|
+
# may not be able to efficiently compute whether a user has access to any
|
115
|
+
# child mailboxes. Note that even though the \HasChildren attribute for a
|
116
|
+
# mailbox must be correct at the time of processing the mailbox, a client
|
117
|
+
# must be prepared to deal with a situation when a mailbox is marked with
|
118
|
+
# the \HasChildren attribute, but no child mailbox appears in the response
|
119
|
+
# to the LIST command. This might happen, for example, due to child
|
120
|
+
# mailboxes being deleted or made inaccessible to the user (using access
|
121
|
+
# control) by another client before the server is able to list them.
|
122
|
+
#
|
123
|
+
# It is an error for the server to return both a \HasChildren and a
|
124
|
+
# \HasNoChildren attribute in the same LIST response. A client that
|
125
|
+
# encounters a LIST response with both \HasChildren and \HasNoChildren
|
126
|
+
# attributes present should act as if both are absent in the LIST response.
|
127
|
+
HAS_CHILDREN = :HasChildren
|
128
|
+
|
129
|
+
# The presence of this attribute indicates that the mailbox has NO child
|
130
|
+
# mailboxes that are accessible to the currently authenticated user.
|
52
131
|
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
132
|
+
# It is an error for the server to return both a \HasChildren and a
|
133
|
+
# \HasNoChildren attribute in the same LIST response. A client that
|
134
|
+
# encounters a LIST response with both \HasChildren and \HasNoChildren
|
135
|
+
# attributes present should act as if both are absent in the LIST response.
|
136
|
+
#
|
137
|
+
# Note: the \HasNoChildren attribute should not be confused with the
|
138
|
+
# \NoInferiors attribute, which indicates that no child mailboxes exist now
|
139
|
+
# and none can be created in the future.
|
140
|
+
HAS_NO_CHILDREN = :HasNoChildren
|
141
|
+
|
142
|
+
# The mailbox has been marked "interesting" by the server; the mailbox
|
143
|
+
# probably contains messages that have been added since the last time the
|
144
|
+
# mailbox was selected.
|
145
|
+
#
|
146
|
+
# If it is not feasible for the server to determine whether or not the
|
147
|
+
# mailbox is "interesting", the server SHOULD NOT send either \Marked or
|
148
|
+
# \Unmarked. The server MUST NOT send more than one of \Marked, \Unmarked,
|
149
|
+
# and \Noselect for a single mailbox, and it MAY send none of these.
|
56
150
|
MARKED = :Marked
|
57
151
|
|
58
|
-
#
|
152
|
+
# The mailbox does not contain any additional messages since the last time
|
153
|
+
# the mailbox was selected.
|
59
154
|
#
|
60
|
-
#
|
155
|
+
# If it is not feasible for the server to determine whether or not the
|
156
|
+
# mailbox is "interesting", the server SHOULD NOT send either \Marked or
|
157
|
+
# \Unmarked. The server MUST NOT send more than one of \Marked, \Unmarked,
|
158
|
+
# and \Noselect for a single mailbox, and it MAY send none of these.
|
61
159
|
UNMARKED = :Unmarked
|
62
160
|
|
63
|
-
|
161
|
+
# The mailbox name was subscribed to using the SUBSCRIBE command.
|
162
|
+
SUBSCRIBED = :Subscribed
|
163
|
+
|
164
|
+
# The mailbox is a remote mailbox.
|
165
|
+
REMOTE = :Remove
|
166
|
+
|
167
|
+
# -------------------------------------------------------------------------
|
168
|
+
# :section: Mailbox Name Attributes, Special Use
|
169
|
+
# Mailbox name attributes will be returned in LIST responses. In addition
|
170
|
+
# to the base mailbox name attributes defined above, an IMAP server MAY also
|
171
|
+
# include any or all of the following attributes that denote "role" (or
|
172
|
+
# "special-use") of a mailbox. These attributes are included along with base
|
173
|
+
# attributes defined above. A given mailbox may have none, one, or more than
|
174
|
+
# one of these attributes. In some cases, a special use is advice to a
|
175
|
+
# client about what to put in that mailbox. In other cases, it's advice to a
|
176
|
+
# client about what to expect to find there.
|
177
|
+
#
|
178
|
+
# IMAP4 specifies that all mailbox name attributes, including future
|
179
|
+
# extensions, begin with "\". +Net::IMAP+ returns all mailbox attributes as
|
180
|
+
# symbols, without the "\" prefix.
|
181
|
+
#
|
182
|
+
# The descriptions here were copied from the IMAP4rev2 specification:
|
183
|
+
# [RFC-9051 § 7.3.1](https://www.rfc-editor.org/rfc/rfc9051.html#section-7.3.1).
|
184
|
+
#
|
185
|
+
# Other mailbox name attributes can be found in the [IANA IMAP Mailbox Name
|
186
|
+
# Attributes registry](https://www.iana.org/assignments/imap-mailbox-name-attributes/imap-mailbox-name-attributes.xhtml)].
|
187
|
+
# -------------------------------------------------------------------------
|
188
|
+
|
189
|
+
# Mailbox attribute indicating that this mailbox presents all messages in
|
190
|
+
# the user's message store. Implementations MAY omit some messages, such as,
|
191
|
+
# perhaps, those in \Trash and \Junk. When this special use is supported, it
|
192
|
+
# is almost certain to represent a virtual mailbox
|
193
|
+
ALL = :All
|
194
|
+
|
195
|
+
# Mailbox attribute indicating that this mailbox is used to archive
|
196
|
+
# messages. The meaning of an "archival" mailbox is server dependent;
|
197
|
+
# typically, it will be used to get messages out of the inbox, or otherwise
|
198
|
+
# keep them out of the user's way, while still making them accessible
|
199
|
+
ARCHIVE = :Archive
|
200
|
+
|
201
|
+
# Mailbox attribute indicating that this mailbox is used to hold draft
|
202
|
+
# messages -- typically, messages that are being composed but have not yet
|
203
|
+
# been sent. In some server implementations, this might be a virtual
|
204
|
+
# mailbox, containing messages from other mailboxes that are marked with the
|
205
|
+
# "\Draft" message flag. Alternatively, this might just be advice that a
|
206
|
+
# client put drafts here
|
207
|
+
DRAFTS = :Drafts
|
208
|
+
|
209
|
+
# FLAGGED is defined with the system flags section.
|
210
|
+
|
211
|
+
# Mailbox attribute indicating that this mailbox is where messages deemed to
|
212
|
+
# be junk mail are held. Some server implementations might put messages here
|
213
|
+
# automatically. Alternatively, this might just be advice to a client-side
|
214
|
+
# spam filter.
|
215
|
+
JUNK = :Junk
|
64
216
|
|
65
|
-
#
|
66
|
-
|
67
|
-
|
68
|
-
|
217
|
+
# Mailbox attribute indicating that this mailbox is used to hold copies of
|
218
|
+
# messages that have been sent. Some server implementations might put
|
219
|
+
# messages here automatically. Alternatively, this might just be advice that
|
220
|
+
# a client save sent messages here.
|
221
|
+
SENT = :Sent
|
69
222
|
|
70
|
-
#
|
71
|
-
|
72
|
-
|
73
|
-
|
223
|
+
# Mailbox attribute indicating that this mailbox is used to hold messages
|
224
|
+
# that have been deleted or marked for deletion. In some server
|
225
|
+
# implementations, this might be a virtual mailbox, containing messages from
|
226
|
+
# other mailboxes that are marked with the "\Deleted" message flag.
|
227
|
+
# Alternatively, this might just be advice that a client that chooses not to
|
228
|
+
# use the IMAP "\Deleted" model should use as its trash location. In server
|
229
|
+
# implementations that strictly expect the IMAP "\Deleted" model, this
|
230
|
+
# special use is likely not to be supported.
|
231
|
+
TRASH = :Trash
|
74
232
|
|
75
233
|
end
|
76
234
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative "errors"
|
4
|
+
|
3
5
|
module Net
|
4
6
|
class IMAP < Protocol
|
5
7
|
|
@@ -9,7 +11,6 @@ module Net
|
|
9
11
|
@pos = nil
|
10
12
|
@lex_state = nil
|
11
13
|
@token = nil
|
12
|
-
@flag_symbols = {}
|
13
14
|
end
|
14
15
|
|
15
16
|
def parse(str)
|
@@ -1212,12 +1213,7 @@ module Net
|
|
1212
1213
|
if atom
|
1213
1214
|
atom
|
1214
1215
|
else
|
1215
|
-
|
1216
|
-
@flag_symbols[symbol] = true
|
1217
|
-
if @flag_symbols.length > IMAP.max_flag_count
|
1218
|
-
raise FlagCountError, "number of flag symbols exceeded"
|
1219
|
-
end
|
1220
|
-
symbol
|
1216
|
+
flag.capitalize.intern
|
1221
1217
|
end
|
1222
1218
|
}
|
1223
1219
|
else
|
data/lib/net/imap.rb
CHANGED
@@ -13,7 +13,6 @@
|
|
13
13
|
# See Net::IMAP for documentation.
|
14
14
|
#
|
15
15
|
|
16
|
-
|
17
16
|
require "socket"
|
18
17
|
require "monitor"
|
19
18
|
require 'net/protocol'
|
@@ -22,12 +21,6 @@ begin
|
|
22
21
|
rescue LoadError
|
23
22
|
end
|
24
23
|
|
25
|
-
require_relative "imap/command_data"
|
26
|
-
require_relative "imap/data_encoding"
|
27
|
-
require_relative "imap/flags"
|
28
|
-
require_relative "imap/response_data"
|
29
|
-
require_relative "imap/response_parser"
|
30
|
-
|
31
24
|
module Net
|
32
25
|
|
33
26
|
#
|
@@ -227,7 +220,7 @@ module Net
|
|
227
220
|
# Unicode", RFC-2152[https://tools.ietf.org/html/rfc2152], May 1997.
|
228
221
|
#
|
229
222
|
class IMAP < Protocol
|
230
|
-
VERSION = "0.
|
223
|
+
VERSION = "0.3.0"
|
231
224
|
|
232
225
|
include MonitorMixin
|
233
226
|
if defined?(OpenSSL::SSL)
|
@@ -385,28 +378,37 @@ module Net
|
|
385
378
|
# Sends an AUTHENTICATE command to authenticate the client.
|
386
379
|
# The +auth_type+ parameter is a string that represents
|
387
380
|
# the authentication mechanism to be used. Currently Net::IMAP
|
388
|
-
# supports the
|
389
|
-
#
|
390
|
-
#
|
391
|
-
#
|
392
|
-
#
|
393
|
-
#
|
394
|
-
#
|
395
|
-
#
|
396
|
-
#
|
397
|
-
#
|
398
|
-
#
|
399
|
-
# the
|
400
|
-
#
|
401
|
-
#
|
402
|
-
#
|
403
|
-
#
|
381
|
+
# supports the following mechanisms:
|
382
|
+
#
|
383
|
+
# PLAIN:: Login using cleartext user and password. Secure with TLS.
|
384
|
+
# See Net::IMAP::PlainAuthenticator.
|
385
|
+
# CRAM-MD5:: DEPRECATED: Use PLAIN (or DIGEST-MD5) with TLS.
|
386
|
+
# DIGEST-MD5:: DEPRECATED by RFC6331. Must be secured using TLS.
|
387
|
+
# See Net::IMAP::DigestMD5Authenticator.
|
388
|
+
# LOGIN:: DEPRECATED: Use PLAIN.
|
389
|
+
#
|
390
|
+
# Most mechanisms require two args: authentication identity (e.g. username)
|
391
|
+
# and credentials (e.g. a password). But each mechanism requires and allows
|
392
|
+
# different arguments; please consult the documentation for the specific
|
393
|
+
# mechanisms you are using. <em>Several obsolete mechanisms are available
|
394
|
+
# for backwards compatibility. Using deprecated mechanisms will issue
|
395
|
+
# warnings.</em>
|
396
|
+
#
|
397
|
+
# Servers do not support all mechanisms and clients must not attempt to use
|
398
|
+
# a mechanism unless "AUTH=#{mechanism}" is listed as a #capability.
|
399
|
+
# Clients must not attempt to authenticate or #login when +LOGINDISABLED+ is
|
400
|
+
# listed with the capabilities. Server capabilities, especially auth
|
401
|
+
# mechanisms, do change after calling #starttls so they need to be checked
|
402
|
+
# again.
|
404
403
|
#
|
405
404
|
# For example:
|
406
405
|
#
|
407
|
-
# imap.authenticate('
|
406
|
+
# imap.authenticate('PLAIN', user, password)
|
408
407
|
#
|
409
408
|
# A Net::IMAP::NoResponseError is raised if authentication fails.
|
409
|
+
#
|
410
|
+
# See +Net::IMAP::Authenticators+ for more information on plugging in your
|
411
|
+
# own authenticator.
|
410
412
|
def authenticate(auth_type, *args)
|
411
413
|
authenticator = self.class.authenticator(auth_type, *args)
|
412
414
|
send_command("AUTHENTICATE", auth_type) do |resp|
|
@@ -1462,118 +1464,13 @@ module Net
|
|
1462
1464
|
end
|
1463
1465
|
end
|
1464
1466
|
|
1465
|
-
# Common validators of number and nz_number types
|
1466
|
-
module NumValidator # :nodoc
|
1467
|
-
class << self
|
1468
|
-
# Check is passed argument valid 'number' in RFC 3501 terminology
|
1469
|
-
def valid_number?(num)
|
1470
|
-
# [RFC 3501]
|
1471
|
-
# number = 1*DIGIT
|
1472
|
-
# ; Unsigned 32-bit integer
|
1473
|
-
# ; (0 <= n < 4,294,967,296)
|
1474
|
-
num >= 0 && num < 4294967296
|
1475
|
-
end
|
1476
|
-
|
1477
|
-
# Check is passed argument valid 'nz_number' in RFC 3501 terminology
|
1478
|
-
def valid_nz_number?(num)
|
1479
|
-
# [RFC 3501]
|
1480
|
-
# nz-number = digit-nz *DIGIT
|
1481
|
-
# ; Non-zero unsigned 32-bit integer
|
1482
|
-
# ; (0 < n < 4,294,967,296)
|
1483
|
-
num != 0 && valid_number?(num)
|
1484
|
-
end
|
1485
|
-
|
1486
|
-
# Check is passed argument valid 'mod_sequence_value' in RFC 4551 terminology
|
1487
|
-
def valid_mod_sequence_value?(num)
|
1488
|
-
# mod-sequence-value = 1*DIGIT
|
1489
|
-
# ; Positive unsigned 64-bit integer
|
1490
|
-
# ; (mod-sequence)
|
1491
|
-
# ; (1 <= n < 18,446,744,073,709,551,615)
|
1492
|
-
num >= 1 && num < 18446744073709551615
|
1493
|
-
end
|
1494
|
-
|
1495
|
-
# Ensure argument is 'number' or raise DataFormatError
|
1496
|
-
def ensure_number(num)
|
1497
|
-
return if valid_number?(num)
|
1498
|
-
|
1499
|
-
msg = "number must be unsigned 32-bit integer: #{num}"
|
1500
|
-
raise DataFormatError, msg
|
1501
|
-
end
|
1502
|
-
|
1503
|
-
# Ensure argument is 'nz_number' or raise DataFormatError
|
1504
|
-
def ensure_nz_number(num)
|
1505
|
-
return if valid_nz_number?(num)
|
1506
|
-
|
1507
|
-
msg = "nz_number must be non-zero unsigned 32-bit integer: #{num}"
|
1508
|
-
raise DataFormatError, msg
|
1509
|
-
end
|
1510
|
-
|
1511
|
-
# Ensure argument is 'mod_sequence_value' or raise DataFormatError
|
1512
|
-
def ensure_mod_sequence_value(num)
|
1513
|
-
return if valid_mod_sequence_value?(num)
|
1514
|
-
|
1515
|
-
msg = "mod_sequence_value must be unsigned 64-bit integer: #{num}"
|
1516
|
-
raise DataFormatError, msg
|
1517
|
-
end
|
1518
|
-
end
|
1519
|
-
end
|
1520
|
-
|
1521
|
-
# Superclass of IMAP errors.
|
1522
|
-
class Error < StandardError
|
1523
|
-
end
|
1524
|
-
|
1525
|
-
# Error raised when data is in the incorrect format.
|
1526
|
-
class DataFormatError < Error
|
1527
|
-
end
|
1528
|
-
|
1529
|
-
# Error raised when a response from the server is non-parseable.
|
1530
|
-
class ResponseParseError < Error
|
1531
|
-
end
|
1532
|
-
|
1533
|
-
# Superclass of all errors used to encapsulate "fail" responses
|
1534
|
-
# from the server.
|
1535
|
-
class ResponseError < Error
|
1536
|
-
|
1537
|
-
# The response that caused this error
|
1538
|
-
attr_accessor :response
|
1539
|
-
|
1540
|
-
def initialize(response)
|
1541
|
-
@response = response
|
1542
|
-
|
1543
|
-
super @response.data.text
|
1544
|
-
end
|
1545
|
-
|
1546
|
-
end
|
1547
|
-
|
1548
|
-
# Error raised upon a "NO" response from the server, indicating
|
1549
|
-
# that the client command could not be completed successfully.
|
1550
|
-
class NoResponseError < ResponseError
|
1551
|
-
end
|
1552
|
-
|
1553
|
-
# Error raised upon a "BAD" response from the server, indicating
|
1554
|
-
# that the client command violated the IMAP protocol, or an internal
|
1555
|
-
# server failure has occurred.
|
1556
|
-
class BadResponseError < ResponseError
|
1557
|
-
end
|
1558
|
-
|
1559
|
-
# Error raised upon a "BYE" response from the server, indicating
|
1560
|
-
# that the client is not being allowed to login, or has been timed
|
1561
|
-
# out due to inactivity.
|
1562
|
-
class ByeResponseError < ResponseError
|
1563
|
-
end
|
1564
|
-
|
1565
|
-
# Error raised upon an unknown response from the server.
|
1566
|
-
class UnknownResponseError < ResponseError
|
1567
|
-
end
|
1568
|
-
|
1569
|
-
RESPONSE_ERRORS = Hash.new(ResponseError)
|
1570
|
-
RESPONSE_ERRORS["NO"] = NoResponseError
|
1571
|
-
RESPONSE_ERRORS["BAD"] = BadResponseError
|
1572
|
-
|
1573
|
-
# Error raised when too many flags are interned to symbols.
|
1574
|
-
class FlagCountError < Error
|
1575
|
-
end
|
1576
1467
|
end
|
1577
1468
|
end
|
1578
1469
|
|
1470
|
+
require_relative "imap/errors"
|
1471
|
+
require_relative "imap/command_data"
|
1472
|
+
require_relative "imap/data_encoding"
|
1473
|
+
require_relative "imap/flags"
|
1474
|
+
require_relative "imap/response_data"
|
1475
|
+
require_relative "imap/response_parser"
|
1579
1476
|
require_relative "imap/authenticators"
|
data/net-imap.gemspec
CHANGED
@@ -10,13 +10,13 @@ end
|
|
10
10
|
Gem::Specification.new do |spec|
|
11
11
|
spec.name = name
|
12
12
|
spec.version = version
|
13
|
-
spec.authors = ["Shugo Maeda"]
|
14
|
-
spec.email = ["shugo@ruby-lang.org"]
|
13
|
+
spec.authors = ["Shugo Maeda", "nicholas a. evans"]
|
14
|
+
spec.email = ["shugo@ruby-lang.org", "nick@ekenosen.net"]
|
15
15
|
|
16
16
|
spec.summary = %q{Ruby client api for Internet Message Access Protocol}
|
17
17
|
spec.description = %q{Ruby client api for Internet Message Access Protocol}
|
18
18
|
spec.homepage = "https://github.com/ruby/net-imap"
|
19
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
19
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
|
20
20
|
spec.licenses = ["Ruby", "BSD-2-Clause"]
|
21
21
|
|
22
22
|
spec.metadata["homepage_uri"] = spec.homepage
|
@@ -25,13 +25,13 @@ Gem::Specification.new do |spec|
|
|
25
25
|
# Specify which files should be added to the gem when it is released.
|
26
26
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
27
27
|
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
28
|
-
`git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
28
|
+
`git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(bin|test|spec|features)/}) }
|
29
29
|
end
|
30
30
|
spec.bindir = "exe"
|
31
31
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
32
|
spec.require_paths = ["lib"]
|
33
33
|
|
34
34
|
spec.add_dependency "net-protocol"
|
35
|
-
spec.
|
36
|
-
spec.
|
35
|
+
spec.add_development_dependency "digest"
|
36
|
+
spec.add_development_dependency "strscan"
|
37
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-imap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shugo Maeda
|
8
|
+
- nicholas a. evans
|
8
9
|
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2022-09-28 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: net-protocol
|
@@ -31,7 +32,7 @@ dependencies:
|
|
31
32
|
- - ">="
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: '0'
|
34
|
-
type: :
|
35
|
+
type: :development
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
@@ -45,7 +46,7 @@ dependencies:
|
|
45
46
|
- - ">="
|
46
47
|
- !ruby/object:Gem::Version
|
47
48
|
version: '0'
|
48
|
-
type: :
|
49
|
+
type: :development
|
49
50
|
prerelease: false
|
50
51
|
version_requirements: !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
@@ -55,18 +56,18 @@ dependencies:
|
|
55
56
|
description: Ruby client api for Internet Message Access Protocol
|
56
57
|
email:
|
57
58
|
- shugo@ruby-lang.org
|
59
|
+
- nick@ekenosen.net
|
58
60
|
executables: []
|
59
61
|
extensions: []
|
60
62
|
extra_rdoc_files: []
|
61
63
|
files:
|
64
|
+
- ".github/dependabot.yml"
|
62
65
|
- ".github/workflows/test.yml"
|
63
66
|
- ".gitignore"
|
64
67
|
- Gemfile
|
65
68
|
- LICENSE.txt
|
66
69
|
- README.md
|
67
70
|
- Rakefile
|
68
|
-
- bin/console
|
69
|
-
- bin/setup
|
70
71
|
- lib/net/imap.rb
|
71
72
|
- lib/net/imap/authenticators.rb
|
72
73
|
- lib/net/imap/authenticators/cram_md5.rb
|
@@ -75,6 +76,7 @@ files:
|
|
75
76
|
- lib/net/imap/authenticators/plain.rb
|
76
77
|
- lib/net/imap/command_data.rb
|
77
78
|
- lib/net/imap/data_encoding.rb
|
79
|
+
- lib/net/imap/errors.rb
|
78
80
|
- lib/net/imap/flags.rb
|
79
81
|
- lib/net/imap/response_data.rb
|
80
82
|
- lib/net/imap/response_parser.rb
|
@@ -94,14 +96,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
96
|
requirements:
|
95
97
|
- - ">="
|
96
98
|
- !ruby/object:Gem::Version
|
97
|
-
version: 2.
|
99
|
+
version: 2.6.0
|
98
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
101
|
requirements:
|
100
102
|
- - ">="
|
101
103
|
- !ruby/object:Gem::Version
|
102
104
|
version: '0'
|
103
105
|
requirements: []
|
104
|
-
rubygems_version: 3.
|
106
|
+
rubygems_version: 3.4.0.dev
|
105
107
|
signing_key:
|
106
108
|
specification_version: 4
|
107
109
|
summary: Ruby client api for Internet Message Access Protocol
|
data/bin/console
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "bundler/setup"
|
4
|
-
require "net/imap"
|
5
|
-
|
6
|
-
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|