ditty 0.7.1 → 0.10.1

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 (185) hide show
  1. checksums.yaml +4 -4
  2. data/.env.test +2 -0
  3. data/.gitignore +3 -0
  4. data/.pryrc +2 -0
  5. data/.rubocop.yml +24 -8
  6. data/.travis.yml +4 -8
  7. data/CNAME +1 -0
  8. data/Dockerfile +18 -0
  9. data/Gemfile.ci +0 -15
  10. data/Rakefile +5 -4
  11. data/Readme.md +24 -2
  12. data/_config.yml +1 -0
  13. data/config.ru +4 -4
  14. data/ditty.gemspec +31 -20
  15. data/docs/CNAME +1 -0
  16. data/docs/_config.yml +1 -0
  17. data/docs/index.md +34 -0
  18. data/exe/ditty +2 -0
  19. data/lib/ditty.rb +30 -4
  20. data/lib/ditty/cli.rb +38 -5
  21. data/lib/ditty/components/ditty.rb +82 -0
  22. data/lib/ditty/controllers/application_controller.rb +267 -0
  23. data/lib/ditty/controllers/{audit_logs.rb → audit_logs_controller.rb} +5 -7
  24. data/lib/ditty/controllers/{auth.rb → auth_controller.rb} +56 -32
  25. data/lib/ditty/controllers/{component.rb → component_controller.rb} +35 -24
  26. data/lib/ditty/controllers/{main.rb → main_controller.rb} +7 -7
  27. data/lib/ditty/controllers/roles_controller.rb +23 -0
  28. data/lib/ditty/controllers/user_login_traits_controller.rb +46 -0
  29. data/lib/ditty/controllers/{users.rb → users_controller.rb} +17 -20
  30. data/lib/ditty/db.rb +9 -5
  31. data/lib/ditty/emails/base.rb +48 -34
  32. data/lib/ditty/generators/crud_generator.rb +114 -0
  33. data/lib/ditty/generators/migration_generator.rb +26 -0
  34. data/lib/ditty/generators/project_generator.rb +52 -0
  35. data/lib/ditty/helpers/authentication.rb +6 -5
  36. data/lib/ditty/helpers/component.rb +11 -2
  37. data/lib/ditty/helpers/pundit.rb +24 -8
  38. data/lib/ditty/helpers/response.rb +38 -15
  39. data/lib/ditty/helpers/views.rb +48 -6
  40. data/lib/ditty/listener.rb +44 -14
  41. data/lib/ditty/memcached.rb +8 -0
  42. data/lib/ditty/middleware/accept_extension.rb +4 -2
  43. data/lib/ditty/middleware/error_catchall.rb +4 -2
  44. data/lib/ditty/models/audit_log.rb +1 -0
  45. data/lib/ditty/models/base.rb +13 -0
  46. data/lib/ditty/models/identity.rb +10 -7
  47. data/lib/ditty/models/role.rb +2 -0
  48. data/lib/ditty/models/user.rb +40 -3
  49. data/lib/ditty/models/user_login_trait.rb +17 -0
  50. data/lib/ditty/policies/audit_log_policy.rb +6 -6
  51. data/lib/ditty/policies/role_policy.rb +3 -3
  52. data/lib/ditty/policies/user_login_trait_policy.rb +45 -0
  53. data/lib/ditty/policies/user_policy.rb +3 -3
  54. data/lib/ditty/rubocop.rb +3 -0
  55. data/lib/ditty/seed.rb +2 -0
  56. data/lib/ditty/services/authentication.rb +31 -15
  57. data/lib/ditty/services/email.rb +22 -12
  58. data/lib/ditty/services/logger.rb +30 -13
  59. data/lib/ditty/services/pagination_wrapper.rb +9 -5
  60. data/lib/ditty/services/settings.rb +19 -7
  61. data/lib/ditty/tasks/ditty.rake +127 -0
  62. data/lib/ditty/tasks/omniauth-ldap.rake +43 -0
  63. data/lib/ditty/templates/.gitignore +5 -0
  64. data/lib/ditty/templates/.rspec +2 -0
  65. data/lib/ditty/templates/.rubocop.yml +7 -0
  66. data/lib/ditty/templates/Rakefile +12 -0
  67. data/lib/ditty/templates/application.rb +12 -0
  68. data/lib/ditty/templates/config.ru +37 -0
  69. data/lib/ditty/templates/controller.rb.erb +64 -0
  70. data/lib/ditty/templates/env.example +4 -0
  71. data/lib/ditty/templates/lib/project.rb.erb +5 -0
  72. data/lib/ditty/templates/migration.rb.erb +7 -0
  73. data/lib/ditty/templates/model.rb.erb +26 -0
  74. data/lib/ditty/templates/pids/.empty_directory +0 -0
  75. data/lib/ditty/templates/policy.rb.erb +48 -0
  76. data/{public → lib/ditty/templates/public}/browserconfig.xml +0 -0
  77. data/lib/ditty/templates/public/css/sb-admin-2.min.css +10 -0
  78. data/lib/ditty/templates/public/css/styles.css +13 -0
  79. data/lib/ditty/templates/public/favicon.ico +0 -0
  80. data/{public → lib/ditty/templates/public}/images/apple-icon.png +0 -0
  81. data/{public → lib/ditty/templates/public}/images/favicon-16x16.png +0 -0
  82. data/{public → lib/ditty/templates/public}/images/favicon-32x32.png +0 -0
  83. data/{public → lib/ditty/templates/public}/images/launcher-icon-1x.png +0 -0
  84. data/{public → lib/ditty/templates/public}/images/launcher-icon-2x.png +0 -0
  85. data/{public → lib/ditty/templates/public}/images/launcher-icon-4x.png +0 -0
  86. data/{public → lib/ditty/templates/public}/images/mstile-150x150.png +0 -0
  87. data/{public → lib/ditty/templates/public}/images/safari-pinned-tab.svg +0 -0
  88. data/lib/ditty/templates/public/js/sb-admin-2.min.js +7 -0
  89. data/lib/ditty/templates/public/js/scripts.js +1 -0
  90. data/{public/manifest.json → lib/ditty/templates/public/manifest.json.erb} +2 -2
  91. data/lib/ditty/templates/settings.yml.erb +19 -0
  92. data/lib/ditty/templates/sidekiq.rb +18 -0
  93. data/lib/ditty/templates/sidekiq.yml +9 -0
  94. data/lib/ditty/templates/spec_helper.rb +43 -0
  95. data/lib/ditty/templates/type.rb.erb +21 -0
  96. data/lib/ditty/templates/views/display.haml.tt +20 -0
  97. data/lib/ditty/templates/views/edit.haml.tt +10 -0
  98. data/lib/ditty/templates/views/form.haml.tt +11 -0
  99. data/lib/ditty/templates/views/index.haml.tt +29 -0
  100. data/lib/ditty/templates/views/new.haml.tt +10 -0
  101. data/lib/ditty/version.rb +1 -1
  102. data/lib/rubocop/cop/ditty/call_services_directly.rb +42 -0
  103. data/migrate/20181209_add_user_login_traits.rb +16 -0
  104. data/migrate/20181209_extend_audit_log.rb +12 -0
  105. data/migrate/20190220_add_parent_id_to_roles.rb +9 -0
  106. data/spec/ditty/api_spec.rb +51 -0
  107. data/spec/ditty/controllers/roles_spec.rb +67 -0
  108. data/spec/ditty/controllers/user_login_traits_spec.rb +72 -0
  109. data/spec/ditty/controllers/users_spec.rb +72 -0
  110. data/spec/ditty/emails/base_spec.rb +76 -0
  111. data/spec/ditty/emails/forgot_password_spec.rb +20 -0
  112. data/spec/ditty/helpers/component_spec.rb +85 -0
  113. data/spec/ditty/models/user_spec.rb +36 -0
  114. data/spec/ditty/services/email_spec.rb +36 -0
  115. data/spec/ditty/services/logger_spec.rb +68 -0
  116. data/spec/ditty/services/settings_spec.rb +63 -0
  117. data/spec/ditty_spec.rb +9 -0
  118. data/spec/factories.rb +46 -0
  119. data/spec/fixtures/logger.yml +17 -0
  120. data/spec/fixtures/section.yml +3 -0
  121. data/spec/fixtures/settings.yml +8 -0
  122. data/spec/spec_helper.rb +51 -0
  123. data/spec/support/api_shared_examples.rb +250 -0
  124. data/spec/support/crud_shared_examples.rb +145 -0
  125. data/views/403.haml +2 -0
  126. data/views/404.haml +2 -4
  127. data/views/500.haml +11 -0
  128. data/views/audit_logs/index.haml +32 -28
  129. data/views/auth/forgot_password.haml +32 -16
  130. data/views/auth/identity.haml +14 -13
  131. data/views/auth/ldap.haml +17 -0
  132. data/views/auth/login.haml +23 -17
  133. data/views/auth/register.haml +20 -18
  134. data/views/auth/register_identity.haml +27 -12
  135. data/views/auth/reset_password.haml +36 -19
  136. data/views/blank.haml +43 -0
  137. data/views/emails/forgot_password.haml +1 -1
  138. data/views/emails/layouts/action.haml +10 -6
  139. data/views/emails/layouts/alert.haml +2 -1
  140. data/views/emails/layouts/billing.haml +2 -1
  141. data/views/embedded.haml +17 -11
  142. data/views/error.haml +8 -3
  143. data/views/index.haml +1 -1
  144. data/views/layout.haml +45 -30
  145. data/views/partials/actions.haml +15 -14
  146. data/views/partials/content_tag.haml +0 -0
  147. data/views/partials/delete_form.haml +1 -1
  148. data/views/partials/filter_control.haml +2 -2
  149. data/views/partials/footer.haml +13 -5
  150. data/views/partials/form_control.haml +30 -19
  151. data/views/partials/form_tag.haml +1 -1
  152. data/views/partials/navitems.haml +42 -0
  153. data/views/partials/notifications.haml +12 -8
  154. data/views/partials/pager.haml +44 -25
  155. data/views/partials/search.haml +15 -11
  156. data/views/partials/sidebar.haml +15 -37
  157. data/views/partials/sort_ui.haml +2 -0
  158. data/views/partials/timespan_selector.haml +64 -0
  159. data/views/partials/topbar.haml +53 -0
  160. data/views/partials/user_associations.haml +32 -0
  161. data/views/quick_start.haml +23 -0
  162. data/views/roles/display.haml +27 -6
  163. data/views/roles/edit.haml +3 -3
  164. data/views/roles/form.haml +1 -0
  165. data/views/roles/index.haml +23 -14
  166. data/views/roles/new.haml +2 -2
  167. data/views/user_login_traits/display.haml +32 -0
  168. data/views/user_login_traits/edit.haml +10 -0
  169. data/views/user_login_traits/form.haml +5 -0
  170. data/views/user_login_traits/index.haml +28 -0
  171. data/views/user_login_traits/new.haml +10 -0
  172. data/views/users/display.haml +15 -16
  173. data/views/users/edit.haml +3 -3
  174. data/views/users/form.haml +0 -0
  175. data/views/users/index.haml +31 -24
  176. data/views/users/login_traits.haml +25 -0
  177. data/views/users/new.haml +2 -2
  178. data/views/users/profile.haml +17 -15
  179. data/views/users/user.haml +1 -1
  180. metadata +314 -76
  181. data/lib/ditty/components/app.rb +0 -77
  182. data/lib/ditty/controllers/application.rb +0 -175
  183. data/lib/ditty/controllers/roles.rb +0 -16
  184. data/lib/ditty/rake_tasks.rb +0 -102
  185. data/views/partials/navbar.haml +0 -23
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ shared_examples 'a CRUD Controller' do |route|
4
+ context 'GET' do
5
+ it '/doesnotexist' do
6
+ get '/doesnotexist'
7
+ expect(last_response).not_to be_ok
8
+ expect(last_response.status).to eq 404
9
+ end
10
+
11
+ it route.to_s do
12
+ model # Ensure that there's at least one item in the list
13
+ get '/'
14
+
15
+ if Pundit.policy(user, app.model_class).list?
16
+ expect(last_response).to be_ok, "Expected OK response, got #{last_response.status}"
17
+ else
18
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
19
+ end
20
+ end
21
+
22
+ it "#{route}?count=1&page=1" do
23
+ model # Ensure that there's at least one item in the list
24
+ get '/?count=1&page=1'
25
+
26
+ if Pundit.policy(user, app.model_class).list?
27
+ expect(last_response).to be_ok, "Expected OK response, got #{last_response.status}"
28
+ else
29
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
30
+ end
31
+ end
32
+
33
+ it "#{route}/new" do
34
+ get '/new'
35
+
36
+ if Pundit.policy(user, app.model_class).create?
37
+ expect(last_response).to be_ok, "Expected OK response, got #{last_response.status}"
38
+ else
39
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
40
+ end
41
+ end
42
+
43
+ it "#{route}/id" do
44
+ get "/#{model.id}"
45
+
46
+ if Pundit.policy(user, model).read?
47
+ expect(last_response).to be_ok, "Expected OK response, got #{last_response.status}"
48
+ else
49
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
50
+ end
51
+ end
52
+
53
+ it "#{route}/id/edit" do
54
+ get "/#{model.id}/edit"
55
+
56
+ if Pundit.policy(user, model).update?
57
+ expect(last_response).to be_ok, "Expected OK response, got #{last_response.status}"
58
+ else
59
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
60
+ end
61
+ end
62
+ end
63
+
64
+ context 'POST' do
65
+ it '/doesnotexist' do
66
+ header 'Accept', 'text/html'
67
+ post '/doesnotexist'
68
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
69
+ expect(last_response.status).to eq 404
70
+ end
71
+
72
+ it route.to_s do
73
+ header 'Accept', 'text/html'
74
+ post '/', create_data
75
+
76
+ if Pundit.policy(user, app.model_class).create?
77
+ expect(last_response.status).to eq 302
78
+ else
79
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
80
+ end
81
+ end
82
+
83
+ it "#{route} with invalid parameters" do
84
+ header 'Accept', 'text/html'
85
+ header 'Content-Type', 'application/x-www-form-urlencoded'
86
+ post '/', invalid_create_data
87
+
88
+ if Pundit.policy(user, app.model_class).create?
89
+ expect(last_response.status).to eq 400
90
+ else
91
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
92
+ end
93
+ end
94
+ end
95
+
96
+ context 'PUT' do
97
+ it '/doesnotexist' do
98
+ header 'Accept', 'text/html'
99
+ put '/doesnotexist'
100
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
101
+ expect(last_response.status).to eq 404
102
+ end
103
+
104
+ it "#{route}/:id" do
105
+ header 'Accept', 'text/html'
106
+ put "/#{model.id}", update_data
107
+
108
+ if Pundit.policy(user, model).update?
109
+ expect(last_response.status).to eq 302
110
+ else
111
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
112
+ end
113
+ end
114
+
115
+ it "#{route} with invalid parameters" do
116
+ header 'Accept', 'text/html'
117
+ put "/#{model.id}", invalid_update_data
118
+
119
+ if Pundit.policy(user, model).update?
120
+ expect(last_response.status).to eq 400
121
+ else
122
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
123
+ end
124
+ end
125
+ end
126
+
127
+ context 'DELETE' do
128
+ it '/doesnotexist' do
129
+ delete '/doesnotexist'
130
+ expect(last_response).not_to be_ok, "Expected a NOT OK response, got #{last_response.status}"
131
+ expect(last_response.status).to eq 404
132
+ end
133
+
134
+ it "#{route}/id" do
135
+ header 'Accept', 'text/html'
136
+ delete "/#{model.id}"
137
+
138
+ if Pundit.policy(user, model).delete?
139
+ expect(last_response.status).to eq 302
140
+ else
141
+ expect(last_response).not_to be_ok
142
+ end
143
+ end
144
+ end
145
+ end
data/views/403.haml ADDED
@@ -0,0 +1,2 @@
1
+ %p.lead.text-center
2
+ Your user is not allowed access to the requested URL.
data/views/404.haml CHANGED
@@ -1,7 +1,5 @@
1
- %h2 Whoops!
2
-
3
- %p.lead
1
+ %p.lead.text-center
4
2
  We could not find the page you were looking for...
5
3
 
6
4
  .text-center
7
- %iframe{ width: 560, height: 315, src: 'https://www.youtube.com/embed/e3-5YC_oHjE', frameborder: 0, allowfullscreen: true }
5
+ %iframe{ width: 560, height: 315, src: 'https://www.youtube.com/embed/e3-5YC_oHjE', frameborder: 0, allowfullscreen: true }
data/views/500.haml ADDED
@@ -0,0 +1,11 @@
1
+ %p.lead.text-center
2
+ A call to Elasticsearch failed unexpectedly.
3
+
4
+ - if current_user.admin?
5
+ %p
6
+ The error was:
7
+ %bt
8
+ = error.message
9
+ - if current_user.super_admin?
10
+ %pre
11
+ %code= error.backtrace.join("\n")
@@ -1,32 +1,36 @@
1
1
  .row
2
2
  .col-md-12
3
- .panel.panel-default
4
- .panel-body
5
- = haml :'partials/search'
6
- %table.table.table-striped
7
- %thead
8
- %tr
9
- %th User email
10
- %th Action
11
- %th Details
12
- %th Created at
13
- %tbody
14
- - if list.count > 0
15
- - list.all.each do |entity|
16
- %tr
17
- %td
18
- -if entity.user
19
- %a{ href: "#{settings.map_path}/users/#{entity.user.id}" }= entity.user.email
20
- -else
21
- None
22
- %td
23
- = entity.action
24
- %td
25
- = entity.details
26
- %td
27
- = entity.created_at.strftime('%Y-%m-%d %H:%M:%S')
28
- - else
3
+ = haml :'partials/search'
4
+ %table.table.table-striped.table-bordered.table-hover
5
+ %thead.thead-dark
6
+ %tr
7
+ %th= "User #{sort_ui(:user)}"
8
+ %th= "Action #{sort_ui(:action)}"
9
+ %th= "Details #{sort_ui(:details)}"
10
+ %th= "IP Address #{sort_ui(:ip_address)}"
11
+ %th= "Browser #{sort_ui(:browser)}"
12
+ %th= "Device #{sort_ui(:device)}"
13
+ %th= "Platform #{sort_ui(:platform)}"
14
+ %th= "Created At #{sort_ui(:created_at)}"
15
+ %tbody
16
+ - if list.count > 0
17
+ - list.all.each do |entity|
29
18
  %tr
30
- %td.text-center{ colspan: 4 } No records
19
+ %td
20
+ -if entity.user
21
+ %a{ href: "#{settings.map_path}/users/#{entity.user.id}" }= entity.user.email
22
+ -else
23
+ None
24
+ %td= entity.action
25
+ %td= entity.details
26
+ %td= entity.ip_address || 'Unknown'
27
+ %td= entity.browser || 'Unknown'
28
+ %td= entity.device || 'Unknown'
29
+ %td= entity.platform || 'Unknown'
30
+ %td= entity.created_at&.strftime('%Y-%m-%d %H:%M:%S') || 'Unknown'
31
+ - else
32
+ %tr
33
+ %td.text-center{ colspan: 4 } No records
31
34
 
32
- =pagination(list, base_path)
35
+ - if list.count > 0
36
+ = pagination(list, base_path)
@@ -1,16 +1,32 @@
1
- .row
2
- .col-md-4
3
- .col-md-4
4
- .panel.panel-default
5
- .panel-body
6
- %p.text-center
7
- Enter your email address and we will send you a link to reset your password if you've registered on the system.
8
- = form_tag("#{settings.map_path}/auth/forgot-password") do
9
- .form-group
10
- .col-sm-12
11
- %input.form-control{ name: 'email', type: 'text', placeholder: 'Enter your email address' }
12
- .row.text-right
13
- .col-md-12
14
- %button.btn.btn-primary.btn-block{ type: 'submit' }
15
- Email password reset link
16
- .col-md-4
1
+ .container
2
+ / Outer Row
3
+ .row.justify-content-center
4
+ .col-xl-10.col-lg-12.col-md-9
5
+ .card.card-default.o-hidden.border-0.shadow-lg.my-5
6
+ .card-body.p-0
7
+ / Nested Row within Card Body
8
+ .row
9
+ .col-lg-6.d-none.d-lg-block.bg-password-image
10
+ .col-lg-6
11
+ .p-5
12
+ .text-center
13
+ %h1.h4.text-gray-900.mb-2
14
+ Forgot Your Password?
15
+ %p.mb-4
16
+ We get it, stuff happens. Just enter your email address below and we'll send you a link to reset your password!
17
+ .small
18
+ = haml :'partials/notifications'
19
+ = form_tag("#{settings.map_path}/auth/forgot-password", attributes: { class: 'user' }) do
20
+ .form-group
21
+ %input.form-control.form-control-user{ name: 'email', type: 'email', placeholder: 'Enter Email Address...' }
22
+ %button.btn.btn-primary.btn-user.btn-block{ type: 'submit' }
23
+ Reset Password
24
+ %hr
25
+ - if policy(::Ditty::User).register?
26
+ .text-center
27
+ %a.small{ href: "#{settings.map_path}/auth/register" } Create an Account!
28
+ .text-center
29
+ %a.small{ href: "#{settings.map_path}/auth/login" } Already have an account? Login!
30
+
31
+ .row.justify-content-center
32
+ .col-xl-10.col-lg-12.col-md-9
@@ -1,15 +1,16 @@
1
- = form_tag("#{settings.map_path}/auth/identity/callback", attributes: { class: '' }) do
1
+ = form_tag("#{settings.map_path}/auth/identity/callback", attributes: { class: 'user' }) do
2
2
  .form-group
3
- %label.control-label Email
4
- %input.form-control.border-input{ name: 'username', tabindex: '1' }
3
+ %input.form-control.form-control-user{ name: 'username', type: 'email', 'aria-describedby': 'emailHelp', placeholder: 'Enter Email Address...' }
5
4
  .form-group
6
- %label.control-label{ style: 'display: block' }
7
- Password
8
- %a{ href: "#{settings.map_path}/auth/forgot-password", style: 'float: right', tabindex: '5' }
9
- Forgot?
10
- %input.form-control.border-input{ name: 'password', type: 'password', tabindex: '2' }
11
- %button.btn.btn-primary{ type: 'submit', tabindex: '3' } Log In
12
- - if policy(::Ditty::User).register?
13
- .pull-right
14
- No account yet?
15
- %a.btn.btn-default{ href: "#{settings.map_path}/auth/register", tabindex: '4' } Register
5
+ %input.form-control.form-control-user{ name: 'password', type: 'password', placeholder: 'Password' }
6
+ / .form-group
7
+ / .custom-control.custom-checkbox.small
8
+ / <input type="checkbox" class="custom-control-input" id="customCheck">
9
+ / <label class="custom-control-label" for="customCheck">Remember Me</label>
10
+ %button.btn.btn-primary.btn-user.btn-block{ type: 'submit' } Log In
11
+ %hr
12
+ .text-center
13
+ %a.small{ href: "#{settings.map_path}/auth/forgot-password" } Forgot Password?
14
+ - if policy(::Ditty::User).register?
15
+ .text-center
16
+ %a.small{ href: "#{settings.map_path}/auth/register" } Create an Account!
@@ -0,0 +1,17 @@
1
+ .row
2
+ .col-sm-2
3
+ .col-sm-8
4
+ .card.card-default.shadow
5
+ .card-body
6
+ = form_tag("#{settings.map_path}/auth/ldap/callback", attributes: { class: '' }) do
7
+ .form-group
8
+ %label.control-label Username
9
+ %input.form-control.border-input{ name: 'username', tabindex: '1' }
10
+ .form-group
11
+ %label.control-label{ style: 'display: block' }
12
+ Password
13
+ %input.form-control.border-input{ name: 'password', type: 'password', tabindex: '2' }
14
+ %button.btn.btn-primary{ type: 'submit', tabindex: '3' }
15
+ %i.fa.fa-building
16
+ Log In
17
+ .col-sm-2
@@ -1,18 +1,24 @@
1
- .row
2
- .col-sm-2
3
- .col-sm-8
4
- .panel.panel-default
5
- .panel-body
6
- - if Ditty::Services::Authentication.provides? 'identity'
7
- = haml :'auth/identity'
1
+ .container
2
+ / Outer Row
3
+ .row.justify-content-center
4
+ .col-xl-10.col-lg-12.col-md-9
5
+ .card.card-default.o-hidden.border-0.shadow-lg.my-5
6
+ .card-body.p-0
7
+ / Nested Row within Card Body
8
8
  .row
9
- .col-sm-12= "&nbsp;"
10
- .row
11
- .col-sm-8.col-sm-push-2
12
- - Ditty::Services::Authentication.providers.each do |name|
13
- - provider = Ditty::Services::Authentication[name]
14
- - next if provider[:login_prompt].nil?
15
- %a.btn.btn-block.btn-default{ href: "#{settings.map_path}/auth/#{name}" }
16
- %i.fa{ class: "fa-#{provider[:icon] || 'key'}"}
17
- = provider[:login_prompt]
18
- .col-sm-2
9
+ .col-lg-6.d-none.d-lg-block.bg-login-image
10
+ .col-lg-6
11
+ .p-5
12
+ .text-center
13
+ %h1.h4.text-gray-900.mb-4 Welcome Back!
14
+ .small
15
+ = haml :'partials/notifications'
16
+ - ::Ditty::Services::Authentication.providers.each do |name|
17
+ - provider = ::Ditty::Services::Authentication[name]
18
+ - next if provider[:login_prompt].nil?
19
+ %p
20
+ %a.btn.btn-block.btn-secondary{ href: "#{settings.map_path}/auth/#{name}" }
21
+ %i.fab.fw{ class: "fa-#{provider[:icon] || 'key'}"}
22
+ = provider[:login_prompt]
23
+ - if ::Ditty::Services::Authentication.provides? 'identity'
24
+ = haml :'auth/identity'
@@ -1,19 +1,21 @@
1
- / TODO: How can we detect a google registration? Extra parameter to the callback? Or a custom callback page?
2
- .row
3
- .col-md-2
4
- .col-md-8
5
- .panel.panel-default
6
- .panel-body
7
- - if Ditty::Services::Authentication.provides? 'identity'
8
- = haml :'auth/register_identity', locals: { identity: identity }
9
- .row
10
- .col-sm-12= "&nbsp;"
11
- .row
12
- .col-sm-8.col-sm-push-2
13
- - Ditty::Services::Authentication.providers.each do |name|
14
- - provider = Ditty::Services::Authentication[name]
1
+ .container
2
+ .card.card-default.o-hidden.border-0.shadow-lg.my-5
3
+ .card-body.p-0
4
+ / Nested Row within Card Body
5
+ .row
6
+ .col-lg-5.d-none.d-lg-block.bg-register-image
7
+ .col-lg-7
8
+ .p-5
9
+ .text-center
10
+ %h1.h4.text-gray-900.mb-4 Create an Account!
11
+ .small
12
+ = haml :'partials/notifications'
13
+ - ::Ditty::Services::Authentication.providers.each do |name|
14
+ - provider = ::Ditty::Services::Authentication[name]
15
15
  - next if provider[:register_prompt].nil?
16
- %a.btn.btn-block.btn-default{ href: "#{settings.map_path}/auth/#{name}" }
17
- %i.fa{ class: "fa-#{provider[:icon] || 'key'}"}
18
- = provider[:register_prompt]
19
- .col-md-2
16
+ %p
17
+ %a.btn.btn-user.btn-block{ href: "#{settings.map_path}/auth/#{name}", class: "btn-#{provider[:icon] || 'key'}" }
18
+ %i.fab.fa-fw{ class: "fa-#{provider[:icon] || 'key'}"}
19
+ = provider[:register_prompt]
20
+ - if ::Ditty::Services::Authentication.provides? 'identity'
21
+ = haml :'auth/register_identity', locals: { identity: identity }
@@ -1,14 +1,29 @@
1
- = form_tag("#{settings.map_path}/auth/register/identity") do
2
- = form_control(:username, identity, label: 'Email', placeholder: 'your@email.com')
3
- = form_control(:password, identity, label: 'Password', type: :password)
4
- = form_control(:password_confirmation, identity, label: 'Confirm Password', type: :password)
1
+ - if identity.errors[:password] && identity.errors[:password].include?('is not strong enough')
2
+ .alert.alert-warning
3
+ %p Make sure your password is at least 8 characters long, and including the following
4
+ %ul
5
+ %li Upper- and lowercase letters
6
+ %li Numbers
7
+ %li Special Characters
5
8
 
6
- - if identity.errors[:password] && identity.errors[:password].include?('is not strong enough')
7
- .alert.alert-warning
8
- %p Make sure your password is at least 8 characters long, and including the following
9
- %ul
10
- %li Upper- and lowercase letters
11
- %li Numbers
12
- %li Special Characters
9
+ = form_tag("#{settings.map_path}/auth/register/identity", attributes: { class: 'user' }) do
10
+ .form-group
11
+ %input.form-control.form-control-user{ name: 'identity[username]', type: 'email', placeholder: 'Email Address', class: identity.errors[:username] ? 'is-invalid' : 'is-valid' }
12
+ - if identity.errors[:username]
13
+ .invalid-feedback= identity.errors[:username].join(', ')
14
+ .form-group.row
15
+ .col-sm-6.mb-3.mb-sm-0
16
+ %input.form-control.form-control-user{ name: 'identity[password]', type: 'password', placeholder: 'Password', class: identity.errors[:password] ? 'is-invalid' : 'is-valid' }
17
+ - if identity.errors[:password]
18
+ .invalid-feedback= identity.errors[:password].join(', ')
19
+ .col-sm-6
20
+ %input.form-control.form-control-user{ name: 'identity[password_confirmation]', type: 'password', placeholder: 'Repeat Password', class: identity.errors[:password_confirmation] ? 'is-invalid' : 'is-valid' }
21
+ - if identity.errors[:password_confirmation]
22
+ .invalid-feedback= identity.errors[:password_confirmation].join(', ')
13
23
 
14
- %button.btn.btn-primary{ type: 'submit' } Register
24
+ %button.btn.btn-primary.btn-user.btn-block{ type: 'submit' } Register
25
+ %hr
26
+ .text-center
27
+ %a.small{ href: "#{settings.map_path}/auth/forgot-password" } Forgot Password?
28
+ .text-center
29
+ %a.small{ href: "#{settings.map_path}/auth/login" } Already have an account? Login!