j1_template_mde 2018.4.31 → 2018.4.32

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.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/_includes/themes/j1/layouts/layout_metadata_generator.html +5 -6
  3. data/_includes/themes/j1/layouts/layout_shim_generator.html +20 -2
  4. data/_includes/themes/j1/layouts/layout_theme_generator.html +2 -2
  5. data/_includes/themes/j1/modules/connectors/{analytic/google → ad/custom-provider.html} +7 -16
  6. data/_includes/themes/j1/modules/connectors/ad/google-adsense.html +6 -6
  7. data/_includes/themes/j1/modules/connectors/ads +23 -8
  8. data/_includes/themes/j1/modules/connectors/analytic/custom-provider.html +32 -0
  9. data/_includes/themes/j1/modules/connectors/analytic/google-analytics.html +38 -0
  10. data/_includes/themes/j1/modules/connectors/analytics +16 -17
  11. data/_includes/themes/j1/modules/connectors/comment/custom-provider.html +31 -0
  12. data/_includes/themes/j1/modules/connectors/comment/disqus.html +3 -3
  13. data/_includes/themes/j1/modules/connectors/comment/facebook.html +31 -0
  14. data/_includes/themes/j1/modules/connectors/comments +14 -12
  15. data/_includes/themes/j1/modules/connectors/sharing +3 -10
  16. data/_includes/themes/j1/modules/navigator/generator.html +17 -12
  17. data/_includes/themes/j1/modules/navigator/procedures/quicklinks.proc +37 -27
  18. data/_includes/themes/j1/modules/navigator/procedures/sidebar.proc +3 -3
  19. data/_includes/themes/j1/procedures/layouts/module_writer.proc +4 -4
  20. data/_includes/themes/j1/procedures/layouts/resource_writer.proc +6 -6
  21. data/lib/j1/version.rb +1 -1
  22. data/lib/j1_app/j1_auth_manager/_unused/auth_manager.before_merge_added.rb +1267 -0
  23. data/lib/j1_app/j1_auth_manager/_unused/auth_manager.update.web_cookie.rb +1333 -0
  24. data/lib/j1_app/j1_auth_manager/_unused/auth_manager_ui.2.erb +198 -0
  25. data/lib/j1_app/j1_auth_manager/_unused/auth_manager_ui.additional_inits.erb +254 -0
  26. data/lib/j1_app/j1_auth_manager/auth_manager.rb +361 -275
  27. data/lib/j1_app/j1_auth_manager/config.rb +9 -9
  28. data/lib/j1_app/j1_auth_manager/helpers.rb +60 -2
  29. data/lib/j1_app/j1_auth_manager/views/auth_manager_ui.erb +123 -37
  30. data/lib/starter_web/Gemfile +1 -1
  31. data/lib/starter_web/_config.yml +42 -32
  32. data/lib/starter_web/_data/j1_config.yml +46 -56
  33. data/lib/starter_web/_data/j1_resources.yml +25 -5
  34. data/lib/starter_web/_data/layouts/default.yml +10 -0
  35. data/lib/starter_web/_data/modules/j1_cookie_consent.yml +120 -0
  36. data/lib/starter_web/_data/modules/j1_log4javascript.yml +24 -22
  37. data/lib/starter_web/_data/modules/j1_navigator.yml +61 -50
  38. data/lib/starter_web/_data/modules/j1_navigator_menu.yml +32 -11
  39. data/lib/starter_web/_data/tables/country.asciidoc +252 -0
  40. data/lib/starter_web/assets/data/_authclient.html +365 -0
  41. data/lib/starter_web/assets/data/authclient.html +213 -222
  42. data/lib/starter_web/assets/data/cookie_consent.html +261 -0
  43. data/lib/starter_web/assets/data/countries.json +974 -0
  44. data/lib/starter_web/assets/data/footer.html +17 -26
  45. data/lib/starter_web/assets/data/menu.html +20 -21
  46. data/lib/starter_web/assets/images/icons/j1/scalable/j1v2.svg +1 -1
  47. data/lib/starter_web/assets/images/master_header/admin-bootstrap.jpg +0 -0
  48. data/lib/starter_web/assets/images/pages/roundtrip/package.json +16 -16
  49. data/lib/starter_web/assets/themes/j1/core/css/theme_extensions.css +1313 -1219
  50. data/lib/starter_web/assets/themes/j1/core/css/theme_extensions.min.css +1 -1
  51. data/lib/starter_web/assets/themes/j1/core/css/uno.css +1251 -1219
  52. data/lib/starter_web/assets/themes/j1/core/css/uno.min.css +1 -1
  53. data/lib/starter_web/assets/themes/j1/core/css/vendor.css +72 -72
  54. data/lib/starter_web/assets/themes/j1/core/css/vendor.min.css +2 -2
  55. data/lib/starter_web/assets/themes/j1/core/js/adapter/algolia.js +1 -1
  56. data/lib/starter_web/assets/themes/j1/core/js/adapter/back2top.js +1 -1
  57. data/lib/starter_web/assets/themes/j1/core/js/adapter/bs_gallery.js +1 -1
  58. data/lib/starter_web/assets/themes/j1/core/js/adapter/cookie_consent.js +345 -0
  59. data/lib/starter_web/assets/themes/j1/core/js/adapter/custom.js +1 -1
  60. data/lib/starter_web/assets/themes/j1/core/js/adapter/lightbox.js +1 -1
  61. data/lib/starter_web/assets/themes/j1/core/js/adapter/logger.js +1 -1
  62. data/lib/starter_web/assets/themes/j1/core/js/adapter/master_header.js +1 -1
  63. data/lib/starter_web/assets/themes/j1/core/js/adapter/navigator.js +254 -190
  64. data/lib/starter_web/assets/themes/j1/core/js/adapter/scroller.js +1 -1
  65. data/lib/starter_web/assets/themes/j1/core/js/adapter/searcher.js +1 -1
  66. data/lib/starter_web/assets/themes/j1/core/js/adapter/stickybits.js +1 -1
  67. data/lib/starter_web/assets/themes/j1/core/js/adapter/switcher.js +1 -1
  68. data/lib/starter_web/assets/themes/j1/core/js/adapter/template.js +432 -97
  69. data/lib/starter_web/assets/themes/j1/core/js/adapter/toccer.js +1 -1
  70. data/lib/starter_web/assets/themes/j1/core/js/template.js +15 -15
  71. data/lib/starter_web/assets/themes/j1/core/js/template.js.map +1 -1
  72. data/lib/starter_web/assets/themes/j1/core/js/template.min.js +1 -1
  73. data/lib/starter_web/assets/themes/j1/extensions/cookiebar/js/cookiebar.js +277 -0
  74. data/lib/starter_web/assets/themes/j1/{core/js/adapter/cookiebar.js → extensions/cookiebar/js/j1cookiebar.js} +1 -1
  75. data/lib/starter_web/collections/_biography/becoming.adoc +1 -1
  76. data/lib/starter_web/collections/_biography/born-to-run.adoc +1 -1
  77. data/lib/starter_web/collections/posts/{premium → private}/series/_posts/000_includes/attributes.asciidoc +0 -0
  78. data/lib/starter_web/collections/posts/{premium → private}/series/_posts/000_includes/documents/100-docker-using-shared-folders.asciidoc +0 -0
  79. data/lib/starter_web/collections/posts/{premium → private}/series/_posts/000_includes/documents/loop.sh +0 -0
  80. data/lib/starter_web/collections/posts/{premium → private}/series/_posts/000_includes/tables/debug_variables.asciidoc +0 -0
  81. data/lib/starter_web/collections/posts/{premium → private}/series/_posts/2018-11-01-docker-using-shared-folders.adoc +0 -0
  82. data/lib/starter_web/collections/posts/{private → protected}/wikipedia/_posts/000_includes/attributes.asciidoc +0 -0
  83. data/lib/starter_web/collections/posts/{private → protected}/wikipedia/_posts/000_includes/tables/debug_variables.asciidoc +0 -0
  84. data/lib/starter_web/collections/posts/{private → protected}/wikipedia/_posts/2016-11-20-minneapolis.adoc +0 -0
  85. data/lib/starter_web/collections/posts/{private → protected}/wikipedia/_posts/2016-11-24-narcisse-snake-dens.adoc +0 -0
  86. data/lib/starter_web/collections/posts/{private → protected}/wikipedia/_posts/2016-11-26-columbia-river.adoc +1 -1
  87. data/lib/starter_web/collections/posts/public/featured/_posts/2019-04-12-about-cookies.adoc +175 -0
  88. data/lib/starter_web/collections/posts/public/{featured → jekyll}/_posts/2018-05-01-confusion-about-base-url.adoc +0 -0
  89. data/lib/starter_web/index.html +4 -1
  90. data/lib/starter_web/package.json +1 -1
  91. data/lib/starter_web/pages/{premium → private}/bookshelf/100_about_jekyll_collections.adoc +1 -1
  92. data/lib/starter_web/pages/{premium → private}/bookshelf/200_book_shelf_biography.adoc +1 -1
  93. data/lib/starter_web/pages/{premium → private}/bookshelf/300_book_shelf_fantasy.adoc +1 -1
  94. data/lib/starter_web/pages/{premium → private}/bookshelf/400_book_shelf_romance.adoc +1 -1
  95. data/lib/starter_web/pages/{private → protected}/TeamUp/000_includes/attributes.asciidoc +0 -0
  96. data/lib/starter_web/pages/{private → protected}/TeamUp/index.adoc +3 -3
  97. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/attributes.asciidoc +0 -0
  98. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/100_absolute_sizes.asciidoc +0 -0
  99. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/110_bs_grid_sizes.asciidoc +0 -0
  100. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/120_relative_sizes.asciidoc +0 -0
  101. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/200_rotate.asciidoc +0 -0
  102. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/300_flip.asciidoc +0 -0
  103. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/400_spin_pulsed.asciidoc +0 -0
  104. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/500_bw_color_palette.asciidoc +0 -0
  105. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/510_bs_color_palette.asciidoc +0 -0
  106. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/600_md_color_palette.asciidoc +0 -0
  107. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/601_md_color_palette_indigo.asciidoc +0 -0
  108. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/mdi_icons/602_md_color_palette_pink.asciidoc +0 -0
  109. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/twitter_emoji/100_bs_sizes.asciidoc +0 -0
  110. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/twitter_emoji/100_relative_sizes.asciidoc +0 -0
  111. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/twitter_emoji/200_rotate.asciidoc +0 -0
  112. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/twitter_emoji/300_flip.asciidoc +0 -0
  113. data/lib/starter_web/pages/{private → protected}/previewer/000_includes/tables/twitter_emoji/400_spin_pulsed.asciidoc +0 -0
  114. data/lib/starter_web/pages/{private → protected}/previewer/justified_gallery.html +1 -1
  115. data/lib/starter_web/pages/{private → protected}/previewer/mdi_icons_preview.adoc +1 -1
  116. data/lib/starter_web/pages/{private → protected}/previewer/twitter_emoji_preview.adoc +1 -1
  117. data/lib/starter_web/pages/public/about/about_you.adoc +139 -0
  118. data/lib/starter_web/pages/public/legal/de/100_impress.adoc +26 -15
  119. data/lib/starter_web/pages/public/legal/de/200_terms_of_use.adoc +2 -2
  120. data/lib/starter_web/pages/public/legal/en/100_impress.adoc +65 -53
  121. data/lib/starter_web/pages/public/legal/en/200_terms_of_use.adoc +11 -8
  122. data/lib/starter_web/pages/public/legal/en/300_privacy.adoc +46 -68
  123. data/lib/starter_web/pages/public/legal/en/400_license_agreement.adoc +72 -74
  124. data/lib/starter_web/pages/public/legal/en/eu/cookie.policy.asciidoc +55 -0
  125. data/lib/starter_web/pages/public/previewer/bootstrap_theme.adoc +1 -1
  126. data/lib/starter_web/pages/public/start/roundtrip/700_extended_modals.adoc +71 -53
  127. metadata +60 -44
  128. data/_includes/themes/j1/modules/connectors/analytic/googleUA +0 -44
  129. data/lib/starter_web/_data/modules/j1_cookiebar.yml +0 -65
  130. data/lib/starter_web/_unused/package.json.new +0 -125
@@ -17,28 +17,30 @@
17
17
  {% endcomment %}
18
18
 
19
19
  {% comment %} Liquid procedures
20
- --------------------------------------------------------------- {% endcomment %}
20
+ -------------------------------------------------------------------------------- {% endcomment %}
21
21
 
22
22
  {% comment %} Variables
23
- --------------------------------------------------------------- {% endcomment %}
24
-
23
+ -------------------------------------------------------------------------------- {% endcomment %}
24
+ {% assign comments = site.data.j1_config.comments.enabled %}
25
+ {% assign comment_provider = site.data.j1_config.comments.provider %}
25
26
 
26
27
  {% comment %} Main
27
- --------------------------------------------------------------- {% endcomment %}
28
+ -------------------------------------------------------------------------------- {% endcomment %}
28
29
 
29
- {% if site.data.j1_config.comment.provider and page.comments %}
30
+ <!-- [INFO ] [j1.layout.connectors ] [Start processing load region head, layout: {{page.layout}}] -->
31
+ {% if comments and page.comments %}
30
32
 
31
- {% case site.data.j1_config.comment.provider %}
33
+ {% case comment_provider %}
32
34
  {% when "disqus" %}
35
+ <!-- [INFO ] [j1.layout.connectors ] [Place comment provider DISQUS ] -->
33
36
  {% include themes/{{site.template.name}}/modules/connectors/comment/disqus.html %}
34
- {% when "livefyre" %}
35
- {% include themes/{{site.template.name}}/procedures/provider/comment/livefyre %}
36
- {% when "intensedebate" %}
37
- {% include themes/{{site.template.name}}/procedures/provider/comment/intensedebate %}
38
37
  {% when "facebook" %}
39
- {% include themes/{{site.template.name}}/procedures/provider/comment/facebook %}
38
+ <!-- [INFO ] [j1.layout.connectors ] [Place comment provider FACEBOOK ] -->
39
+ {% include themes/{{site.template.name}}/procedures/provider/comment/facebook.html %}
40
40
  {% when "custom" %}
41
- {% include themes/{{site.template.name}}/procedures/provider/comment/custom %}
41
+ <!-- [INFO ] [j1.layout.connectors ] [Place comment provider CUSTOM ] -->
42
+ {% include themes/{{site.template.name}}/procedures/provider/comment/custom-provider.html %}
42
43
  {% endcase %}
43
44
 
44
45
  {% endif %}
46
+ <!-- [INFO ] [j1.layout.connectors ] [End processing] -->
@@ -17,20 +17,13 @@
17
17
  {% endcomment %}
18
18
 
19
19
  {% comment %} Liquid procedures
20
- --------------------------------------------------------------- {% endcomment %}
20
+ -------------------------------------------------------------------------------- {% endcomment %}
21
21
 
22
22
  {% comment %} Variables
23
- --------------------------------------------------------------- {% endcomment %}
23
+ -------------------------------------------------------------------------------- {% endcomment %}
24
24
 
25
25
 
26
26
  {% comment %} Main
27
- --------------------------------------------------------------- {% endcomment %}
27
+ -------------------------------------------------------------------------------- {% endcomment %}
28
28
 
29
- {% if site.safe and site.xxj.sharing.provider and page.xxj.sharing != false %}
30
29
 
31
- {% case site.xxj.sharing.provider %}
32
- {% when "custom" %}
33
- {% include custom/sharing %}
34
- {% endcase %}
35
-
36
- {% endif %}
@@ -1,7 +1,7 @@
1
1
  {% comment %}
2
2
  # -----------------------------------------------------------------------------
3
3
  # ~/_includes/themes/j1/modules/navigator/generator.html
4
- # Liquid HTML template to create the Navigation System for J1 Template
4
+ # Liquid HTML template to create the Navigation System for J1 Template
5
5
  #
6
6
  # Product/Info:
7
7
  # https://jekyll-one.com
@@ -58,6 +58,14 @@
58
58
  {% assign nav_authclient_default = nav_defaults.nav_authclient %}
59
59
  {% assign nav_authclient_config = navigator_config.nav_authclient %}
60
60
 
61
+ {% assign cookie_consent_config = site.data.modules.j1_cookie_consent %}
62
+ {% assign consent_defaults = cookie_consent_config.defaults %}
63
+ {% assign consent_settings = cookie_consent_config.consent %}
64
+
65
+ {% assign cookiebar_config_defaults = site.data.modules.j1_cookiebar.defaults %}
66
+ {% assign cookiebar_config = site.data.modules.j1_cookiebar.cookiebar %}
67
+
68
+
61
69
 
62
70
  {% comment %} Set config options
63
71
  ------------------------------------------------------------------------------ {% endcomment %}
@@ -66,7 +74,8 @@
66
74
  {% assign topsearch_options = nav_topsearch_default | merge: nav_topsearch_config %}
67
75
  {% assign sidebar_options = nav_sidebar_default | merge: nav_sidebar_config %}
68
76
  {% assign authclient_options = nav_authclient_default | merge: nav_authclient_config %}
69
-
77
+ {% assign cookie_consent_options = consent_defaults | merge: consent_settings %}
78
+
70
79
  {% comment %} Set navBarOptions
71
80
  ------------------------------------------------------------------------------ {% endcomment %}
72
81
  {% assign brand_position = nav_bar_options.brand_position %}
@@ -75,9 +84,8 @@
75
84
  {% assign nav_color = nav_bar_options.color %}
76
85
 
77
86
 
78
- {% comment %} Set navBarProperties
87
+ {% comment %} Set navBarProperties
79
88
  ------------------------------------------------------------------------------ {% endcomment %}
80
-
81
89
  {% if nav_fixed %}
82
90
  {% assign nav_bar_fixed = 'navbar-fixed' %}
83
91
  {% if nav_style == 'overlay' %} {% assign nav_bar_style = 'navbar-transparent' %} {% endif %}
@@ -91,7 +99,7 @@
91
99
  {% capture nav_bar_defaults %}navbar navigator navbar-expand-{{nav_expand}} navbar-default{% endcapture %}
92
100
 
93
101
 
94
- {% comment %} Main
102
+ {% comment %} Main
95
103
  -------------------------------------------------------------------------------- {% endcomment %}
96
104
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [check for topsearch] -->
97
105
  {% if topsearch_options.enabled %}
@@ -146,26 +154,23 @@
146
154
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [start processing: nav bar] -->
147
155
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [place nav menu container for AJAX load] -->
148
156
  <div id="{{menu_id}}" class="collapse"></div>
149
-
150
157
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [check for Quicklinks] -->
151
158
  <!-- [INFO ] [j1.modules.navigator.generator.html ] Quicklinks enabled: {{quicklinks_options.enabled}}] -->
152
159
  {% if quicklinks_options.enabled %}
153
160
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [start processing: quicklinks] -->
154
- {% include {{ quicklinks_create }} options=quicklinks_options auth_options=j1_auth_config %}
161
+ {% include {{ quicklinks_create }} options=quicklinks_options auth_options=j1_auth_config consent_options=cookie_consent_options %}
155
162
  {% endif %}
156
163
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [end processing: quicklinks] -->
157
164
 
158
165
  </nav>
159
166
 
160
-
161
- {% comment %} Place HTMl code for SignIn|SignOut dialogs for J1AuthClient
167
+ {% comment %} Place div container for sign in|out dialog used by J1AuthClient
162
168
  -------------------------------------------------------------------------------- {% endcomment %}
163
169
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [check for J1 AuthClient] -->
164
170
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [J1 AuthClient enabled: {{j1_auth_config.enabled}}] -->
165
- {% if j1_auth_config.enabled %}
166
- <!-- [INFO ] [j1.modules.navigator.generator.html ] [start processing: AuthClient] -->
167
171
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [place <div> container for the auth_client] -->
168
172
  <div id="{{authclient_modals_id}}" class="authclient_modals"></div>
169
- {% endif %}
170
173
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [end processing: auth_client] -->
171
174
  <!-- [INFO ] [j1.modules.navigator.generator.html ] [end processing: navigation] -->
175
+
176
+
@@ -1,7 +1,7 @@
1
1
  {% comment %}
2
2
  # -----------------------------------------------------------------------------
3
3
  # ~/_includes/templates/j1/modules/navigator/procedures/quicklinks.html
4
- # Liquid PROCEDURE template to create the quickLink bar
4
+ # Liquid PROCEDURE template to create the quickLink bar and place icons
5
5
  #
6
6
  # Product/Info:
7
7
  # https://jekyll-one.com
@@ -10,7 +10,6 @@
10
10
  #
11
11
  # J1 Template is licensed under the MIT License.
12
12
  # See: https://github.com/jekyll-one/j1_template_mde/blob/master/LICENSE
13
- #
14
13
  # -----------------------------------------------------------------------------
15
14
  # Test data:
16
15
  # liquid_var: {{ liquid_var | debug }}
@@ -22,6 +21,7 @@
22
21
  -------------------------------------------------------------------------------- {% endcomment %}
23
22
  {% assign quicklinks_options = include.options %}
24
23
  {% assign auth_options = include.auth_options %}
24
+ {% assign consent_settings = include.consent_options %}
25
25
 
26
26
  {% comment %} Liquid procedures
27
27
  -------------------------------------------------------------------------------- {% endcomment %}
@@ -34,37 +34,47 @@
34
34
 
35
35
  {% comment %} Set intial settings
36
36
  ------------------------------------------------------------------------------ {% endcomment %}
37
- {% assign top_search_enabled = false %}
38
- {% assign sidebar_enabled = false %}
39
- {% assign signin_modal_id = "modalOmniSignIn" %}
37
+ {% assign sidebar_enabled = false %}
38
+ {% assign top_search_enabled = false %}
39
+ {% assign cookie_consent_enabled = consent_settings.consent.enabled %}
40
+ {% assign authclient_enabled = auth_options.enabled %}
41
+ {% assign signin_modal_id = "modalOmniSignIn" %}
40
42
 
41
43
  {% comment %} Set quicklinks properties
42
44
  ------------------------------------------------------------------------------ {% endcomment %}
43
- {% assign icon_family = quicklinks_options.icon_family | downcase %}
44
-
45
- {% assign search_icon = quicklinks_options.top_search_icon %}
46
- {% assign sidebar_icon = quicklinks_options.sidebar_icon %}
47
-
48
- {% assign signin_icon = quicklinks_options.signin_icon %}
49
- {% assign signout_icon = quicklinks_options.signout_icon %}
50
- {% assign facebook_icon = quicklinks_options.facebook_icon %}
51
- {% assign github_icon = quicklinks_options.github_icon %}
52
- {% assign google_plus_icon = quicklinks_options.google_plus_icon %}
53
- {% assign twitter_icon = quicklinks_options.twitter_icon %}
45
+ {% assign icon_family = quicklinks_options.icon_family | downcase %}
46
+
47
+ {% assign cookies_icon = quicklinks_options.cookies_icon %}
48
+ {% assign search_icon = quicklinks_options.top_search_icon %}
49
+ {% assign sidebar_icon = quicklinks_options.sidebar_icon %}
50
+ {% assign signin_icon = quicklinks_options.signin_icon %}
51
+ {% assign signout_icon = quicklinks_options.signout_icon %}
52
+
53
+ {% assign disqus_icon = quicklinks_options.disqus_icon %}
54
+ {% assign github_icon = quicklinks_options.github_icon %}
55
+ {% assign patreon_icon = quicklinks_options.patreon_icon %}
56
+ {% assign facebook_icon = quicklinks_options.facebook_icon %}
57
+ {% assign twitter_icon = quicklinks_options.twitter_icon %}
54
58
 
55
- {% assign facebook_url = quicklinks_options.facebook_url %}
56
- {% assign github_url = quicklinks_options.github_url %}
57
- {% assign google_plus_url = quicklinks_options.google_plus_url %}
58
- {% assign twitter_url = quicklinks_options.twitter_url %}
59
+ {% assign disqus_url = quicklinks_options.google_plus_url %}
60
+ {% assign github_url = quicklinks_options.github_url %}
61
+ {% assign patreon_url = quicklinks_options.patreon_url %}
62
+ {% assign facebook_url = quicklinks_options.facebook_url %}
63
+ {% assign twitter_url = quicklinks_options.twitter_url %}
59
64
 
60
65
  {% comment %}
61
- auth_options.enabled: {{ auth_options.enabled | debug }}
66
+ authclient_enabled: {{ auth_options.enabled | debug }}
67
+ {% if consent_settings.consent.enabled %} {% assign consent_enabled = true %} {% endif %}
68
+ consent_settings: {{ consent_settings | debug }}
69
+ consent_enabled: {{ consent_enabled | debug }}
62
70
  {% endcomment %}
63
71
 
64
- <!-- [INFO ] [j1.modules.navigator.quicklinks.proc ] [J1 AuthManager detected as: {{ auth_options.enabled }}] -->
65
-
66
72
  {% if quicklinks_options.top_search_icon %} {% assign top_search_enabled = true %} {% endif %}
67
73
  {% if quicklinks_options.sidebar_icon %} {% assign sidebar_enabled = true %} {% endif %}
74
+ {% if consent_settings.enabled %} {% assign consent_enabled = true %} {% endif %}
75
+
76
+ <!-- [INFO ] [j1.modules.navigator.quicklinks.proc ] [J1 AuthManager detected as: {{ authclient_enabled }}] -->
77
+ <!-- [INFO ] [j1.modules.navigator.quicklinks.proc ] [J1 CookieConsent detected as: {{ consent_enabled }}] -->
68
78
 
69
79
  {% if quicklinks_options.icon_family == 'FontAwesome' or quicklinks_options.icon_family == 'FontAwesome4' or quicklinks_options.icon_family == 'FontAwesome5' %}
70
80
  {% assign icon_family = 'fa' %}
@@ -77,8 +87,6 @@
77
87
  {% include {{select_icon_size}} family=quicklinks_options.icon_family size=quicklinks_options.icon_size %}
78
88
  {% assign icon_size = {{size}} %}
79
89
 
80
-
81
-
82
90
  {% comment %} Icon color set dynamically by adapter
83
91
  ------------------------------------------------------------------------------
84
92
  {% include {{select_color}} color=quicklinks_options.icon_color fallback="#9E9E9E" %}
@@ -86,7 +94,6 @@
86
94
  {% capture icon_color %}style="color:{{my_icon_color}}"{% endcapture %}
87
95
  {% endcomment %}
88
96
 
89
-
90
97
  {% comment %} Main
91
98
  -------------------------------------------------------------------------------- {% endcomment %}
92
99
  <!-- [INFO ] [j1.modules.navigator.quicklinks.proc ] [start processing: quick links] -->
@@ -96,9 +103,12 @@
96
103
  {% if github_url != "none" %}<li nav-item><a class="nav-icon" href="{{github_url}}"><i class="{{icon_family}} {{icon_family}}-{{github_icon}} {{icon_size}}"></i></a></li>{% endif %}
97
104
  {% if google_plus_url != "none" %}<li nav-item><a class="nav-icon" href="{{google_plus_url}}"><i class="{{icon_family}} {{icon_family}}-{{google_plus_icon}} {{icon_size}}"></i></a></li>{% endif %}
98
105
  {% if twitter_url != "none" %}<li nav-item><a class="nav-icon" href="{{twitter_url}}"><i class="{{icon_family}} {{icon_family}}-{{twitter_icon}} {{icon_size}}"></i></a></li>{% endif %}
99
- {% if auth_options.enabled %}<li class="nav-item" id="quickLinksSignInOutButton"><a class="nav-icon" id="navLinkSignInOut" href="#" data-toggle="modal" data-target="#{{signin_modal_id}}"><i id="iconSignInOut" class="{{icon_family}} {{icon_family}}-{{signin_icon}} {{icon_size}}"></i></a></li>{% endif %}
106
+ {% if authclient_enabled %}<li class="nav-item" id="quickLinksSignInOutButton" style="display: none;"><a class="nav-icon" id="navLinkSignInOut" href="#" data-toggle="modal" data-target="#{{signin_modal_id}}"><i id="iconSignInOut" class="{{icon_family}} {{icon_family}}-{{signin_icon}} {{icon_size}}"></i></a></li>{% endif %}
107
+ {% if consent_enabled %}<li class="nav-item" id="quickLinksCookieButton" style="display: none;"><a id="cookie-state" class="nav-icon" href="#" data-toggle="modal" data-target="#cookieRevokeCentralDanger"><i class="{{icon_family}} {{icon_family}}-{{cookies_icon}} {{icon_size}}"></i></a></li>{% endif %}
100
108
  {% if top_search_enabled %}<li class="nav-item search"><a class="nav-icon" href="#"><i class="{{icon_family}} {{icon_family}}-{{search_icon}} {{icon_size}}"></i></a></li>{% endif %}
101
109
  {% if sidebar_enabled %}<li class="nav-item side-menu"><a class="nav-icon" href="#"><i class="{{icon_family}} {{icon_family}}-{{sidebar_icon}} {{icon_size}}"></i></a></li>{% endif %}
102
110
  </ul>
103
111
  </div>
104
112
  <!-- [INFO ] [j1.modules.navigator.quicklinks.proc ] [end processing: quick links] -->
113
+
114
+
@@ -98,9 +98,9 @@
98
98
  {% else %}
99
99
  {% capture icon %}<i class="{{icon_family}} {{icon_family}}-{{link.icon}} {{icon_size}} mr-2" {{icon_color}}></i>{% endcapture %}
100
100
  {% endif %}
101
-
102
- {% if link.target == null %}
103
- {% assign target = '' %}
101
+
102
+ {% if link.target == "" %}
103
+ {% assign target = "" %}
104
104
  {% else %}
105
105
  {% capture target %}target="{{link.target}}"{% endcapture %}
106
106
  {% endif %}
@@ -111,7 +111,7 @@
111
111
  <script>
112
112
  $(document).ready(function() {
113
113
  // [INFO ] [j1.layout.module_writer.proc ] [create logger for component "loader"]
114
- var logger = log4javascript.getLogger("j1.loader");
114
+ var logger = log4javascript.getLogger("j1.ModuleLoader.liquid");
115
115
 
116
116
  {% if environment == 'development' %}
117
117
  // [INFO ] [j1.layout.module_writer.proc ] [create module loader START message]
@@ -119,10 +119,10 @@
119
119
  var start = moment();
120
120
  var finished = '';
121
121
  var elapsed = '';
122
- var log_text = "[" +start.format("HH:mm:ss.SSS")+ "] [INFO ] [j1.loader ] [{{comment | replace: 'Resources for', '' | strip }} is being initialized]"
122
+ var log_text = "[" +start.format("HH:mm:ss.SSS")+ "] [INFO ] [j1.ModuleLoader ] [{{comment | replace: 'Resources for', '' | strip }} are being initialized]"
123
123
  console.info( log_text );
124
124
  {% else %}
125
- var log_text = "{{comment | replace: 'Resources for', '' | strip }} is being initialized"
125
+ var log_text = "{{comment | replace: 'Resources for', '' | strip }} are being initialized"
126
126
  logger.info(log_text);
127
127
  {% endif %}
128
128
  {% endif %}
@@ -158,7 +158,7 @@
158
158
  // [INFO ] [j1.layout.module_writer.proc ] [create module loader FINISHED message]
159
159
  {% if id == 'log4javascript' %}
160
160
  finished = moment();
161
- log_text = "[" +finished.format("HH:mm:ss.SSS")+ "] [INFO ] [j1.loader ] [{{comment | replace: 'Resources for', '' | strip }} initializing finished]"
161
+ log_text = "[" +finished.format("HH:mm:ss.SSS")+ "] [INFO ] [j1.ModuleLoader ] [{{comment | replace: 'Resources for', '' | strip }} initializing finished]"
162
162
  console.info( log_text );
163
163
  {% else %}
164
164
  var log_text = "{{comment | replace: 'Resources for', '' | strip }} initializing finished"
@@ -88,8 +88,8 @@
88
88
 
89
89
  {% if data_key == 'files' %}
90
90
 
91
- <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: {{comment}}] -->
92
- <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: place general file resources for ID: {{id}} ] -->
91
+ <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: {{comment}}] -->
92
+ <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: place general file resources for ID: {{id}} ] -->
93
93
 
94
94
  {% for file in data_value %}
95
95
 
@@ -138,8 +138,8 @@
138
138
  {% if data_key == 'css' %}
139
139
  {% for locator in data_value %}
140
140
 
141
- <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: {{comment}}] -->
142
- <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: place {{data_key}} files for resource ID: {{id}} ] -->
141
+ <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: {{comment}}] -->
142
+ <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: place {{data_key}} files for resource ID: {{id}} ] -->
143
143
 
144
144
  {% include {{select_location}} location=location locator=locator %}
145
145
  {% assign my_location = {{location_source}} %}
@@ -158,8 +158,8 @@
158
158
  {% if data_key == 'js' %}
159
159
  {% for locator in data_value %}
160
160
 
161
- <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: {{comment}}] -->
162
- <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: place {{data_key}} files for resource ID: {{id}} ] -->
161
+ <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: {{comment}}] -->
162
+ <!-- [INFO ] [j1.layout.resource_writer.proc ] [{{layout}}: place {{data_key}} files for resource ID: {{id}} ] -->
163
163
 
164
164
  {% include {{select_location}} location=location locator=locator %}
165
165
  {% assign my_location = {{location_source}} %}
data/lib/j1/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module J1
2
- VERSION = '2018.4.31'
2
+ VERSION = '2018.4.32'
3
3
  end
@@ -0,0 +1,1267 @@
1
+ # RuboCops - Documentation
2
+ # ------------------------------------------------------------------------------
3
+ # See: https://rubocop.readthedocs.io/en/latest/
4
+
5
+ # RuboCops - Disabled Cops
6
+ # ------------------------------------------------------------------------------
7
+ # rubocop:disable Metrics/BlockLength
8
+ # rubocop:disable Metrics/ClassLength
9
+ # rubocop:disable Metrics/LineLength
10
+ # rubocop:disable Style/StringLiterals
11
+ # rubocop:disable Style/Documentation
12
+ # rubocop:disable Metrics/BlockNesting
13
+ # rubocop:disable Layout/ClosingParenthesisIndentation
14
+ # rubocop:disable Layout/LeadingCommentSpace
15
+ # rubocop:disable Layout/EmptyLines
16
+ # rubocop:disable Layout/EmptyLinesAroundBlockBody
17
+ # rubocop:disable Layout/FirstParameterIndentation
18
+ # rubocop:disable Layout/CommentIndentation
19
+ # rubocop:disable Layout/AlignParameters
20
+ # rubocop:disable Layout/AlignHash
21
+ # rubocop:disable Layout/TrailingWhitespace
22
+ # rubocop:disable Layout/IndentHash
23
+ # rubocop:disable Layout/SpaceAroundOperators
24
+ # rubocop:disable Layout/ExtraSpacing
25
+ # rubocop:disable Style/UnlessElse
26
+ # rubocop:disable Style/HashSyntax
27
+
28
+
29
+ # ------------------------------------------------------------------------------
30
+ # ~/lib/j1_auth_manager/auth_manager/.rb
31
+ #
32
+ # Provides authentication services based on Warden|OmniAuth
33
+ #
34
+ # Product/Info:
35
+ # https://jekyll-one.com
36
+ #
37
+ # Copyright (C) 2019 Juergen Adams
38
+ #
39
+ # J1 Template is licensed under the MIT License.
40
+ # See: https://github.com/jekyll-one/j1_template_mde/blob/master/LICENSE
41
+ #
42
+ # ------------------------------------------------------------------------------
43
+ # NOTES
44
+ #
45
+ # ------------------------------------------------------------------------------
46
+ # frozen_string_literal: true
47
+
48
+ module J1App
49
+ class AuthManager < Sinatra::Base
50
+
51
+ include J1App::Helpers
52
+ include J1App::GithubHelpers
53
+
54
+ # ==========================================================================
55
+ # Sinatra Framework settings
56
+ # ==========================================================================
57
+
58
+ # NOTE: https://stackoverflow.com/questions/7847536/sinatra-in-facebook-iframe
59
+ #
60
+ #set :protection, :except => :frame_options
61
+
62
+ # Check: http://sinatrarb.com/intro.html
63
+ #
64
+ #set :static_cache_control, [:public, :max_age => 10]
65
+
66
+
67
+ # ==========================================================================
68
+ # Base App and Warden Framework settings
69
+ # ==========================================================================
70
+
71
+ # j1_web_session = {
72
+ # :authenticated => 'false',
73
+ # :requested_page => '/',
74
+ # :user_name => 'unknown',
75
+ # :users_allowed => 'unknown',
76
+ # :user_id => 'unknown',
77
+ # :provider => 'unknown',
78
+ # :provider_url => '/',
79
+ # :payment_info => 'unknown',
80
+ # :permissions => 'unknown',
81
+ # :writer => 'middleware'
82
+ # }
83
+
84
+ j1_web_session = {
85
+ :authenticated => 'false',
86
+ :requested_page => '/',
87
+ :user_name => 'visitor',
88
+ :users_allowed => 'all',
89
+ :user_id => 'unknown',
90
+ :provider => 'j1',
91
+ :provider_membership => 'guest',
92
+ :provider_url => 'https://jekyll.one',
93
+ :payment_info => 'unknown',
94
+ :provider_permissions => 'public',
95
+ :writer => 'middleware'
96
+ }
97
+
98
+ # Enable SSL for the rack session if configured
99
+ # --------------------------------------------------------------------------
100
+ require 'rack-ssl-enforcer' if J1App.ssl?
101
+ use Rack::SslEnforcer if J1App.ssl?
102
+
103
+ # Set the session cookie used by Rack to track all relevant data
104
+ # for the authentication service
105
+ # --------------------------------------------------------------------------
106
+ use Rack::Session::Cookie,
107
+ http_only: true, # if set to 'true', make session cookie visible to the browser (document) for HTTP
108
+ key: 'j1.app.session',
109
+ secret: ENV['J1_SESSION_SECRET'] || SecureRandom.hex
110
+
111
+ # use Rack::Cache do |config|
112
+ # #
113
+ # # ------------------------------------------------------------------------
114
+ # config.middleware.delete(Rack::Cache)
115
+ # end
116
+
117
+ # ==========================================================================
118
+ # Warden Framework initialisation
119
+ # ==========================================================================
120
+
121
+ # Define what (user) data should be put (serialized) into the session
122
+ # on requests and responses from Rack environment into the warden
123
+ # environment (env['warden']).
124
+ # --------------------------------------------------------------------------
125
+ Warden::Manager.serialize_into_session do |user|
126
+ user
127
+ end
128
+ Warden::Manager.serialize_from_session do |user|
129
+ user
130
+ end
131
+
132
+
133
+ # ==========================================================================
134
+ # OmniAuth|Warden Framework initialisation
135
+ # ==========================================================================
136
+
137
+ # Set the 'default' authentication strategy and exception handler
138
+ # (for warden) if the user was not explicitly signed in (signin dialog).
139
+ # If 'signin' fails, the default exception 'signin_failure' is thrown
140
+ # (used for all OmniAuth strategies registered).
141
+ # --------------------------------------------------------------------------
142
+ signin_failure = ->(_e) { Rack::Response.new("Can't login", 401).finish }
143
+ use Warden::Manager do |config|
144
+ # OmniAuth strategies are name-spaced by 'omni' (see: warden_omniauth.rb)
145
+ # ------------------------------------------------------------------------
146
+ config.default_strategies :"omni_#{J1App.default_provider}"
147
+ config.failure_app = signin_failure
148
+ end
149
+
150
+ use OmniAuth::Builder do |config|
151
+ # Workaround to rescue OmniAuth::Strategies::OAuth2::CallbackError?
152
+ # for chromium based browsers (e.g. google-chrome)
153
+ # ------------------------------------------------------------------------
154
+ config.on_failure do
155
+ new_path = '/redirect_requested_page'
156
+ Rack::Response.new(['302 Moved'], 302, 'Location' => new_path).finish
157
+ end
158
+
159
+ # Detect and set supported authentication strategies for OmniAuth
160
+ # ------------------------------------------------------------------------
161
+
162
+ # Additional (strategy) option skip_extra, default: true
163
+ #
164
+ # If true, skips the collection of raw data (extra) to NOT blow
165
+ # up the session cookie (as it is limited to 4K)
166
+ skip_extra = true
167
+
168
+ if J1App.active_providers.include? 'patreon'
169
+ scope = J1App.auth_config['providers']['patreon']['scope'].join(',')
170
+ data_collection = J1App.auth_config['providers']['patreon']['data_fields'].join(',')
171
+ skip_extra = false if data_collection =~ /raw/i
172
+ provider :patreon,
173
+ ENV['PATREON_CLIENT_ID'],
174
+ ENV['PATREON_CLIENT_SECRET'],
175
+ scope: "#{scope}",
176
+ skip_extra: skip_extra
177
+ end
178
+ if J1App.active_providers.include? 'disqus'
179
+ scope = J1App.auth_config['providers']['disqus']['scope'].join(',')
180
+ data_collection = J1App.auth_config['providers']['disqus']['data_fields'].join(',')
181
+ skip_extra = false if data_collection =~ /raw/i
182
+ provider :disqus,
183
+ ENV['DISQUS_CLIENT_ID'],
184
+ ENV['DISQUS_CLIENT_SECRET'],
185
+ scope: "#{scope}",
186
+ skip_extra: skip_extra
187
+ end
188
+ if J1App.active_providers.include? 'facebook'
189
+ scope = J1App.auth_config['providers']['facebook']['scope'].join(',')
190
+ data_collection = J1App.auth_config['providers']['facebook']['data_fields'].join(',')
191
+ skip_extra = false if data_collection =~ /raw/i
192
+ provider :facebook,
193
+ ENV['FACEBOOK_CLIENT_ID'],
194
+ ENV['FACEBOOK_CLIENT_SECRET'],
195
+ scope: "#{scope}",
196
+ skip_extra: skip_extra
197
+ end
198
+ if J1App.active_providers.include? 'github'
199
+ scope = J1App.auth_config['providers']['github']['scope'].join(',')
200
+ data_collection = J1App.auth_config['providers']['github']['data_fields'].join(',')
201
+ skip_extra = false if data_collection =~ /raw/i
202
+ provider :github,
203
+ ENV['GITHUB_CLIENT_ID'],
204
+ ENV['GITHUB_CLIENT_SECRET'],
205
+ scope: "#{scope}",
206
+ skip_extra: skip_extra
207
+ end
208
+ if J1App.active_providers.include? 'twitter'
209
+ scope = J1App.auth_config['providers']['twitter']['scope'].join(',')
210
+ data_collection = J1App.auth_config['providers']['twitter']['data_fields'].join(',')
211
+ skip_extra = false if data_collection =~ /raw/i
212
+ provider :twitter,
213
+ ENV['TWITTER_CLIENT_ID'],
214
+ ENV['TWITTER_CLIENT_SECRET'],
215
+ scope: "#{scope}",
216
+ skip_extra: skip_extra
217
+ end
218
+ end
219
+
220
+ # Set the (internal) endpoint if a user is successfully authenticated
221
+ # --------------------------------------------------------------------------
222
+ use J1WardenOmniAuth do |config|
223
+ config.redirect_after_callback = '/post_authentication'
224
+ end
225
+
226
+ # Add the internal logger from Rack to the middleware's of the stack
227
+ # --------------------------------------------------------------------------
228
+ use Rack::Logger
229
+
230
+ # Load user profiles, permissions, conditions and strategies
231
+ # --------------------------------------------------------------------------
232
+
233
+ providers = J1App.auth_config['providers']
234
+ permissions = J1App.permissions
235
+
236
+
237
+ # ==========================================================================
238
+ # Sinatra (before) FILTER to preprocess all page requests
239
+ # ==========================================================================
240
+
241
+ # Prepare root (index) page for app detection
242
+ #
243
+ before '/' do
244
+ log_info! "ROOT", "Prepare", 'Web Session'
245
+
246
+ # read existing/current cookie 'j1.web.session' to update all data
247
+ # of j1_web_session (hash) otherwise set initial data
248
+ # ------------------------------------------------------------------------
249
+ unless env['HTTP_COOKIE'] == nil
250
+ if env['HTTP_COOKIE'].include? 'j1.web.session'
251
+ session_encoded = request.cookies['j1.web.session']
252
+ session_decoded = Base64.decode64(session_encoded)
253
+ j1_web_session = JSON.parse(session_decoded)
254
+ end
255
+ else
256
+ requested_page = env['REQUEST_URI']
257
+ j1_web_session['requested_page'] = "#{env['REQUEST_URI']}"
258
+ end
259
+
260
+ # Create|Initialize the J1 web session cookie
261
+ # ------------------------------------------------------------------------
262
+ if warden.authenticated?
263
+ log_info! "ROOT", 'Cookie', 'Update current user data'
264
+
265
+ user = warden.user
266
+ log_info! "ROOT", 'AuthCheck', 'User detected as signed in', "#{user[:provider]}"
267
+ j1_web_session['authenticated'] = 'true'
268
+ j1_web_session['requested_page'] = '/'
269
+ j1_web_session['users_allowed'] = providers["#{user[:provider]}"]['users']
270
+ j1_web_session['user_name'] = user[:info]['nickname']
271
+ j1_web_session['user_id'] = user[:uid]
272
+ j1_web_session['provider'] = user[:provider]
273
+ j1_web_session['provider_membership'] = 'member'
274
+ j1_web_session['provider_url'] = providers["#{user[:provider]}"]['provider_url']
275
+ j1_web_session['provider_permissions'] = providers["#{user[:provider]}"]['permissions']
276
+ j1_web_session['payment_status'] = user[:info][:payment_status]
277
+ else
278
+ log_info! "ROOT", 'AuthCheck', 'User detected', 'signed out'
279
+ j1_web_session['authenticated'] = 'false'
280
+ j1_web_session['requested_page'] = '/'
281
+ j1_web_session['users_allowed'] = 'all'
282
+ j1_web_session['user_name'] = 'visitor'
283
+ j1_web_session['user_id'] = 'unknown'
284
+ j1_web_session['payment_status'] = 'unknown'
285
+ j1_web_session['provider'] = 'j1'
286
+ j1_web_session['provider_membership'] = 'guest'
287
+ j1_web_session['provider_url'] = 'https://jekyll.one'
288
+ j1_web_session['provider_permissions'] = 'public'
289
+ end
290
+ j1_web_session['writer'] = 'middleware'
291
+
292
+ session_json = j1_web_session.to_json
293
+ log_info! "ROOT", 'Cookie', 'Update web session data', "#{session_json}"
294
+
295
+ session_encoded = Base64.encode64(session_json)
296
+ response.set_cookie(
297
+ 'j1.web.session',
298
+ domain: false,
299
+ value: session_encoded.to_s,
300
+ path: '/'
301
+ )
302
+ end
303
+
304
+ # General page detection (page auth pre-flight)
305
+ # --------------------------------------------------------------------------
306
+ before '/(pages|posts)/*' do
307
+
308
+ log_info! 'AuthManager', 'PreFlight', 'Initial checks initiated'
309
+
310
+ # read existing/current cookie 'j1.web.session'
311
+ # to update all data of j1_web_session (hash)
312
+ # if request.warden.user.respond_to?(:info)
313
+ # ------------------------------------------------------------------------
314
+ if env['HTTP_COOKIE'].include? 'j1.web.session'
315
+ session_encoded = request.cookies['j1.web.session']
316
+ session_decoded = Base64.decode64(session_encoded)
317
+ j1_web_session = JSON.parse(session_decoded)
318
+
319
+ log_info! 'PreFlight', 'Cookie', 'Read web session data' # "#{session_decoded}"
320
+ else
321
+ requested_page = env['REQUEST_URI']
322
+ j1_web_session['requested_page'] = "#{env['REQUEST_URI']}"
323
+ end
324
+
325
+ # Create|Initialize the J1 web session cookie
326
+ # ------------------------------------------------------------------------
327
+ log_info! 'PreFlight', 'AuthCheck', 'Check authentication status'
328
+ if warden.authenticated?
329
+ user = warden.user
330
+ j1_web_session['authenticated'] = 'true'
331
+ j1_web_session['user_name'] = user[:info]['nickname']
332
+ j1_web_session['user_id'] = user[:uid]
333
+ j1_web_session['provider'] = user[:provider]
334
+ j1_web_session['provider_url'] = providers["#{user[:provider]}"]['provider_url']
335
+ j1_web_session['users_allowed'] = providers["#{user[:provider]}"]['users']#
336
+ j1_web_session['provider_permissions'] = providers["#{user[:provider]}"]['permissions']
337
+ j1_web_session['payment_status'] = user[:info][:payment_status]
338
+ j1_web_session['writer'] = 'middleware'
339
+
340
+ log_info! 'PreFlight', 'AuthCheck', 'User authenticated', "#{user[:info]['nickname']}"
341
+
342
+ session_json = j1_web_session.to_json
343
+ log_info! 'PreFlight', 'Cookie', 'Write web session data', "#{session_json}"
344
+
345
+ session_encoded = Base64.encode64(session_json)
346
+ response.set_cookie(
347
+ 'j1.web.session',
348
+ domain: false,
349
+ value: session_encoded.to_s,
350
+ path: '/'
351
+ )
352
+ end
353
+
354
+ # User state|content detection for implicit authentication
355
+ # ------------------------------------------------------------------------
356
+ log_info! 'PreFlight', 'CheckConfig', 'Authentication check', 'disabled' if authentication_enabled? == false
357
+ log_info! 'PreFlight', 'AuthCheck', 'Pass for all pages' if authentication_enabled? == false
358
+ pass if authentication_enabled? == false
359
+
360
+ log_info! 'PreFlight', 'CheckConfig', 'Authentication check', 'enabled'
361
+ log_info! 'PreFlight', 'DetectContent', 'Public content', 'YES' if public_content?
362
+ log_info! 'PreFlight', 'DetectContent', 'Pass all public content' if public_content?
363
+ pass if public_content?
364
+
365
+ log_info! 'PreFlight', 'DetectCookieConsent', 'Cookie Consent', "#{j1_web_session['cookies_accepted']}"
366
+
367
+ if j1_web_session['cookies_accepted'] === 'declined'
368
+ requested_page = env['REQUEST_URI']
369
+ requested_page.scan(/(protected|private)/) do |match|
370
+ category = match[0]
371
+ log_info! 'PreFlight', 'Redirect', 'Pass to dialog page (Cookie Consent)'
372
+ description_title = "Cookie consent declined"
373
+ redirect "/cookie_consent?provider=#{j1_web_session['provider']}&user=#{j1_web_session['user_name']}&category=#{category}&requested_page=#{requested_page}&title=#{description_title}"
374
+ end
375
+ end
376
+
377
+ log_info! 'PreFlight', 'DetectContent', 'Check content type'
378
+
379
+ requested_page = env['REQUEST_URI']
380
+ requested_page.scan(/(protected|private)/) do |match|
381
+
382
+ category = match[0]
383
+ log_info! 'PreFlight', 'DetectContent', 'Content type detected', "#{category}"
384
+
385
+ log_info! 'PreFlight', 'AuthCheck', 'Check authorisation status'
386
+ if warden.authenticated?
387
+ user_name = user[:info]['nickname']
388
+ log_info! 'PreFlight', 'AuthCheck', 'User detected', "#{user_name}"
389
+
390
+ current_provider = warden.user[:provider]
391
+
392
+ # provider_strategy = strategies["#{default_provider}"]
393
+ strategy = providers["#{current_provider}"]['strategy']
394
+ provider_strategy = :"#{strategy}"
395
+
396
+ j1_web_session['user_name'] = user_name
397
+ j1_web_session['provider_url'] = providers["#{current_provider}"]['provider_url']
398
+ j1_web_session['users_allowed'] = providers["#{current_provider}"]['users']
399
+ j1_web_session['provider_permissions'] = providers["#{user[:provider]}"]['permissions']
400
+ j1_web_session['requested_page'] = requested_page
401
+
402
+ log_info! 'PreFlight', 'ContentCheck', 'Check permissions'
403
+ if permissions[:"#{category}"].include? current_provider
404
+ log_info! 'PreFlight', 'ContentCheck', 'Provider detected', "#{current_provider}"
405
+ log_info! 'PreFlight', 'ContentCheck', 'Category detected', "#{category}"
406
+ log_info! 'PreFlight', 'ContentCheck', 'Category support', 'enabled'
407
+
408
+ # Check permissions
409
+ #
410
+ #log_info! 'Authorisation', 'ConditionCheck', 'Check permissions for provider', "#{current_provider}"
411
+ #conditions = J1App.conditions current_provider
412
+ # if conditions["#{category}"]
413
+ # log_info! 'Authorisation', 'ConditionCheck', 'Conditions detected', "#{category}"
414
+ # conditions["#{category}"].each do |k, v|
415
+ # case k
416
+ # when 'enabled'
417
+ # log_info! 'Authorisation', 'ConditionCheck', "#{k}", "#{v}"
418
+ # when 'users'
419
+ # log_info! 'Authorisation', 'ConditionCheck', 'users'
420
+ # v.each do |k, v|
421
+ # log_info! 'Authorisation', 'ConditionCheck', "users - #{k}", "#{v}"
422
+ # end
423
+ # when 'payment'
424
+ # log_info! 'Authorisation', 'ConditionCheck', 'payment'
425
+ # v.each do |k, v|
426
+ # case k
427
+ # when 'tiers'
428
+ # log_info! 'Authorisation', 'ConditionCheck', "payment - #{k}", "#{v}"
429
+ # when 'tier'
430
+ # v.each do |k, v|
431
+ # log_info! 'Authorisation', 'ConditionCheck', 'payment - tiers - tier : ' "#{k}", "#{v}"
432
+ # end
433
+ # end
434
+ # end
435
+ # end
436
+ # end
437
+ # end
438
+ else
439
+ provider = permissions[:"#{category}"][0]
440
+ log_info! 'PreFlight', 'ContentCheck', 'Provider detected', "#{current_provider}"
441
+ log_info! 'PreFlight', 'ContentCheck', 'Category detected', "#{category}"
442
+ log_info! 'PreFlight', 'ContentCheck', 'Category supported', 'NO'
443
+ log_info! 'PreFlight', 'AuthCheck', 'Authorisation failed for user', "#{user_name}"
444
+
445
+ log_info! 'PreFlight', 'SignOut', 'Sign out user', "#{user_name}"
446
+ warden.logout
447
+ session.clear
448
+
449
+ session_json = j1_web_session.to_json
450
+ log_info! 'PreFlight', 'Cookie', 'Write web session data', "#{session_json}"
451
+
452
+ session_encoded = Base64.encode64(session_json)
453
+ response.set_cookie(
454
+ 'j1.web.session',
455
+ domain: false,
456
+ value: session_encoded.to_s,
457
+ path: '/'
458
+ )
459
+
460
+ log_info! 'PreFlight', 'Redirect', 'Call API request', 'PageValidate'
461
+ allowed_users = providers["#{provider}"]['users'].join(',')
462
+ redirect "/page_validation?provider=#{provider}&category=#{category}&page=#{requested_page}&allowed_users=#{allowed_users}"
463
+ end
464
+
465
+ time = Time.now.ctime.to_s
466
+ log_info! 'PreFlight', 'AuthCheck', 'Pass to requested page', "#{requested_page}"
467
+ log_info! 'PreFlight', 'AuthCheck', 'Set X-Response-Headers'
468
+
469
+ # See: https://stackoverflow.com/questions/10438276/how-to-disable-static-file-caching-in-rails-3-thin-on-windows
470
+ # response.headers["Cache-Control"] = 'no-cache, no-store, max-age=0, must-revalidate'
471
+ # response.headers["Pragma"] = 'no-cache'
472
+ # response.headers["Expires"] = 'Fri, 01 Jan 1990 00:00:00 GMT'
473
+ response.headers['X-J1-AuthManager'] = "page-validated;category=#{category};called=" + time
474
+ pass
475
+ else
476
+ log_info! 'PreFlight', 'AuthCheck', 'User detected', 'signed out'
477
+ default_provider = permissions[:"#{category}"][0]
478
+ log_info! 'PreFlight', 'AuthCheck', 'Set default provider', "#{default_provider}"
479
+
480
+ strategy = providers["#{default_provider}"]['strategy']
481
+ provider_strategy = :"#{strategy}"
482
+
483
+ log_info! 'PreFlight', 'AuthCheck', 'Start processing provider', "#{default_provider}"
484
+ log_info! 'PreFlight', 'AuthCheck', 'Authentication strategy', "#{provider_strategy}"
485
+
486
+ case provider_strategy
487
+
488
+ when :org
489
+ warden.authenticate!
490
+ github_organization_authenticate! ENV['GITHUB_ORG_NAME']
491
+ logger.info "Hi There, #{j1_web_session[:user_name]}! You have access to the #{params['id']} organization"
492
+
493
+ when :team
494
+ warden.authenticate!
495
+ github_team_authenticate! ENV['GITHUB_TEAM_ID']
496
+ logger.info "Hi There, #{j1_web_session[:user_name]}! You have access to the #{params['id']} team"
497
+
498
+ when :teams
499
+ warden.authenticate!
500
+ github_teams_authenticate! ENV['GITHUB_TEAM_IDS'].split(',')
501
+ logger.info "Hi There, #{j1_web_session[:user_name]}! You have access to the #{params['id']} team"
502
+
503
+ when :member
504
+ log_info! 'PreFlight', 'AuthCheck', 'Process authentication strategy'
505
+
506
+ if env['HTTP_COOKIE'].include? 'j1.web.session'
507
+ session_encoded = request.cookies['j1.web.session']
508
+ session_decoded = Base64.decode64(session_encoded)
509
+ log_info! 'PreFlight', 'Cookie', 'Read web session data' # "#{session_decoded}"
510
+ j1_web_session = JSON.parse(session_decoded)
511
+ end
512
+
513
+ # Update cookie data
514
+ # ----------------------------------------------------------------------
515
+ j1_web_session['provider_url'] = providers["#{default_provider}"]['provider_url']
516
+ j1_web_session['users_allowed'] = providers["#{default_provider}"]['users']
517
+ j1_web_session['provider_permissions'] = providers["#{default_provider}"]['permissions']
518
+ j1_web_session['requested_page'] = env['REQUEST_URI']
519
+ j1_web_session['writer'] = 'middleware'
520
+
521
+ # write updated J1 session cookie
522
+ #
523
+ session_json = j1_web_session.to_json
524
+ session_encoded = Base64.encode64(session_json)
525
+ log_info! 'PreFlight', 'Cookie', 'Write web session data', "#{session_json}"
526
+
527
+ response.set_cookie(
528
+ 'j1.web.session',
529
+ domain: false,
530
+ value: session_encoded.to_s,
531
+ path: '/'
532
+ )
533
+
534
+ allowed_users = providers["#{default_provider}"]['users'].join(',')
535
+ requested_page = env['REQUEST_URI']
536
+
537
+ log_info! 'PreFlight', 'Redirect', 'Call API request', 'PageValidate'
538
+ redirect "/page_validation?provider=#{default_provider}&category=#{category}&page=#{requested_page}&allowed_users=#{allowed_users}"
539
+ else
540
+ raise J1App::ConfigError
541
+ end
542
+
543
+ end
544
+ end
545
+ end
546
+
547
+
548
+ # ==========================================================================
549
+ # API ENDPOINTS (Sinatra HANDLERS)
550
+ # ==========================================================================
551
+
552
+ # ENDPOINT authentication (called from WEB by auth client)
553
+ # --------------------------------------------------------------------------
554
+ get '/authentication' do
555
+ # collect (common) GET parameter|s
556
+ #
557
+ request = params.fetch('request')
558
+ provider = params.fetch('provider')
559
+
560
+ log_info! 'API', 'Authentication', 'Authentication request received'
561
+
562
+ # SignIn
563
+ # ------------------------------------------------------------------------
564
+ if request === 'signin'
565
+
566
+ log_info! 'Authentication', 'SignIn', 'Called for provider', "#{provider}"
567
+
568
+ # collect (additional) GET parameter|s
569
+ # ----------------------------------------------------------------------
570
+ allowed_users = params.fetch('allowed_users')
571
+
572
+ j1_web_session['users_allowed'] = allowed_users
573
+ j1_web_session['writer'] = 'middleware'
574
+
575
+ # Write updated J1 session data to cookie
576
+ # --------------------------------------------------------------------
577
+ session_json = j1_web_session.to_json
578
+ log_info! 'Authentication', 'Cookie', 'Write web session data', "#{session_json}"
579
+
580
+ session_encoded = Base64.encode64(session_json)
581
+ response.set_cookie(
582
+ 'j1.web.session',
583
+ domain: false,
584
+ value: session_encoded.to_s,
585
+ path: '/'
586
+ )
587
+
588
+ if warden.authenticated?
589
+ log_info! 'Authentication', 'SignIn', 'User already signed in', "#{warden.user[:info]['nickname']} "
590
+ else
591
+ log_info! 'Authentication', 'SignIn', 'Initiate OmniAuth authentication'
592
+
593
+ # Make (really) sure that old session is cleared before login
594
+ # --------------------------------------------------------------------
595
+ warden.logout
596
+ session.clear
597
+ warden.authenticate! :"omni_#{provider}"
598
+ end
599
+ # SignOut
600
+ # ------------------------------------------------------------------------
601
+ elsif request === 'signout'
602
+ # collect (additional) GET parameter|s
603
+ provider_signout = params.fetch('provider_signout')
604
+ log_info! 'Authentication', 'SignOut', 'Called for provider', #{provider}"
605
+
606
+ if warden.authenticated?
607
+ user = warden.user[:info]['nickname']
608
+ provider = warden.user[:provider]
609
+ provider_url = j1_web_session['provider_url']
610
+ log_info! 'Authentication', 'SignOut', 'Sign out user', "#{user}"
611
+ warden.logout
612
+ session.clear
613
+
614
+ # Read current J1 web session cookie
615
+ # --------------------------------------------------------------------
616
+ if env['HTTP_COOKIE'].include? 'j1.web.session'
617
+ session_encoded = env['rack.request.cookie_hash']['j1.web.session']
618
+ session_decoded = Base64.decode64(session_encoded)
619
+ log_info! 'Authentication', 'Cookie', 'Read web session data' # #{session_decoded}"
620
+ j1_web_session = JSON.parse(session_decoded)
621
+ else
622
+ j1_web_session['requested_page'] = env['REQUEST_URI']
623
+ end
624
+
625
+ # Update J1 web session data
626
+ # --------------------------------------------------------------------
627
+ j1_web_session['user_name'] = 'visitor'
628
+ j1_web_session['user_id'] = 'unknown'
629
+ j1_web_session['users_allowed'] = 'all'
630
+ j1_web_session['payment_status'] = 'unknown'
631
+ j1_web_session['provider'] = 'j1'
632
+ j1_web_session['provider_url'] = 'https://jekyll.one'
633
+ j1_web_session['provider_permissions'] = 'public'
634
+ j1_web_session['authenticated'] = 'false'
635
+ j1_web_session['writer'] = 'middleware'
636
+
637
+ # Write updated J1 session data to cookie
638
+ # --------------------------------------------------------------------
639
+ session_json = j1_web_session.to_json
640
+ log_info! 'Authentication', 'Cookie', 'Write web session data', "#{session_json}"
641
+
642
+ session_encoded = Base64.encode64(session_json)
643
+ response.set_cookie(
644
+ 'j1.web.session',
645
+ domain: false,
646
+ value: session_encoded.to_s,
647
+ path: '/'
648
+ )
649
+
650
+ if provider_signout === 'true'
651
+ log_info! 'Authentication', 'SignOut', 'Sign out user', "#{user}"
652
+ log_info! 'Authentication', 'SignOut', 'Sign out from', "#{provider}"
653
+ log_info! 'Authentication', 'Redirect', 'Pass to provider', "#{provider_url}"
654
+ redirect "#{provider_url}"
655
+ else
656
+ log_info! 'Authentication', 'SignOut', 'Sign out user', "#{user}"
657
+ log_info! 'Authentication', 'SignOut', 'Sign out from', "session"
658
+
659
+ # If signed out, redirect ONLY for PUBLIC pages
660
+ # ------------------------------------------------------------------
661
+ if redirect_whitelisted?j1_web_session['requested_page']
662
+ log_info! 'Authentication', 'Redirect', 'Pass to page', "#{j1_web_session['requested_page']}"
663
+ redirect j1_web_session['requested_page']
664
+ else
665
+ log_info! 'Authentication', 'Redirect', 'Redirect NOT whitelisted'
666
+ log_info! 'Authentication', 'Redirect', 'Pass to page', "/"
667
+ redirect '/'
668
+ end
669
+ end
670
+ else
671
+ # THIS condition should NEVER REACHED because NO logout dialog
672
+ # (modal) is provided by the auth client if a user isn't signed in.
673
+ # Kept this alternative for cases something went wrong.
674
+ # --------------------------------------------------------------------
675
+ log_info! 'Authentication', 'API', 'DEAD PATH: Called for sign out', 'NOT signed in'
676
+
677
+ # Read current J1 session cookie
678
+ # --------------------------------------------------------------------
679
+ if env['HTTP_COOKIE'].include? 'j1.web.session'
680
+ session_encoded = env['rack.request.cookie_hash']['j1.web.session']
681
+ session_decoded = Base64.decode64(session_encoded)
682
+ j1_web_session = JSON.parse(session_decoded)
683
+
684
+ log_info! 'Authentication', 'Cookie', 'DEAD PATH. Read web session data' # #{session_decoded}"
685
+ else
686
+ j1_web_session['requested_page'] = env['REQUEST_URI']
687
+ end
688
+
689
+ # Update J1 web session data
690
+ # --------------------------------------------------------------------
691
+ j1_web_session['user_name'] = 'visitor'
692
+ j1_web_session['user_id'] = 'unknown'
693
+ j1_web_session['users_allowed'] = 'all'
694
+ j1_web_session['payment_status'] = 'unknown'
695
+ j1_web_session['provider'] = 'j1'
696
+ j1_web_session['provider_url'] = 'https://jekyll.one'
697
+ j1_web_session['provider_permissions'] = 'public'
698
+ j1_web_session['authenticated'] = 'false'
699
+ j1_web_session['writer'] = 'middleware'
700
+
701
+ # Write updated J1 session data to cookie
702
+ # --------------------------------------------------------------------
703
+ session_json = j1_web_session.to_json
704
+ log_info! 'Authentication', 'Cookie', 'DEAD PATH. Write web session data', "#{session_json}"
705
+
706
+ session_encoded = Base64.encode64(session_json)
707
+ response.set_cookie(
708
+ 'j1.web.session',
709
+ domain: false,
710
+ value: session_encoded.to_s,
711
+ path: '/'
712
+ )
713
+
714
+ log_info! 'Post Authentication', 'Redirect', 'DEAD PATH: Pass to requested page', "#{j1_web_session['requested_page']}"
715
+ redirect j1_web_session['requested_page']
716
+ end
717
+ else
718
+ raise J1App::ConfigError
719
+ end
720
+ end
721
+ # END: get '/authentication'
722
+ # --------------------------------------------------------------------------
723
+
724
+ # ENDPOINT post_authentication (called after a user is back from OAuth Provider)
725
+ # --------------------------------------------------------------------------
726
+ get '/post_authentication' do
727
+ reward = {
728
+ :id => 'unknown',
729
+ :name => 'unknown',
730
+ :link => '#'
731
+ }
732
+ campaign = {
733
+ :id => 'unknown',
734
+ :link => '#'
735
+ }
736
+
737
+ log_info! 'API', 'Post Authentication', 'Identification request received'
738
+
739
+ log_info! 'Post Authentication', 'Cookie', 'Read web session data'
740
+ session_encoded = request.cookies['j1.web.session']
741
+ session_decoded = Base64.decode64(session_encoded)
742
+ j1_web_session = JSON.parse(session_decoded)
743
+
744
+ user = warden.user
745
+ user_json = user.to_json
746
+
747
+ if user[:provider] === 'disqus'
748
+ user[:info][:urls][:site] = "https://disqus.com"
749
+ user[:info][:urls][:home] = user[:info]['urls']['profileUrl']
750
+ user[:info][:urls][:blog] = "https://disqus.com/by/juergen_adams/"
751
+ user[:info][:urls][:member] = user[:info]['urls']['profileUrl']
752
+ end
753
+
754
+ if user[:provider] === 'github'
755
+ user[:info][:urls][:site] = "https://github.com"
756
+ user[:info][:urls][:home] = user[:info]['urls']['GitHub']
757
+ user[:info][:urls][:blog] = "https://github.com/jekyll-one"
758
+ user[:info][:urls][:member] = user[:info]['urls']['Blog']
759
+ end
760
+
761
+ if user[:provider] === 'patreon'
762
+
763
+ user[:info][:urls][:site] = "https://patreon.com"
764
+ user[:info][:urls][:home] = "https://patreon.com/home"
765
+ user[:info][:urls][:blog] = "https://patreon.com/jekyll_one"
766
+
767
+ unless user[:info]['payment_info'].empty?
768
+ reward_url = user[:info]['payment_info']['relationships']['reward']['links']['related']
769
+ reward_json = RestClient.get "#{reward_url}", {:content_type => :json, :accept => :json}
770
+ reward_data = JSON.parse(reward_json)
771
+ user[:info][:urls][:member] = "https://patreon.com" + reward_data['data']['attributes']['url']
772
+ user[:info][:payment_status] = user[:info]['payment_info']['attributes']['declined_since'].nil? ? 'true' : 'false'
773
+ else
774
+ reward_url = ""
775
+ reward_json = ""
776
+ reward_data = ""
777
+ user[:info][:payment_status] = 'false'
778
+ end
779
+
780
+ unless reward_data.empty?
781
+ reward[:id] = reward_data['data']['id']
782
+ reward[:name] = reward_data['data']['attributes']['title']
783
+ reward[:link] = "https://patreon.com" + reward_data['data']['attributes']['url']
784
+ campaign[:id] = reward_data['data']['relationships']['campaign']['data']['id']
785
+ campaign[:link] = reward_data['data']['relationships']['campaign']['links']['related']
786
+ else
787
+ reward[:id] = ""
788
+ reward[:name] = "no tiers"
789
+ reward[:link] = ""
790
+ campaign[:id] = ""
791
+ campaign[:link] = ""
792
+ end
793
+ end
794
+
795
+ user[:extra][:reward] = reward
796
+ user[:extra][:campaign] = campaign
797
+
798
+ if user.nil?
799
+ # Collection of session data failed (e.g cookie > 4K)
800
+ #
801
+ log_info! 'Post Authentication', 'Identification', 'Internal error', 'User identification failed'
802
+ warden.logout
803
+ session.clear
804
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
805
+ description_title = "Access Denied"
806
+ redirect "/access_denied?provider=unknown&user=unknown&category=unknown&title=#{description_title}"
807
+ else
808
+ log_info! 'Post Authentication', 'Identification', 'User identified successfully'
809
+ log_info! 'Post Authentication', 'Cookie', 'Update web session data' # "#{j1_web_session}"
810
+ j1_web_session['user_name'] = user[:info]['nickname']
811
+ j1_web_session['user_id'] = user[:uid]
812
+ j1_web_session['provider'] = user[:provider]
813
+ j1_web_session['provider_membership'] = 'member'
814
+ j1_web_session['provider_permissions'] = providers["#{user[:provider]}"]['permissions']
815
+ j1_web_session['authenticated'] = 'true'
816
+ j1_web_session['payment_status'] = user[:info][:payment_status]
817
+ j1_web_session['writer'] = 'middleware'
818
+
819
+ current_user = user[:info]['nickname'] = user[:info]['nickname']
820
+ current_provider = user[:provider]
821
+
822
+ j1_web_session['requested_page'].scan(/(protected|private)/) do |match|
823
+
824
+ # Set category from requested page
825
+ #
826
+ category = match[0]
827
+ log_info! 'Post Authentication', 'Identification', 'Process content type', "#{category}"
828
+
829
+ # Check if user is allowed to access protected content in GENERAL
830
+ #
831
+ log_info! 'Post Authentication', 'Identification', 'Check for allowed users'
832
+ unless j1_web_session['users_allowed'].include? 'all'
833
+ unless j1_web_session['users_allowed'].include? "#{current_user}"
834
+ log_info! 'Post Authentication', 'Identification', 'User not allowed', "#{current_user}"
835
+ log_info! 'Post Authentication', 'Identification', 'Allowed users', "#{j1_web_session['users_allowed']}"
836
+ log_info! 'Post Authentication', 'Identification', 'Logout user from current session', "#{current_user}"
837
+ warden.logout
838
+ session.clear
839
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
840
+ description_title = "Access Denied"
841
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
842
+ end
843
+ end
844
+ log_info! 'Post Authentication', 'Identification', 'Allowed users', "#{j1_web_session['users_allowed']}"
845
+
846
+ # Check conditions to access protected content (if any)
847
+ #
848
+ log_info! 'Post Authentication', 'Identification', 'Check for conditions', "#{current_provider}"
849
+ check_conditions = providers["#{user[:provider]}"]['conditions'][category]['enabled']
850
+ if check_conditions
851
+
852
+ if providers["#{user[:provider]}"]['conditions'][category]['users']['whitelist'].nil?
853
+ category_whitelist = 'all'
854
+ else
855
+ category_whitelist = providers["#{user[:provider]}"]['conditions'][category]['users']['whitelist']
856
+ end
857
+
858
+ # Check if user is BLACKLISTED
859
+ #
860
+ blacklist = providers["#{user[:provider]}"]['conditions'][category]['users']['blacklist']
861
+ if blacklist.include? "#{current_user}"
862
+ log_info! 'Post Authentication', 'Identification', 'Check blacklisting'
863
+ log_info! 'Post Authentication', 'Identification', 'User blacklisted', "#{current_user}"
864
+ user[:info][:blacklisted] = 'true'
865
+ log_info! 'Post Authentication', 'Identification', 'Logout user from current session', "#{current_user}"
866
+ warden.logout
867
+ session.clear
868
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
869
+ description_title = "Access Denied"
870
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
871
+ end
872
+
873
+ log_info! 'Post Authentication', 'Identification', 'Check whitelisting'
874
+ if category_whitelisted? category_whitelist, current_user
875
+ user[:info][:whitelisted] = 'true'
876
+ reward[:name] = 'whitelisted'
877
+ log_info! 'Post Authentication', 'Identification', 'User whitelisted', "#{current_user}"
878
+ log_info! 'Post Authentication', 'Identification', 'Reward set to', 'Whitelisted'
879
+ else
880
+ log_info! 'Post Authentication', 'Identification', 'No whitelisting found', "#{current_user}"
881
+ end
882
+
883
+ log_info! 'Post Authentication', 'Identification', 'Check conditions'
884
+ unless category_whitelisted? category_whitelist, current_user
885
+ log_info! 'Post Authentication', 'Identification', 'Check rewards'
886
+ payment_tiers = providers["#{user[:provider]}"]['conditions'][category]['payment']['activated']
887
+ log_info! 'Post Authentication', 'Identification', 'Check rewards', "#{current_user}"
888
+ if payment_activated? payment_tiers
889
+ log_info! 'Post Authentication', 'Identification', 'Reward found', "#{reward[:name]}"
890
+
891
+ # Check if any payment exists for that user
892
+ #
893
+ log_info! 'Post Authentication', 'Identification', 'Check payment status'
894
+ if user[:info]['payment_info'].empty?
895
+ log_info! 'Post Authentication', 'Identification', 'Payment status: NOT AVAILABLE', "#{current_user}"
896
+ log_info! 'Post Authentication', 'Identification', 'Logout user from current session', "#{current_user}"
897
+ warden.logout
898
+ session.clear
899
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
900
+ description_title = "Access Denied"
901
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
902
+ end
903
+
904
+ # Check for VALID payments (scope: pledge-to-me)
905
+ #
906
+ payment_status = user[:info]['payment_info']['attributes']['declined_since']
907
+ unless payment_valid? payment_status
908
+ log_info! 'Post Authentication', 'Identification', 'Payment status INVALID', "#{current_user}"
909
+ log_info! 'Post Authentication', 'Identification', 'Logout user from current session', "#{current_user}"
910
+ warden.logout
911
+ session.clear
912
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
913
+ description_title = "Access Denied"
914
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
915
+ else
916
+ log_info! 'Post Authentication', 'Identification', 'Payment status VALID', "#{current_user}"
917
+ end
918
+ end
919
+
920
+ end
921
+ # end category_whitelisted
922
+ else
923
+ category_condition_state = providers["#{user[:provider]}"]['conditions'][category]['enabled']
924
+ log_info! 'Post Authentication', 'Identification', 'Category check failed for', "#{current_provider}"
925
+ log_info! 'Post Authentication', 'Identification', "Category checked", "#{category}"
926
+ log_info! 'Post Authentication', 'Identification', "Category support", "#{category_condition_state}"
927
+ warden.logout
928
+ session.clear
929
+ log_info! 'Post Authentication', 'Redirect', 'Pass to error page (access_denied)'
930
+ description_title = "Access Denied"
931
+ redirect "/access_denied?provider=#{current_provider}&user=#{current_user}&category=#{category}&title=#{description_title}"
932
+ end
933
+ # end check conditions
934
+
935
+ end
936
+ # end protected content
937
+ end
938
+ # end user.nil?
939
+
940
+ # redirect authenticated|validated user to requested page
941
+ #
942
+ j1_web_session['provider'] = current_provider
943
+ j1_web_session['users_allowed'] = providers["#{current_provider}"]['users']
944
+
945
+ # TODO: Add membership|product specific data for the SideBar
946
+
947
+ # write updated J1 session data to cookie
948
+ #
949
+ session_json = j1_web_session.to_json
950
+ log_info! 'Post Authentication', 'Cookie', 'Write web session data', "#{session_json}"
951
+
952
+ session_encoded = Base64.encode64(session_json)
953
+ response.set_cookie(
954
+ 'j1.web.session',
955
+ domain: false,
956
+ value: session_encoded.to_s,
957
+ path: '/'
958
+ )
959
+
960
+ time = Time.now.ctime.to_s
961
+
962
+ log_info! 'Post Authentication', 'Identification', 'Provider', "#{user[:provider]}"
963
+ log_info! 'Post Authentication', 'Identification', 'User', "#{user[:info]['nickname']}"
964
+ log_info! 'Post Authentication', 'Redirect', 'Set Last-Modified', "#{time}"
965
+ log_info! 'Post Authentication', 'Redirect', 'Pass to requested page', "#{j1_web_session['requested_page']}"
966
+
967
+
968
+ response.headers['Last-Modified'] = time
969
+ response.headers['Cache-Control'] = 'private,max-age=0,must-revalidate,no-store'
970
+ redirect j1_web_session['requested_page']
971
+
972
+ end
973
+ # END: get /post_authentication
974
+ # --------------------------------------------------------------------------
975
+
976
+
977
+ # ENDPOINT status (called from WEB to get current state of an user)
978
+ # --------------------------------------------------------------------------
979
+ get '/status' do
980
+ session_encoded = request.cookies['j1.web.session']
981
+ session_decoded = Base64.decode64(session_encoded)
982
+ j1_web_session = JSON.parse(session_decoded)
983
+
984
+ log_info! 'API', 'Status Request', 'Info request received'
985
+
986
+ # if request.warden.user.respond_to?(:info)
987
+ #
988
+ if warden.authenticated?
989
+ user_name = warden.user[:info]['nickname']
990
+ user_id = warden.user[:uid]
991
+ provider = warden.user[:provider]
992
+ provider_permissions = j1_web_session['provider_permissions']
993
+ provider_site_url = warden.user[:info][:urls][:site]
994
+ provider_home_url = warden.user[:info][:urls][:home]
995
+ provider_blog_url = warden.user[:info][:urls][:blog]
996
+ provider_member_url = warden.user[:info][:urls][:member]
997
+
998
+ if provider == 'patreon'
999
+ provider_membership = warden.user[:extra][:reward][:name]
1000
+ provider_member_url = warden.user[:extra][:reward][:link]
1001
+ else
1002
+ provider_membership = 'member'
1003
+ provider_member_url = '#'
1004
+ end
1005
+
1006
+ log_info! 'API', 'Status Request', 'User detected as signed in', "#{user_name}"
1007
+ else
1008
+ user_name = 'unknown'
1009
+ log_info! 'API', 'Status Request', 'User detected', 'signed out'
1010
+ end
1011
+
1012
+ # if request.warden.authenticated?
1013
+ #
1014
+ if user_name != 'unknown'
1015
+ log_info! 'API', 'Status Request', 'Send data', 'SIGNED_IN'
1016
+ content_type 'application/json'
1017
+ {
1018
+ user_name: user_name,
1019
+ user_id: user_id,
1020
+ provider: provider,
1021
+ provider_membership: provider_membership,
1022
+ provider_permissions: provider_permissions,
1023
+ provider_site_url: provider_site_url,
1024
+ provider_home_url: provider_home_url,
1025
+ provider_blog_url: provider_blog_url,
1026
+ provider_member_url: provider_member_url,
1027
+ status: 'signed in'
1028
+ }.to_json
1029
+ else
1030
+ log_info! 'API', 'Status Request', 'Send data', 'SIGNED_OUT'
1031
+ content_type 'application/json'
1032
+ {
1033
+ user_name: 'visitor',
1034
+ user_id: 'unknown',
1035
+ provider: 'j1',
1036
+ provider_membership: 'guest',
1037
+ provider_permissions: 'public',
1038
+ provider_site_url: '#',
1039
+ provider_home_url: '#',
1040
+ provider_blog_url: '#',
1041
+ provider_member_url: '#',
1042
+ status: 'signed out'
1043
+ }.to_json
1044
+ end
1045
+ end
1046
+ # END: get /status
1047
+ # --------------------------------------------------------------------------
1048
+
1049
+ # ENDPOINT cookie_consent (exception, called from the app|auth manager)
1050
+ # --------------------------------------------------------------------------
1051
+ get '/cookie_consent' do
1052
+ provider = params.fetch('provider')
1053
+ category = params.fetch('category')
1054
+ user = params.fetch('user')
1055
+ requested_page = params.fetch('requested_page')
1056
+ description_title = params.fetch('title')
1057
+
1058
+ log_info! 'API', 'ExceptionHandler', 'Request received'
1059
+ log_info! 'ExceptionHandler', 'ERROR', 'Cookies declined'
1060
+ log_info! 'ExceptionHandler', 'Redirect', 'Pass to dialog page', 'Cookie Consent'
1061
+
1062
+ # Capitalize first char
1063
+ provider = provider.sub(/^./, &:upcase)
1064
+ route = requested_page
1065
+
1066
+ @route = route
1067
+ @provider = provider
1068
+ @modal = "centralCookieConsent"
1069
+ @info_type = "danger"
1070
+ @modal_icon = "cookie"
1071
+ @modal_agreed_text = "Yes, please"
1072
+ @modal_disagreed_text = "No, thanks"
1073
+ @modal_title = "Authentication Manager"
1074
+ # @modal_description = "<h4>#{description_title}</h4><br /><br />User <b>#{user}</b> from provider <b>#{provider}</b> requested access on <b>#{category}</b> pages.<br /> In order to continue, you need to accept on <b>Cookies</b>."
1075
+ @modal_description = "<h4>#{description_title}</h4><br /><br /> In order to continue, you need to accept on <b>Cookies</b>."
1076
+
1077
+ erb :auth_manager_ui
1078
+ end
1079
+ # END: get /cookies_rejected
1080
+ # --------------------------------------------------------------------------
1081
+
1082
+
1083
+ # ENDPOINT access_denied (exception, called from the app|auth manager)
1084
+ # --------------------------------------------------------------------------
1085
+ get '/access_denied' do
1086
+ provider = params.fetch('provider')
1087
+ category = params.fetch('category')
1088
+ user = params.fetch('user')
1089
+ description_title = params.fetch('title')
1090
+
1091
+ log_info! 'API', 'ExceptionHandler', 'Request received'
1092
+ log_info! 'ExceptionHandler', 'ERROR', 'Access Denied'
1093
+
1094
+ session_encoded = request.cookies['j1.web.session']
1095
+ session_decoded = Base64.decode64(session_encoded)
1096
+ j1_web_session = JSON.parse(session_decoded)
1097
+
1098
+ # Update J1 web session data
1099
+ # --------------------------------------------------------------------
1100
+ j1_web_session['user_name'] = user
1101
+ # j1_web_session['user_id'] = 'unknown'
1102
+ # j1_web_session['users_allowed'] = 'unknown'
1103
+ # j1_web_session['payment_status'] = 'unknown'
1104
+ j1_web_session['provider'] = provider
1105
+ # j1_web_session['provider_url'] = 'unknown'
1106
+ # j1_web_session['provider_permissions'] = 'unknown'
1107
+ # j1_web_session['authenticated'] = 'false'
1108
+ j1_web_session['writer'] = 'middleware'
1109
+
1110
+ log_info! 'ExceptionHandler', 'Cookie', 'Write web session data', "#{session_json}"
1111
+
1112
+ # write updated J1 session data to cookie
1113
+ #
1114
+ session_json = j1_web_session.to_json
1115
+ session_encoded = Base64.encode64(session_json)
1116
+ response.set_cookie(
1117
+ 'j1.web.session',
1118
+ domain: false,
1119
+ value: session_encoded.to_s,
1120
+ path: '/'
1121
+ )
1122
+
1123
+ log_info! 'ExceptionHandler', 'Redirect', 'Pass to error page', "Access Denied"
1124
+
1125
+ # Capitalize first char
1126
+ provider = provider.sub(/^./, &:upcase)
1127
+ route = '/'
1128
+
1129
+ @route = route
1130
+ @provider = provider
1131
+ @modal = "centralModalInfo"
1132
+ @info_type = "danger"
1133
+ @modal_icon = "account-off"
1134
+ @modal_ok_text = "Ok, understood"
1135
+ @modal_title = "Authentication Manager"
1136
+ @modal_description = "<h4>#{description_title}</h4></br></br> User <b>#{user}</b> from provider <b>#{provider}</b> is not allowed to access <b>#{category}</b> pages."
1137
+
1138
+ erb :auth_manager_ui
1139
+ end
1140
+ # END: get '/access_denied'
1141
+ # --------------------------------------------------------------------------
1142
+
1143
+
1144
+ # ENDPOINT invalid_funds (exception, called from the app|auth manager)
1145
+ # --------------------------------------------------------------------------
1146
+ get '/invalid_funds' do
1147
+ provider = params.fetch('provider')
1148
+ category = params.fetch('category')
1149
+ user = params.fetch('user')
1150
+ description_title = params.fetch('title')
1151
+
1152
+ log_info! 'API', 'ExceptionHandler', 'Request received'
1153
+ log_info! 'ExceptionHandler', 'ERROR', 'Invalid Funds'
1154
+
1155
+ session_encoded = request.cookies['j1.web.session']
1156
+ session_decoded = Base64.decode64(session_encoded)
1157
+ j1_web_session = JSON.parse(session_decoded)
1158
+
1159
+ # Update J1 web session data
1160
+ # --------------------------------------------------------------------
1161
+ j1_web_session['user_name'] = user
1162
+ # j1_web_session['user_id'] = 'unknown'
1163
+ # j1_web_session['users_allowed'] = 'unknown'
1164
+ # j1_web_session['payment_status'] = 'unknown'
1165
+ j1_web_session['provider'] = provider
1166
+ # j1_web_session['provider_url'] = 'unknown'
1167
+ # j1_web_session['provider_permissions'] = 'unknown'
1168
+ # j1_web_session['authenticated'] = 'false'
1169
+ j1_web_session['writer'] = 'middleware'
1170
+
1171
+ log_info! 'ExceptionHandler', 'Cookie', 'Write web session data', "#{session_json}"
1172
+
1173
+ # write updated J1 session data to cookie
1174
+ #
1175
+ log_info! 'API', 'Exception Handler', 'ERROR', 'Invalid Funds'
1176
+ session_json = j1_web_session.to_json
1177
+ session_encoded = Base64.encode64(session_json)
1178
+ response.set_cookie(
1179
+ 'j1.web.session',
1180
+ domain: false,
1181
+ value: session_encoded.to_s,
1182
+ path: '/'
1183
+ )
1184
+
1185
+ log_info! 'ExceptionHandler', 'Redirect', 'Pass to error page', 'Invalid Funds'
1186
+
1187
+ # Capitalize first char
1188
+ provider = provider.sub(/^./, &:upcase)
1189
+ route = '/'
1190
+
1191
+ @route = route
1192
+ @provider = provider
1193
+ @modal = "centralModalInfo"
1194
+ @info_type = "danger"
1195
+ @modal_icon = "account-off"
1196
+ @modal_ok_text = "Ok, understood"
1197
+ @modal_title = "Authentication Manager"
1198
+ @modal_description = "<h4>#{description_title}</h4></br></br> User <b>#{user}</b> from provider <b>#{provider}</b> is not allowed to access <b>#{category}</b> pages."
1199
+
1200
+ erb :auth_manager_ui
1201
+ end
1202
+ # END: get /invalid_funds
1203
+ # --------------------------------------------------------------------------
1204
+
1205
+
1206
+ # access_protected_content ENDPOINT called from the app (auth manager)
1207
+ # --------------------------------------------------------------------------
1208
+ get '/page_validation' do
1209
+ provider = params.fetch('provider')
1210
+ allowed_users = params.fetch('allowed_users')
1211
+ page = params.fetch('page')
1212
+ category = params.fetch('category')
1213
+
1214
+ log_info! 'API', 'PageAccessControl', 'PageValidate request received'
1215
+
1216
+ # Capitalize first char
1217
+ # provider = provider.sub(/^./, &:upcase)
1218
+
1219
+ log_info! 'PageAccessControl', 'AuthCheck', 'Check provider', "#{provider}"
1220
+ # jadams, 2019-03-16: Hier ist das Problem
1221
+ #
1222
+ if warden.authenticated?
1223
+ log_info! 'PageAccessControl', 'AuthCheck', 'Grant access for', "#{provider}"
1224
+ log_info! 'PageAccessControl', 'Redirect', 'Pass to page', "#{page}"
1225
+ route = page
1226
+ else
1227
+ log_info! 'PageAccessControl', 'AuthCheck', 'Authentication failed', "#{provider}"
1228
+ route = "/authentication?request=signin&provider=#{provider}&allowed_users=#{allowed_users}"
1229
+ end
1230
+
1231
+ log_info! 'PageAccessControl', 'Redirect', 'Pass to SignIn dialog, page', "#{page}"
1232
+ # Capitalize first char
1233
+ provider = provider.sub(/^./, &:upcase)
1234
+
1235
+ @provider = provider
1236
+ @route = route
1237
+ @modal = "signInProtectedContent"
1238
+ @modal_icon = "login"
1239
+ @modal_agreed_text = "Yes, please"
1240
+ @modal_disagreed_text = "No, thanks"
1241
+ @modal_title = "SignIn"
1242
+ @modal_image = "/assets/images/master_header/admin-dashboard-bootstrap-1280x600.png"
1243
+ @modal_description = "The page <b>#{page}</b> you requested belongs to <b>#{category}</b> content. You'll be redirected to authenticate with the provider <b>#{provider}</b>. If signed in successfully, you get access to all <b>#{category} pages</b>."
1244
+
1245
+ erb :auth_manager_ui
1246
+ end
1247
+ # END: get '/page_validation
1248
+ # --------------------------------------------------------------------------
1249
+
1250
+ # ENDPOINT iframe
1251
+ # --------------------------------------------------------------------------
1252
+ get '/iframe' do
1253
+ @website_url = "https://jekyll-one.github.io/"
1254
+ erb :iframe
1255
+ end
1256
+
1257
+ # Workaround to rescue OmniAuth::Strategies::OAuth2::CallbackError?
1258
+ # for chromium based browsers (e.g. google-chrome)
1259
+ # ------------------------------------------------------------------------
1260
+ get '/redirect_requested_page' do
1261
+ log_info! 'Fallback', 'Redirect', 'Pass to requested page', "#{j1_web_session['requested_page']}"
1262
+ redirect j1_web_session['requested_page']
1263
+ end
1264
+ # END: get /iframe
1265
+ # --------------------------------------------------------------------------
1266
+ end
1267
+ end