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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +87 -0
- data/README.md +85 -0
- data/Rakefile +1 -0
- data/lib/omniauth-lightning.rb +2 -0
- data/lib/omniauth-lightning/version.rb +5 -0
- data/lib/omniauth/strategies/lightning.rb +117 -0
- data/omniauth-lightning.gemspec +24 -0
- metadata +94 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
@@ -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
|
data/Gemfile.lock
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -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: []
|