omniauth-lightning 1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 040a37ee31c22a382c2fd4a8d393684d8adf3b02accca452ae83a27e1893a6b5
4
+ data.tar.gz: 5c7d0cc3b48357a841f8b29c92994dd0c46be6889ef596d3956e067f923ebbcb
5
+ SHA512:
6
+ metadata.gz: df233b22170ea947d55e218a1cc9a5f07f00f70b71b6a1b57edc4d89fecb31fb0496ec4ba261f1379a301d61df81a94a089cc3a9832c584c6c80cc1f1f156b38
7
+ data.tar.gz: 70abfab149c5e438a5e82d76222457ec93c8291d766fc55ae49db781a1c1c2054f52219426b07bee4f3bfbc097a32be2786d0957c38934b07856a9ce621878b6
@@ -0,0 +1 @@
1
+ pkg
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ ruby '2.6.4'
6
+
7
+ gem 'rake'
8
+
9
+ group :test do
10
+ if Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.0.0")
11
+ # for jruby 1.7.x
12
+ gem "addressable", "2.4.0"
13
+ end
14
+
15
+ if Gem::Version.create(RUBY_VERSION) < Gem::Version.create("2.2.2")
16
+ gem "rack", "~> 1.6"
17
+ end
18
+
19
+ gem 'rspec', '~> 3.2'
20
+ gem 'rack-test'
21
+ gem 'simplecov'
22
+ gem 'webmock'
23
+ end
@@ -0,0 +1,87 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ omniauth-lightning (1.0)
5
+ omniauth-oauth (~> 1.1)
6
+ rack
7
+ rest-client (~> 2)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ addressable (2.7.0)
13
+ public_suffix (>= 2.0.2, < 5.0)
14
+ crack (0.4.3)
15
+ safe_yaml (~> 1.0.0)
16
+ diff-lcs (1.3)
17
+ docile (1.3.2)
18
+ domain_name (0.5.20190701)
19
+ unf (>= 0.0.5, < 1.0.0)
20
+ hashdiff (1.0.0)
21
+ hashie (3.6.0)
22
+ http-accept (1.7.0)
23
+ http-cookie (1.0.3)
24
+ domain_name (~> 0.5)
25
+ mime-types (3.3.1)
26
+ mime-types-data (~> 3.2015)
27
+ mime-types-data (3.2019.1009)
28
+ netrc (0.11.0)
29
+ oauth (0.5.4)
30
+ omniauth (1.9.0)
31
+ hashie (>= 3.4.6, < 3.7.0)
32
+ rack (>= 1.6.2, < 3)
33
+ omniauth-oauth (1.1.0)
34
+ oauth
35
+ omniauth (~> 1.0)
36
+ public_suffix (4.0.3)
37
+ rack (2.2.2)
38
+ rack-test (1.1.0)
39
+ rack (>= 1.0, < 3)
40
+ rake (13.0.1)
41
+ rest-client (2.1.0)
42
+ http-accept (>= 1.7.0, < 2.0)
43
+ http-cookie (>= 1.0.2, < 2.0)
44
+ mime-types (>= 1.16, < 4.0)
45
+ netrc (~> 0.8)
46
+ rspec (3.9.0)
47
+ rspec-core (~> 3.9.0)
48
+ rspec-expectations (~> 3.9.0)
49
+ rspec-mocks (~> 3.9.0)
50
+ rspec-core (3.9.1)
51
+ rspec-support (~> 3.9.1)
52
+ rspec-expectations (3.9.0)
53
+ diff-lcs (>= 1.2.0, < 2.0)
54
+ rspec-support (~> 3.9.0)
55
+ rspec-mocks (3.9.1)
56
+ diff-lcs (>= 1.2.0, < 2.0)
57
+ rspec-support (~> 3.9.0)
58
+ rspec-support (3.9.2)
59
+ safe_yaml (1.0.5)
60
+ simplecov (0.18.2)
61
+ docile (~> 1.1)
62
+ simplecov-html (~> 0.11)
63
+ simplecov-html (0.12.0)
64
+ unf (0.1.4)
65
+ unf_ext
66
+ unf_ext (0.0.7.6)
67
+ webmock (3.8.2)
68
+ addressable (>= 2.3.6)
69
+ crack (>= 0.3.2)
70
+ hashdiff (>= 0.4.0, < 2.0.0)
71
+
72
+ PLATFORMS
73
+ ruby
74
+
75
+ DEPENDENCIES
76
+ omniauth-lightning!
77
+ rack-test
78
+ rake
79
+ rspec (~> 3.2)
80
+ simplecov
81
+ webmock
82
+
83
+ RUBY VERSION
84
+ ruby 2.6.4p104
85
+
86
+ BUNDLED WITH
87
+ 2.1.4
@@ -0,0 +1,85 @@
1
+ # omniauth-lightning
2
+
3
+ This gem implements an Omniauth strategy to login via the Lightning Network. It uses [LNPay.co]
4
+ as the backend.
5
+
6
+ Once integrated, users of your application can submit an invoice from their own node,
7
+ this gem will decode the invoice to extract the pubkey of the user's node and use that pubkey
8
+ as the UID of the user.
9
+
10
+ Note that the user will submit Lightning Network invoices to your application, but your application
11
+ won't need to pay them.
12
+
13
+ ## Installation
14
+
15
+ Add to your `Gemfile`:
16
+
17
+ ```ruby
18
+ gem 'omniauth-lightning'
19
+ ```
20
+
21
+ and run `bundle install`.
22
+
23
+ ## Integration
24
+
25
+ Next, tell OmniAuth about this provider. For a Rails app, your `config/initializers/omniauth.rb` file should look like this:
26
+
27
+ ```ruby
28
+ Rails.application.config.middleware.use OmniAuth::Builder do
29
+ provider :lightning,
30
+ invoice_sats_amount: 1,
31
+ validating_text: 'my-app-auth-string',
32
+ lnpay_key: 'my-lnpay-key' # secret api key from https://lnpay.co/dashboard/developers
33
+ end
34
+ ```
35
+
36
+ This configuration will make the strategy require a `1 sat` invoice that includes the text `my-app-auth-string`
37
+ to validate the invoice.
38
+
39
+ ### Configuration
40
+
41
+ The following settings are available:
42
+ ```ruby
43
+ :title # title of the rendered form that prompts user to submit their invoice
44
+ :sats_amount # amount of sats that the invoice should include
45
+ :validating_text # text that should be included in the invoice's description
46
+ :invoice_max_age_in_seconds # maximum age of invoices that are accepted in seconds
47
+ :lnpay_key # Key from LNPay.co to use to decode invoices
48
+ ```
49
+
50
+ ### Error keys
51
+
52
+ The following errors might be returned from the gem; you might want to handle them on your
53
+ application to display errors:
54
+
55
+ ```ruby
56
+ :invalid_invoice # invoice invalid
57
+ :invoice_without_required_amount # invoice wasn't for the amount specified on :sats_amount
58
+ :invoice_without_required_text # invoice didn't include the required text specified on :validating_text
59
+ :old_invoice # invoice is older than :invoice_max_age_in_seconds
60
+ :custodial_wallet # invoice was generated by a custodial wallet
61
+ ```
62
+
63
+ ## Customizing Invoice Form
64
+
65
+ To use your own custom invoice form, create a form that POSTs to '/auth/lightning/callback' with `invoice`.
66
+
67
+ ```erb
68
+ <%= form_tag '/auth/lightning/callback' do |f| %>
69
+ <h1>Submit your invoice</h1>
70
+ <%= text_field_tag :invoice %>
71
+ <%= submit_tag %>
72
+ <% end %>
73
+ ```
74
+
75
+ ## Example app
76
+
77
+ If you want to see an app using this gem, checkout [bitcoiners-best]. To see a live version of this, checkout https://bitcoiners.best/
78
+
79
+ ## Author
80
+
81
+ Written by [@pablof7z].
82
+
83
+ [LNPay.co]: https://lnpay.co
84
+ [bitcoiners-best]: https://github.com/bitcoiners-Best/bitcoinersbest
85
+ [@pablof7z]: https://twitter.com/pablof7z
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,2 @@
1
+ require "omniauth-lightning/version"
2
+ require 'omniauth/strategies/lightning'
@@ -0,0 +1,5 @@
1
+ module OmniAuth
2
+ module Lightning
3
+ VERSION = "1.0"
4
+ end
5
+ end
@@ -0,0 +1,117 @@
1
+ require 'omniauth-oauth'
2
+ require 'json'
3
+
4
+ module OmniAuth
5
+ module Strategies
6
+ class Lightning
7
+ include OmniAuth::Strategy
8
+
9
+ option :title, 'Lightning Network Verification'
10
+ option :sats_amount, 10
11
+ option :validating_text, 'invoice-for-auth'
12
+ option :invoice_max_age_in_seconds, 1800
13
+ option :lnpay_key, 'pak_O0iUMxk8kK_qUzkT4YKFvp1ZsUtp'
14
+ option :fields, [:pubkey]
15
+
16
+ uid { @pubkey }
17
+
18
+ info do
19
+ {
20
+ pubkey: @pubkey,
21
+ description: @description
22
+ }
23
+ end
24
+
25
+ def request_phase
26
+ if options[:on_login]
27
+ options[:on_login].call(self.env)
28
+ else
29
+ OmniAuth::Form.build(
30
+ title: (options[:title]),
31
+ url: callback_path
32
+ ) do |f|
33
+ f.html """
34
+ <p>
35
+ Create an invoice for #{options[:invoice_sats_amount]}
36
+ satoshis that starts with \"#{options[:validating_text]}\".
37
+ </p>
38
+ """
39
+ f.text_field 'Invoice', 'invoice'
40
+ end.to_response
41
+ end
42
+ end
43
+
44
+ def callback_phase
45
+ r = validate_invoice!(request['invoice'])
46
+
47
+ if r == :ok
48
+ super
49
+ else
50
+ return fail!(*r)
51
+ end
52
+ end
53
+
54
+ private
55
+
56
+ def invalid_invoice(data)
57
+ !data || data['error']
58
+ end
59
+
60
+ def invoice_without_required_amount(data)
61
+ data['num_satoshis'].to_i != options[:sats_amount]
62
+ end
63
+
64
+ def invoice_without_required_text(data)
65
+ !data['description'].downcase.include?(options[:validating_text].downcase)
66
+ end
67
+
68
+ def invoice_too_old(data)
69
+ Time.at(data['timestamp'].to_i) < Time.now - options[:invoice_max_age_in_seconds].to_i
70
+ end
71
+
72
+ def invoice_from_custodial_wallet(data)
73
+ CUSTODIAL_PUBKEYS.include?(data['destination'])
74
+ end
75
+
76
+ def validate_invoice!(invoice)
77
+ data = decode_invoice(invoice)
78
+
79
+ case
80
+ when invalid_invoice(data)
81
+ return :invalid_invoice, ((data && data['error']) ? Exception.new(data['error']) : nil)
82
+ when invoice_without_required_amount(data)
83
+ return :invoice_without_required_amount,
84
+ Exception.new("Invoice amount is #{data['num_satoshis']}; " \
85
+ "should have been #{options[:sats_amount]}")
86
+ when invoice_without_required_text(data)
87
+ return :invoice_without_required_text,
88
+ Exception.new("Invoice's description is '#{data['description']}'; " \
89
+ "should have text '#{options[:validating_text]}'")
90
+ when invoice_too_old(data)
91
+ return :old_invoice
92
+ when invoice_from_custodial_wallet(data)
93
+ return :custodial_wallet
94
+ end
95
+
96
+ @pubkey = data['destination']
97
+ @description = data['description']
98
+
99
+ return :ok
100
+ end
101
+
102
+ def decode_invoice(invoice)
103
+ response = RestClient.get("https://#{options[:lnpay_key]}@lnpay.co/v1/node/default/payments/decodeinvoice", params: { payment_request: invoice })
104
+
105
+ JSON.parse(response.body)
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ CUSTODIAL_PUBKEYS = [
112
+ '03021c5f5f57322740e4ee6936452add19dc7ea7ccf90635f95119ab82a62ae268', # bluewallet
113
+ '02004c625d622245606a1ea2c1c69cfb4516b703b47945a3647713c05fe4aaeb1c', # WalletOfSatoshi.com
114
+ '03c2abfa93eacec04721c019644584424aab2ba4dff3ac9bdab4e9c97007491dda', # tippin.me
115
+ '031015a7839468a3c266d662d5bb21ea4cea24226936e2864a7ca4f2c3939836e0', # Breez
116
+ '02a59dd887d4396178325ffb3f54b7fcb9ada9dd0d615caea2f2306d92a3692f6e', # dropbit.app
117
+ ].freeze
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "omniauth-lightning/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "omniauth-lightning"
7
+ s.version = OmniAuth::Lightning::VERSION
8
+ s.authors = ["Pablo Fernandez"]
9
+ s.email = ["pfer@me.com"]
10
+ s.homepage = "https://github.com/heelhook/omniauth-lightning"
11
+ s.description = %q{OmniAuth strategy for Lightning Network}
12
+ s.summary = s.description
13
+ s.license = "MIT"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+ s.required_ruby_version = Gem::Requirement.new('>= 1.9.3')
20
+ s.add_dependency 'omniauth-oauth', '~> 1.1'
21
+ s.add_dependency 'rest-client', '~> 2'
22
+ s.add_dependency 'rack'
23
+ # s.add_development_dependency 'bundler', '~> 2.1'
24
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omniauth-lightning
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Pablo Fernandez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: omniauth-oauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rest-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: OmniAuth strategy for Lightning Network
56
+ email:
57
+ - pfer@me.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - Gemfile.lock
65
+ - README.md
66
+ - Rakefile
67
+ - lib/omniauth-lightning.rb
68
+ - lib/omniauth-lightning/version.rb
69
+ - lib/omniauth/strategies/lightning.rb
70
+ - omniauth-lightning.gemspec
71
+ homepage: https://github.com/heelhook/omniauth-lightning
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 1.9.3
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubygems_version: 3.0.6
91
+ signing_key:
92
+ specification_version: 4
93
+ summary: OmniAuth strategy for Lightning Network
94
+ test_files: []