rodauth-oauth 0.9.0 → 0.9.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 +4 -4
- data/README.md +3 -2
- data/doc/release_notes/0_9_1.md +9 -0
- data/doc/release_notes/0_9_2.md +10 -0
- data/doc/release_notes/0_9_3.md +9 -0
- data/lib/generators/rodauth/oauth/templates/db/migrate/create_rodauth_oauth.rb +1 -0
- data/lib/rodauth/features/oauth_application_management.rb +1 -1
- data/lib/rodauth/features/oauth_base.rb +53 -57
- data/lib/rodauth/features/oauth_jwt.rb +23 -34
- data/lib/rodauth/features/oauth_jwt_bearer_grant.rb +1 -0
- data/lib/rodauth/features/oauth_management_base.rb +4 -0
- data/lib/rodauth/features/oidc.rb +10 -9
- data/lib/rodauth/oauth/version.rb +1 -1
- data/locales/en.yml +1 -1
- data/templates/jwks_field.str +1 -1
- data/templates/jwt_public_key_field.str +1 -1
- data/templates/new_oauth_application.str +1 -1
- data/templates/scope_field.str +3 -2
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79fa7abfcf7ea1c0a2594f92bfd7a59e53769dec5a7221a22f740b37471e6e07
|
4
|
+
data.tar.gz: 9f7e8ce4370d44d985940d46d569e3192c35e53cb6e3841094517e64258b2b1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 520a85416c418f93615a471133201c7ec6dd5c16ff9d697a6ca87b609084b58c7b9799c5d3c7a8d02a4fc68ca9750c9ef41dd07dde17c1e1153f0cec8e58f3c1
|
7
|
+
data.tar.gz: 8e7ebc28ba158f43b5226a2de98fc76de8c81e8a8c87dbaa95a69050eed96793e487666389b60be6694437c298fdf23f183a1df098983eeec5f5549df0321c7c
|
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Rodauth::Oauth
|
2
2
|
|
3
|
-
[](http://rubygems.org/gems/rodauth-oauth)
|
4
|
+
[](https://gitlab.com/honeyryderchuck/rodauth-oauth/pipelines?page=1&scope=all&ref=master)
|
4
5
|
[](https://honeyryderchuck.gitlab.io/rodauth-oauth/coverage/#_AllFiles)
|
5
6
|
|
6
7
|
This is an extension to the `rodauth` gem which implements the [OAuth 2.0 framework](https://tools.ietf.org/html/rfc6749) for an authorization server.
|
@@ -73,7 +74,7 @@ Or install it yourself as:
|
|
73
74
|
|
74
75
|
## Usage
|
75
76
|
|
76
|
-
This tutorial assumes you already read the documentation and know how to set up `rodauth`. After that, integrating `
|
77
|
+
This tutorial assumes you already read the documentation and know how to set up `rodauth`. After that, integrating `rodauth-oauth` will look like:
|
77
78
|
|
78
79
|
```ruby
|
79
80
|
plugin :rodauth do
|
@@ -0,0 +1,9 @@
|
|
1
|
+
### 0.9.1 (08/05/2022)
|
2
|
+
|
3
|
+
#### Improvements
|
4
|
+
|
5
|
+
Using `return_response`, introduced in `rodauth` v2.23, which accomplishes better integration with rails response logging mechanism when used under `rodauth-rails`.
|
6
|
+
|
7
|
+
#### Bugfixes
|
8
|
+
|
9
|
+
* Fixing namespacing issue which required anyone to have to `require "rodauth-oauth"` before loading it (no need to anymore).
|
@@ -0,0 +1,10 @@
|
|
1
|
+
### 0.9.2 (11/05/2022)
|
2
|
+
|
3
|
+
#### Bugfixes
|
4
|
+
|
5
|
+
* Fixed remaining namespacing fix issues requiring usage of `require "rodauth-oauth"`.
|
6
|
+
* Fixed wrong expectation of database for resource-server mode when `:oauth_management_base` plugin was used.
|
7
|
+
* oidc: fixed incorrect grant creation flow whenn using `nonce` param.
|
8
|
+
* oidc: fixed jwt encoding regression when not setting encryption method/algorithmm for client applications.
|
9
|
+
* templates: added missing jwks field to the "New oauth application" form.
|
10
|
+
* Several fixes on the example OIDC applications, mostly around CSRF breakage when using latest version of `omniauth`.
|
@@ -0,0 +1,9 @@
|
|
1
|
+
### 0.9.2 (30/05/2022)
|
2
|
+
|
3
|
+
#### Bugfixes
|
4
|
+
|
5
|
+
* `oauth_jwt`: new access tokens generated via the `"refresh_token"` grant type are now JWT (it was falling back to non JWT behaviour);
|
6
|
+
* `oidc`: a new `id_token` is now generated via the `"refresh_token"` grant type with "rotation" policy (it was being omitted from the response);
|
7
|
+
* `oidc`: fixing calculation of `"auth_time"` claim, which (as per RFC) needs to stay the same across first authentication and subsequent `"refresh_token"` requests;
|
8
|
+
* it requires a new db column (default: `"auth_time"`, datetime) in the `"oauth_tokens"` database;
|
9
|
+
* hash-column `"refresh_token"` will now expose the refresh token (instead of the hash column version) in the `"refresh_token"` grant type response payload (only happened in "non-rotation" refresh token mode).
|
@@ -33,7 +33,7 @@ module Rodauth
|
|
33
33
|
|
34
34
|
translatable_method :oauth_applications_name_label, "Name"
|
35
35
|
translatable_method :oauth_applications_description_label, "Description"
|
36
|
-
translatable_method :oauth_applications_scopes_label, "
|
36
|
+
translatable_method :oauth_applications_scopes_label, "Default scopes"
|
37
37
|
translatable_method :oauth_applications_contacts_label, "Contacts"
|
38
38
|
translatable_method :oauth_applications_tos_uri_label, "Terms of service"
|
39
39
|
translatable_method :oauth_applications_policy_uri_label, "Policy"
|
@@ -4,6 +4,8 @@ require "time"
|
|
4
4
|
require "base64"
|
5
5
|
require "securerandom"
|
6
6
|
require "net/http"
|
7
|
+
require "rodauth/version"
|
8
|
+
require "rodauth/oauth/version"
|
7
9
|
require "rodauth/oauth/ttl_store"
|
8
10
|
require "rodauth/oauth/database_extensions"
|
9
11
|
require "rodauth/oauth/refinements"
|
@@ -424,32 +426,40 @@ module Rodauth
|
|
424
426
|
}.merge(params)
|
425
427
|
|
426
428
|
rescue_from_uniqueness_error do
|
427
|
-
|
429
|
+
access_token = _generate_access_token(create_params)
|
430
|
+
refresh_token = _generate_refresh_token(create_params) if should_generate_refresh_token
|
431
|
+
oauth_token = _store_oauth_token(create_params)
|
432
|
+
oauth_token[oauth_tokens_token_column] = access_token
|
433
|
+
oauth_token[oauth_tokens_refresh_token_column] = refresh_token if refresh_token
|
434
|
+
oauth_token
|
435
|
+
end
|
436
|
+
end
|
428
437
|
|
429
|
-
|
430
|
-
|
431
|
-
else
|
432
|
-
create_params[oauth_tokens_token_column] = token
|
433
|
-
end
|
438
|
+
def _generate_access_token(params = {})
|
439
|
+
token = oauth_unique_id_generator
|
434
440
|
|
435
|
-
|
436
|
-
|
437
|
-
|
441
|
+
if oauth_tokens_token_hash_column
|
442
|
+
params[oauth_tokens_token_hash_column] = generate_token_hash(token)
|
443
|
+
else
|
444
|
+
params[oauth_tokens_token_column] = token
|
445
|
+
end
|
438
446
|
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
447
|
+
token
|
448
|
+
end
|
449
|
+
|
450
|
+
def _generate_refresh_token(params)
|
451
|
+
token = oauth_unique_id_generator
|
452
|
+
|
453
|
+
if oauth_tokens_refresh_token_hash_column
|
454
|
+
params[oauth_tokens_refresh_token_hash_column] = generate_token_hash(token)
|
455
|
+
else
|
456
|
+
params[oauth_tokens_refresh_token_column] = token
|
449
457
|
end
|
458
|
+
|
459
|
+
token
|
450
460
|
end
|
451
461
|
|
452
|
-
def
|
462
|
+
def _store_oauth_token(params = {})
|
453
463
|
ds = db[oauth_tokens_table]
|
454
464
|
|
455
465
|
if __one_oauth_token_per_account
|
@@ -575,43 +585,24 @@ module Rodauth
|
|
575
585
|
|
576
586
|
rescue_from_uniqueness_error do
|
577
587
|
oauth_tokens_ds = db[oauth_tokens_table]
|
578
|
-
|
588
|
+
access_token = _generate_access_token(update_params)
|
579
589
|
|
580
|
-
if
|
581
|
-
update_params
|
590
|
+
if oauth_refresh_token_protection_policy == "rotation"
|
591
|
+
update_params = {
|
592
|
+
**update_params,
|
593
|
+
oauth_tokens_oauth_token_id_column => oauth_token[oauth_tokens_id_column],
|
594
|
+
oauth_tokens_account_id_column => oauth_token[oauth_tokens_account_id_column],
|
595
|
+
oauth_tokens_scopes_column => oauth_token[oauth_tokens_scopes_column]
|
596
|
+
}
|
597
|
+
|
598
|
+
refresh_token = _generate_refresh_token(update_params)
|
582
599
|
else
|
583
|
-
|
600
|
+
refresh_token = param("refresh_token")
|
584
601
|
end
|
602
|
+
oauth_token = __update_and_return__(oauth_tokens_ds, update_params)
|
585
603
|
|
586
|
-
oauth_token =
|
587
|
-
|
588
|
-
**update_params,
|
589
|
-
oauth_tokens_oauth_token_id_column => oauth_token[oauth_tokens_id_column],
|
590
|
-
oauth_tokens_scopes_column => oauth_token[oauth_tokens_scopes_column]
|
591
|
-
}
|
592
|
-
|
593
|
-
refresh_token = oauth_unique_id_generator
|
594
|
-
|
595
|
-
if oauth_tokens_refresh_token_hash_column
|
596
|
-
insert_params[oauth_tokens_refresh_token_hash_column] = generate_token_hash(refresh_token)
|
597
|
-
else
|
598
|
-
insert_params[oauth_tokens_refresh_token_column] = refresh_token
|
599
|
-
end
|
600
|
-
|
601
|
-
# revoke the refresh token
|
602
|
-
oauth_tokens_ds.where(oauth_tokens_id_column => oauth_token[oauth_tokens_id_column])
|
603
|
-
.update(oauth_tokens_revoked_at_column => Sequel::CURRENT_TIMESTAMP)
|
604
|
-
|
605
|
-
insert_params[oauth_tokens_oauth_token_id_column] = oauth_token[oauth_tokens_id_column]
|
606
|
-
__insert_and_return__(oauth_tokens_ds, oauth_tokens_id_column, insert_params)
|
607
|
-
else
|
608
|
-
# includes none
|
609
|
-
ds = oauth_tokens_ds.where(oauth_tokens_id_column => oauth_token[oauth_tokens_id_column])
|
610
|
-
__update_and_return__(ds, update_params)
|
611
|
-
end
|
612
|
-
|
613
|
-
oauth_token[oauth_tokens_token_column] = token
|
614
|
-
oauth_token[oauth_tokens_refresh_token_column] = refresh_token if refresh_token
|
604
|
+
oauth_token[oauth_tokens_token_column] = access_token
|
605
|
+
oauth_token[oauth_tokens_refresh_token_column] = refresh_token
|
615
606
|
oauth_token
|
616
607
|
end
|
617
608
|
end
|
@@ -687,8 +678,7 @@ module Rodauth
|
|
687
678
|
response["Pragma"] = "no-cache"
|
688
679
|
end
|
689
680
|
json_payload = _json_response_body(body)
|
690
|
-
|
691
|
-
request.halt
|
681
|
+
return_response(json_payload)
|
692
682
|
end
|
693
683
|
|
694
684
|
def throw_json_response_error(status, error_code, message = nil)
|
@@ -703,8 +693,7 @@ module Rodauth
|
|
703
693
|
json_payload = _json_response_body(payload)
|
704
694
|
response["Content-Type"] ||= json_response_content_type
|
705
695
|
response["WWW-Authenticate"] = oauth_token_type.upcase if status == 401
|
706
|
-
|
707
|
-
request.halt
|
696
|
+
return_response(json_payload)
|
708
697
|
end
|
709
698
|
|
710
699
|
unless method_defined?(:_json_response_body)
|
@@ -717,6 +706,13 @@ module Rodauth
|
|
717
706
|
end
|
718
707
|
end
|
719
708
|
|
709
|
+
if Gem::Version.new(Rodauth.version) < Gem::Version.new("2.23")
|
710
|
+
def return_response(body = nil)
|
711
|
+
response.write(body) if body
|
712
|
+
request.halt
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
720
716
|
def authorization_required
|
721
717
|
if accepts_json?
|
722
718
|
throw_json_response_error(authorization_required_error_status, "invalid_client")
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
+
require "rodauth/oauth/version"
|
3
4
|
require "rodauth/oauth/ttl_store"
|
4
5
|
|
5
6
|
module Rodauth
|
@@ -38,6 +39,9 @@ module Rodauth
|
|
38
39
|
|
39
40
|
translatable_method :oauth_applications_jwt_public_key_label, "Public key"
|
40
41
|
|
42
|
+
auth_value_method :oauth_application_jwt_public_key_param, "jwt_public_key"
|
43
|
+
auth_value_method :oauth_application_jwks_param, "jwks"
|
44
|
+
|
41
45
|
auth_value_method :oauth_jwt_keys, {}
|
42
46
|
auth_value_method :oauth_jwt_key, nil
|
43
47
|
auth_value_method :oauth_jwt_public_key, nil
|
@@ -62,7 +66,6 @@ module Rodauth
|
|
62
66
|
:jwt_encode,
|
63
67
|
:jwt_decode,
|
64
68
|
:jwks_set,
|
65
|
-
:last_account_login_at,
|
66
69
|
:generate_jti
|
67
70
|
)
|
68
71
|
|
@@ -95,12 +98,6 @@ module Rodauth
|
|
95
98
|
|
96
99
|
private
|
97
100
|
|
98
|
-
unless method_defined?(:last_account_login_at)
|
99
|
-
def last_account_login_at
|
100
|
-
nil
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
101
|
def issuer
|
105
102
|
@issuer ||= oauth_jwt_token_issuer || authorization_server_url
|
106
103
|
end
|
@@ -171,41 +168,38 @@ module Rodauth
|
|
171
168
|
|
172
169
|
# /token
|
173
170
|
|
174
|
-
def
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
if should_generate_refresh_token
|
181
|
-
refresh_token = oauth_unique_id_generator
|
182
|
-
|
183
|
-
if oauth_tokens_refresh_token_hash_column
|
184
|
-
create_params[oauth_tokens_refresh_token_hash_column] = generate_token_hash(refresh_token)
|
185
|
-
else
|
186
|
-
create_params[oauth_tokens_refresh_token_column] = refresh_token
|
187
|
-
end
|
188
|
-
end
|
171
|
+
def create_oauth_token_from_token(oauth_token, update_params)
|
172
|
+
otoken = super
|
173
|
+
access_token = _generate_jwt_access_token(otoken)
|
174
|
+
otoken[oauth_tokens_token_column] = access_token
|
175
|
+
otoken
|
176
|
+
end
|
189
177
|
|
190
|
-
|
191
|
-
|
178
|
+
def generate_oauth_token(params = {}, should_generate_refresh_token = true)
|
179
|
+
oauth_token = super
|
180
|
+
access_token = _generate_jwt_access_token(oauth_token)
|
181
|
+
oauth_token[oauth_tokens_token_column] = access_token
|
182
|
+
oauth_token
|
183
|
+
end
|
192
184
|
|
185
|
+
def _generate_jwt_access_token(oauth_token)
|
193
186
|
claims = jwt_claims(oauth_token)
|
194
187
|
|
195
188
|
# one of the points of using jwt is avoiding database lookups, so we put here all relevant
|
196
189
|
# token data.
|
197
190
|
claims[:scope] = oauth_token[oauth_tokens_scopes_column]
|
198
191
|
|
199
|
-
|
192
|
+
jwt_encode(claims)
|
193
|
+
end
|
200
194
|
|
201
|
-
|
202
|
-
|
195
|
+
def _generate_access_token(*)
|
196
|
+
# no op
|
203
197
|
end
|
204
198
|
|
205
199
|
def jwt_claims(oauth_token)
|
206
200
|
issued_at = Time.now.to_i
|
207
201
|
|
208
|
-
|
202
|
+
{
|
209
203
|
iss: issuer, # issuer
|
210
204
|
iat: issued_at, # issued at
|
211
205
|
#
|
@@ -223,10 +217,6 @@ module Rodauth
|
|
223
217
|
exp: issued_at + oauth_token_expires_in,
|
224
218
|
aud: (oauth_jwt_audience || oauth_application[oauth_applications_client_id_column])
|
225
219
|
}
|
226
|
-
|
227
|
-
claims[:auth_time] = last_account_login_at.to_i if last_account_login_at
|
228
|
-
|
229
|
-
claims
|
230
220
|
end
|
231
221
|
|
232
222
|
def jwt_subject(oauth_token)
|
@@ -714,8 +704,7 @@ module Rodauth
|
|
714
704
|
response["Cache-Control"] = "no-store"
|
715
705
|
response["Pragma"] = "no-cache"
|
716
706
|
end
|
717
|
-
|
718
|
-
request.halt
|
707
|
+
return_response(jwt)
|
719
708
|
end
|
720
709
|
end
|
721
710
|
end
|
@@ -74,6 +74,7 @@ module Rodauth
|
|
74
74
|
|
75
75
|
auth_value_method :oauth_grants_nonce_column, :nonce
|
76
76
|
auth_value_method :oauth_tokens_nonce_column, :nonce
|
77
|
+
auth_value_method :oauth_tokens_auth_time_column, :auth_time
|
77
78
|
|
78
79
|
translatable_method :invalid_scope_message, "The Access Token expired"
|
79
80
|
|
@@ -120,7 +121,8 @@ module Rodauth
|
|
120
121
|
jwks: oauth_application_jwks,
|
121
122
|
encryption_algorithm: @oauth_application[oauth_applications_userinfo_encrypted_response_alg_column],
|
122
123
|
encryption_method: @oauth_application[oauth_applications_userinfo_encrypted_response_enc_column]
|
123
|
-
}
|
124
|
+
}.compact
|
125
|
+
|
124
126
|
jwt = jwt_encode(
|
125
127
|
oidc_claims,
|
126
128
|
signing_algorithm: algo,
|
@@ -234,8 +236,7 @@ module Rodauth
|
|
234
236
|
href: authorization_server_url
|
235
237
|
}]
|
236
238
|
})
|
237
|
-
|
238
|
-
request.halt
|
239
|
+
return_response(json_payload)
|
239
240
|
end
|
240
241
|
end
|
241
242
|
end
|
@@ -316,7 +317,7 @@ module Rodauth
|
|
316
317
|
def create_oauth_grant(create_params = {})
|
317
318
|
return super unless (nonce = param_or_nil("nonce"))
|
318
319
|
|
319
|
-
super(oauth_grants_nonce_column => nonce)
|
320
|
+
super(create_params.merge(oauth_grants_nonce_column => nonce))
|
320
321
|
end
|
321
322
|
|
322
323
|
def create_oauth_token_from_authorization_code(oauth_grant, create_params)
|
@@ -341,8 +342,7 @@ module Rodauth
|
|
341
342
|
|
342
343
|
# Time when the End-User authentication occurred.
|
343
344
|
#
|
344
|
-
|
345
|
-
id_token_claims[:auth_time] = id_token_claims[:iat]
|
345
|
+
id_token_claims[:auth_time] = oauth_token[oauth_tokens_auth_time_column].to_i
|
346
346
|
|
347
347
|
account = db[accounts_table].where(account_id_column => oauth_token[oauth_tokens_account_id_column]).first
|
348
348
|
|
@@ -358,7 +358,8 @@ module Rodauth
|
|
358
358
|
signing_algorithm: oauth_application[oauth_applications_id_token_signed_response_alg_column] || oauth_jwt_algorithm,
|
359
359
|
encryption_algorithm: oauth_application[oauth_applications_id_token_encrypted_response_alg_column],
|
360
360
|
encryption_method: oauth_application[oauth_applications_id_token_encrypted_response_enc_column]
|
361
|
-
}
|
361
|
+
}.compact
|
362
|
+
|
362
363
|
oauth_token[:id_token] = jwt_encode(id_token_claims, **params)
|
363
364
|
end
|
364
365
|
|
@@ -487,7 +488,7 @@ module Rodauth
|
|
487
488
|
end
|
488
489
|
end
|
489
490
|
|
490
|
-
scope_claims.unshift("auth_time")
|
491
|
+
scope_claims.unshift("auth_time")
|
491
492
|
|
492
493
|
response_types_supported = metadata[:response_types_supported]
|
493
494
|
|
@@ -533,7 +534,7 @@ module Rodauth
|
|
533
534
|
response["Access-Control-Allow-Methods"] = "GET, OPTIONS"
|
534
535
|
response["Access-Control-Max-Age"] = "3600"
|
535
536
|
response.status = 200
|
536
|
-
|
537
|
+
return_response
|
537
538
|
end
|
538
539
|
end
|
539
540
|
end
|
data/locales/en.yml
CHANGED
@@ -19,7 +19,7 @@ en:
|
|
19
19
|
oauth_management_pagination_next_button: "Next"
|
20
20
|
oauth_applications_name_label: "Name"
|
21
21
|
oauth_applications_description_label: "Description"
|
22
|
-
oauth_applications_scopes_label: "
|
22
|
+
oauth_applications_scopes_label: "Default scopes"
|
23
23
|
oauth_applications_contacts_label: "Contacts"
|
24
24
|
oauth_applications_homepage_url_label: "Homepage URL"
|
25
25
|
oauth_applications_tos_uri_label: "Terms of Service URL"
|
data/templates/jwks_field.str
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
<div class="form-group">
|
2
2
|
<label for="name">#{rodauth.oauth_applications_jwks_label}#{rodauth.input_field_label_suffix}</label>
|
3
|
-
|
3
|
+
<textarea id="jwks" class="form-control" name="#{rodauth.oauth_application_jwks_param}" rows="3"></textarea>
|
4
4
|
</div>
|
@@ -1,4 +1,4 @@
|
|
1
1
|
<div class="form-group">
|
2
2
|
<label for="name">#{rodauth.oauth_applications_jwt_public_key_label}#{rodauth.input_field_label_suffix}</label>
|
3
|
-
#{rodauth.input_field_string(rodauth.oauth_application_jwt_public_key_param, "jwt_public_key", :type=>"text")}
|
3
|
+
#{rodauth.input_field_string(rodauth.oauth_application_jwt_public_key_param, "jwt_public_key", :type=>"text", :required=>false)}
|
4
4
|
</div>
|
data/templates/scope_field.str
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
<fieldset class="form-group">
|
2
|
+
<legend>#{rodauth.oauth_applications_scopes_label}</legend>
|
2
3
|
#{
|
3
4
|
rodauth.oauth_application_scopes.map do |scope|
|
4
|
-
"<div class=\"form-check
|
5
|
-
"<input id=\"#{scope}\" type=\"checkbox\" name=\"#{rodauth.oauth_application_scopes_param}[]\" value=\"#{scope}\">" +
|
5
|
+
"<div class=\"form-group form-check\">" +
|
6
|
+
"<input id=\"#{scope}\" type=\"checkbox\" class=\"form-check-input\" name=\"#{rodauth.oauth_application_scopes_param}[]\" value=\"#{scope}\">" +
|
6
7
|
"<label for=\"#{scope}\">#{scope}</label>" +
|
7
8
|
"</div>"
|
8
9
|
end.join
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rodauth-oauth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tiago Cardoso
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rodauth
|
@@ -57,6 +57,9 @@ extra_rdoc_files:
|
|
57
57
|
- doc/release_notes/0_7_4.md
|
58
58
|
- doc/release_notes/0_8_0.md
|
59
59
|
- doc/release_notes/0_9_0.md
|
60
|
+
- doc/release_notes/0_9_1.md
|
61
|
+
- doc/release_notes/0_9_2.md
|
62
|
+
- doc/release_notes/0_9_3.md
|
60
63
|
files:
|
61
64
|
- CHANGELOG.md
|
62
65
|
- LICENSE.txt
|
@@ -85,6 +88,9 @@ files:
|
|
85
88
|
- doc/release_notes/0_7_4.md
|
86
89
|
- doc/release_notes/0_8_0.md
|
87
90
|
- doc/release_notes/0_9_0.md
|
91
|
+
- doc/release_notes/0_9_1.md
|
92
|
+
- doc/release_notes/0_9_2.md
|
93
|
+
- doc/release_notes/0_9_3.md
|
88
94
|
- lib/generators/rodauth/oauth/install_generator.rb
|
89
95
|
- lib/generators/rodauth/oauth/templates/app/models/oauth_application.rb
|
90
96
|
- lib/generators/rodauth/oauth/templates/app/models/oauth_grant.rb
|