omniauth-lightning 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []