j1_template_mde 2018.4.31 → 2018.4.32

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