mournmail 1.0.1 → 1.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d2cbdbd1f9d9fe5f74f7d098cbf1eae74e113d544705005a9ca95f652799c7e3
4
- data.tar.gz: 384b036461c6ea691d7559bb17fec0c2439ebebf51e5694e49481844d25336a5
3
+ metadata.gz: 7b758be18cec7a7b8e51d1d1a02cdc8652200800d3c96cd54b471f360e139310
4
+ data.tar.gz: d201ace873c79702fec68815cda4276f4d78d8dcb60e982b2d24c43efd014778
5
5
  SHA512:
6
- metadata.gz: 18831f3e5fff6e0a181791c56a926c866cfef9f2b210e5f47f7f0bca04c73695130cdd3f9924b9a7e359e1f479e878ea1c8c157092162e366513e62a9111eca3
7
- data.tar.gz: b252222b12d59b599df9f81f5b610dff5649c0440782e89ca273602039738b8a3708f6499560ad461c88844a14c0bcb2e9216ddb21dbdd00471a82de52e71569
6
+ metadata.gz: d972e8d6410736c90eb8074f723a96bed957ca7cdd7c74350261c47cce57c3527a692ea422375e08a5f892ee08fbcfcb7d88edbb0b83e9c6ab1adf6f0616383b
7
+ data.tar.gz: fa3659729fc83d4373896511009080e36297c1382e857e25ef2c7dfa1421d78ef506bafd23d81e00f504972116a0a281843359b22b4446b2031791e6b115450c
@@ -36,4 +36,21 @@ module Textbringer
36
36
  end
37
37
  CONFIG[:mournmail_addresses_path] = File.expand_path("~/.addresses")
38
38
  CONFIG[:mournmail_signature_regexp] = /^\n-- /
39
+ CONFIG[:mournmail_allowed_attachment_extensions] = [
40
+ "txt",
41
+ "md",
42
+ "htm",
43
+ "html",
44
+ "pdf",
45
+ "jpg",
46
+ "jpeg",
47
+ "png",
48
+ "gif",
49
+ "doc",
50
+ "docx",
51
+ "xls",
52
+ "xlsx",
53
+ "ppt",
54
+ "zip"
55
+ ]
39
56
  end
@@ -129,6 +129,14 @@ module Mournmail
129
129
  raise EditorError, "Can't open a multipart entity."
130
130
  end
131
131
  ext = part_file_name(part).slice(/\.([^.]+)\z/, 1)
132
+ if part.main_type != "text" || part.sub_type == "html"
133
+ if ext.nil?
134
+ raise EditorError, "The extension of the filename is not specified"
135
+ end
136
+ if !CONFIG[:mournmail_allowed_attachment_extensions].include?(ext)
137
+ raise EditorError, ".#{ext} is not allowed"
138
+ end
139
+ end
132
140
  if ext
133
141
  file_name = ["mournmail", "." + ext]
134
142
  else
@@ -11,12 +11,13 @@ require 'google/api_client/client_secrets'
11
11
  require 'google/api_client/auth/storage'
12
12
  require 'google/api_client/auth/storages/file_store'
13
13
  require 'launchy'
14
+ require "socket"
14
15
 
15
16
  class Net::SMTP
16
17
  def auth_xoauth2(user, secret)
17
18
  check_auth_args user, secret
18
19
  res = critical {
19
- s = Mournmail.xoauth2_string(user, secret)
20
+ s = Net::IMAP::XOauth2Authenticator.new(user, secret).process("")
20
21
  get_response('AUTH XOAUTH2 ' + base64_encode(s))
21
22
  }
22
23
  check_auth_response res
@@ -24,20 +25,6 @@ class Net::SMTP
24
25
  end
25
26
  end
26
27
 
27
- class Net::IMAP::Xoauth2Authenticator
28
- def process(data)
29
- Mournmail.xoauth2_string(@user, @access_token)
30
- end
31
-
32
- private
33
-
34
- def initialize(user, access_token)
35
- @user = user
36
- @access_token = access_token
37
- end
38
- end
39
- Net::IMAP.add_authenticator("XOAUTH2", Net::IMAP::Xoauth2Authenticator)
40
-
41
28
  module Mournmail
42
29
  begin
43
30
  require "mail-gpg"
@@ -225,6 +212,41 @@ module Mournmail
225
212
  end
226
213
  end
227
214
 
215
+ class GoogleAuthCallbackServer
216
+ def initialize
217
+ @servers = Socket.tcp_server_sockets("127.0.0.1", 0)
218
+ end
219
+
220
+ def port
221
+ @servers.first.local_address.ip_port
222
+ end
223
+
224
+ def receive_code
225
+ Socket.accept_loop(@servers) do |sock, addr|
226
+ line = sock.gets
227
+ query_string = line.slice(%r'\AGET [^?]*\?(.*) HTTP/1.1\r\n', 1)
228
+ params = CGI.parse(query_string)
229
+ code = params["code"][0]
230
+ while line = sock.gets
231
+ break if line == "\r\n"
232
+ end
233
+ sock.print("HTTP/1.1 200 OK\r\n")
234
+ sock.print("Content-Type: text/plain\r\n")
235
+ sock.print("\r\n")
236
+ if code
237
+ sock.print("Authenticated!")
238
+ else
239
+ sock.print("Authentication failed!")
240
+ end
241
+ return code
242
+ ensure
243
+ sock.close
244
+ end
245
+ ensure
246
+ @servers.each(&:close)
247
+ end
248
+ end
249
+
228
250
  def self.google_access_token(account = current_account)
229
251
  auth_path = File.expand_path("cache/#{account}/google_auth.json",
230
252
  CONFIG[:mournmail_directory])
@@ -236,28 +258,21 @@ module Mournmail
236
258
  conf = CONFIG[:mournmail_accounts][account]
237
259
  path = File.expand_path(conf[:client_secret_path])
238
260
  client_secrets = Google::APIClient::ClientSecrets.load(path)
261
+ callback_server = GoogleAuthCallbackServer.new
239
262
  auth_client = client_secrets.to_authorization
240
263
  auth_client.update!(
241
264
  :scope => 'https://mail.google.com/',
242
- :redirect_uri => 'urn:ietf:wg:oauth:2.0:oob'
265
+ :redirect_uri => "http://127.0.0.1:#{callback_server.port}/"
243
266
  )
244
267
  auth_uri = auth_client.authorization_uri.to_s
245
- auth_client.code = foreground! {
268
+ foreground! do
246
269
  begin
247
270
  Launchy.open(auth_uri)
248
271
  rescue Launchy::CommandNotFoundError
249
- buffer = show_google_auth_uri(auth_uri)
272
+ show_google_auth_uri(auth_uri)
250
273
  end
251
- begin
252
- Window.echo_area.clear_message
253
- Window.redisplay
254
- read_from_minibuffer("Code: ").chomp
255
- ensure
256
- if buffer
257
- kill_buffer(buffer, force: true)
258
- end
259
- end
260
- }
274
+ end
275
+ auth_client.code = callback_server.receive_code
261
276
  auth_client.fetch_access_token!
262
277
  old_umask = File.umask(077)
263
278
  begin
@@ -288,10 +303,6 @@ module Mournmail
288
303
  buffer
289
304
  end
290
305
 
291
- def self.xoauth2_string(user, access_token)
292
- "user=#{user}\1auth=Bearer #{access_token}\1\1"
293
- end
294
-
295
306
  def self.fetch_summary(mailbox, all: false)
296
307
  if all
297
308
  summary = Mournmail::Summary.new(mailbox)
@@ -1,3 +1,3 @@
1
1
  module Mournmail
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.3"
3
3
  end
data/mournmail.gemspec CHANGED
@@ -23,11 +23,11 @@ Gem::Specification.new do |spec|
23
23
 
24
24
  spec.add_runtime_dependency "textbringer"
25
25
  spec.add_runtime_dependency "net-smtp"
26
- spec.add_runtime_dependency "net-imap"
26
+ spec.add_runtime_dependency "net-imap", ">= 0.3.1"
27
27
  spec.add_runtime_dependency "mail"
28
28
  spec.add_runtime_dependency "mime-types"
29
29
  spec.add_runtime_dependency "rroonga"
30
- spec.add_runtime_dependency "google-api-client"
30
+ spec.add_runtime_dependency "google-apis-core"
31
31
  spec.add_runtime_dependency "launchy"
32
32
  spec.add_runtime_dependency "html2text"
33
33
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mournmail
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-06 00:00:00.000000000 Z
11
+ date: 2022-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: textbringer
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 0.3.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 0.3.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: mail
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: google-api-client
98
+ name: google-apis-core
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="