masks 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +50 -0
  4. data/Rakefile +11 -0
  5. data/app/assets/builds/application.css +4764 -0
  6. data/app/assets/builds/application.js +8236 -0
  7. data/app/assets/builds/application.js.map +7 -0
  8. data/app/assets/builds/masks/application.css +1 -0
  9. data/app/assets/builds/masks/application.js +7122 -0
  10. data/app/assets/builds/masks/application.js.map +7 -0
  11. data/app/assets/images/masks.png +0 -0
  12. data/app/assets/javascripts/application.js +2 -0
  13. data/app/assets/javascripts/controllers/application.js +9 -0
  14. data/app/assets/javascripts/controllers/emails_controller.js +28 -0
  15. data/app/assets/javascripts/controllers/index.js +12 -0
  16. data/app/assets/javascripts/controllers/keys_controller.js +20 -0
  17. data/app/assets/javascripts/controllers/recover_controller.js +21 -0
  18. data/app/assets/javascripts/controllers/recover_password_controller.js +21 -0
  19. data/app/assets/javascripts/controllers/session_controller.js +94 -0
  20. data/app/assets/manifest.js +2 -0
  21. data/app/assets/masks_manifest.js +2 -0
  22. data/app/assets/stylesheets/application.css +26 -0
  23. data/app/controllers/concerns/masks/controller.rb +114 -0
  24. data/app/controllers/masks/actors_controller.rb +15 -0
  25. data/app/controllers/masks/application_controller.rb +35 -0
  26. data/app/controllers/masks/backup_codes_controller.rb +34 -0
  27. data/app/controllers/masks/debug_controller.rb +9 -0
  28. data/app/controllers/masks/devices_controller.rb +20 -0
  29. data/app/controllers/masks/emails_controller.rb +60 -0
  30. data/app/controllers/masks/error_controller.rb +14 -0
  31. data/app/controllers/masks/keys_controller.rb +45 -0
  32. data/app/controllers/masks/manage/actor_controller.rb +35 -0
  33. data/app/controllers/masks/manage/actors_controller.rb +12 -0
  34. data/app/controllers/masks/manage/base_controller.rb +12 -0
  35. data/app/controllers/masks/one_time_code_controller.rb +49 -0
  36. data/app/controllers/masks/passwords_controller.rb +33 -0
  37. data/app/controllers/masks/recoveries_controller.rb +43 -0
  38. data/app/controllers/masks/sessions_controller.rb +53 -0
  39. data/app/helpers/masks/application_helper.rb +49 -0
  40. data/app/jobs/masks/application_job.rb +7 -0
  41. data/app/jobs/masks/expire_actors_job.rb +15 -0
  42. data/app/jobs/masks/expire_recoveries_job.rb +15 -0
  43. data/app/mailers/masks/actor_mailer.rb +22 -0
  44. data/app/mailers/masks/application_mailer.rb +15 -0
  45. data/app/models/concerns/masks/access.rb +162 -0
  46. data/app/models/concerns/masks/actor.rb +132 -0
  47. data/app/models/concerns/masks/adapter.rb +68 -0
  48. data/app/models/concerns/masks/role.rb +9 -0
  49. data/app/models/concerns/masks/scoped.rb +54 -0
  50. data/app/models/masks/access/actor_password.rb +20 -0
  51. data/app/models/masks/access/actor_scopes.rb +18 -0
  52. data/app/models/masks/access/actor_signup.rb +22 -0
  53. data/app/models/masks/actors/anonymous.rb +40 -0
  54. data/app/models/masks/actors/system.rb +24 -0
  55. data/app/models/masks/adapters/active_record.rb +85 -0
  56. data/app/models/masks/application_model.rb +15 -0
  57. data/app/models/masks/application_record.rb +8 -0
  58. data/app/models/masks/check.rb +192 -0
  59. data/app/models/masks/credential.rb +166 -0
  60. data/app/models/masks/credentials/backup_code.rb +30 -0
  61. data/app/models/masks/credentials/device.rb +59 -0
  62. data/app/models/masks/credentials/email.rb +48 -0
  63. data/app/models/masks/credentials/factor2.rb +71 -0
  64. data/app/models/masks/credentials/key.rb +38 -0
  65. data/app/models/masks/credentials/last_login.rb +12 -0
  66. data/app/models/masks/credentials/masquerade.rb +32 -0
  67. data/app/models/masks/credentials/nickname.rb +63 -0
  68. data/app/models/masks/credentials/one_time_code.rb +34 -0
  69. data/app/models/masks/credentials/password.rb +28 -0
  70. data/app/models/masks/credentials/recovery.rb +71 -0
  71. data/app/models/masks/credentials/session.rb +67 -0
  72. data/app/models/masks/device.rb +30 -0
  73. data/app/models/masks/error.rb +51 -0
  74. data/app/models/masks/event.rb +14 -0
  75. data/app/models/masks/mask.rb +255 -0
  76. data/app/models/masks/rails/actor.rb +190 -0
  77. data/app/models/masks/rails/actor_role.rb +12 -0
  78. data/app/models/masks/rails/device.rb +47 -0
  79. data/app/models/masks/rails/email.rb +96 -0
  80. data/app/models/masks/rails/key.rb +61 -0
  81. data/app/models/masks/rails/recovery.rb +116 -0
  82. data/app/models/masks/rails/role.rb +20 -0
  83. data/app/models/masks/rails/scope.rb +15 -0
  84. data/app/models/masks/session.rb +447 -0
  85. data/app/models/masks/sessions/access.rb +26 -0
  86. data/app/models/masks/sessions/inline.rb +16 -0
  87. data/app/models/masks/sessions/request.rb +42 -0
  88. data/app/resources/masks/actor_resource.rb +9 -0
  89. data/app/resources/masks/session_resource.rb +15 -0
  90. data/app/views/layouts/masks/application.html.erb +17 -0
  91. data/app/views/layouts/masks/mailer.html.erb +17 -0
  92. data/app/views/layouts/masks/mailer.text.erb +1 -0
  93. data/app/views/layouts/masks/manage.html.erb +25 -0
  94. data/app/views/masks/actor_mailer/recover_credentials.html.erb +33 -0
  95. data/app/views/masks/actor_mailer/recover_credentials.text.erb +1 -0
  96. data/app/views/masks/actor_mailer/verify_email.html.erb +34 -0
  97. data/app/views/masks/actor_mailer/verify_email.text.erb +8 -0
  98. data/app/views/masks/actors/current.html.erb +152 -0
  99. data/app/views/masks/application/_header.html.erb +31 -0
  100. data/app/views/masks/backup_codes/new.html.erb +103 -0
  101. data/app/views/masks/emails/new.html.erb +103 -0
  102. data/app/views/masks/emails/verify.html.erb +51 -0
  103. data/app/views/masks/keys/new.html.erb +127 -0
  104. data/app/views/masks/manage/actor/show.html.erb +126 -0
  105. data/app/views/masks/manage/actors/index.html.erb +40 -0
  106. data/app/views/masks/one_time_code/new.html.erb +150 -0
  107. data/app/views/masks/passwords/edit.html.erb +58 -0
  108. data/app/views/masks/recoveries/new.html.erb +71 -0
  109. data/app/views/masks/recoveries/password.html.erb +64 -0
  110. data/app/views/masks/sessions/new.html.erb +153 -0
  111. data/config/brakeman.ignore +28 -0
  112. data/config/locales/en.yml +286 -0
  113. data/config/routes.rb +46 -0
  114. data/db/migrate/20231205173845_create_actors.rb +94 -0
  115. data/lib/generators/masks/install/USAGE +8 -0
  116. data/lib/generators/masks/install/install_generator.rb +33 -0
  117. data/lib/generators/masks/install/templates/initializer.rb +5 -0
  118. data/lib/generators/masks/install/templates/masks.json +6 -0
  119. data/lib/masks/configuration.rb +236 -0
  120. data/lib/masks/engine.rb +25 -0
  121. data/lib/masks/middleware.rb +70 -0
  122. data/lib/masks/version.rb +5 -0
  123. data/lib/masks.rb +183 -0
  124. data/lib/tasks/masks_tasks.rake +71 -0
  125. data/masks.json +274 -0
  126. metadata +416 -0
@@ -0,0 +1,153 @@
1
+ <div data-controller="session">
2
+ <%= form_with url: session_path, method: :post do |form| %>
3
+ <div role="alert" class="alert mb-4 text-left" data-session-target="flash">
4
+ <% if flash[:errors]&.any? && !factor2_required? %>
5
+ <div class="flex items-center gap-4">
6
+ <%= lucide_icon("shield-x", class: "stroke-error") %>
7
+ <span><%= flash[:errors][0] %></span>
8
+ </div>
9
+ <% elsif logged_in? %>
10
+ <div class="flex items-center gap-4">
11
+ <%= lucide_icon("check", class: "stroke-success") %>
12
+ <span><%= t(".logged_in") %></span>
13
+ </div>
14
+ <% else %>
15
+ <div data-flash="enter-factor2" class="hidden flex items-center gap-4">
16
+ <%= lucide_icon("key-square", class: "stroke-warning") %>
17
+ <span><%= t(".enter_factor2") %></span>
18
+ </div>
19
+ <div data-flash="enter-credentials" class="flex items-center gap-4">
20
+ <%= lucide_icon("shield-alert", class: "stroke-warning") %>
21
+ <span><%= t(".enter_credentials") %></span>
22
+ </div>
23
+ <div data-flash="enter-password" class="hidden flex items-center gap-4">
24
+ <%= lucide_icon("shield-ellipsis", class: "stroke-warning") %>
25
+ <span><%= t(".enter_password") %></span>
26
+ </div>
27
+ <div data-flash="continue" class="hidden flex items-center gap-4">
28
+ <%= lucide_icon("shield-question", class: "stroke-accent") %>
29
+ <span><%= t(".continue") %></span>
30
+ </div>
31
+ <% end %>
32
+ </div>
33
+
34
+ <% if factor2_required? %>
35
+ <div class="w-full">
36
+ <div role="tablist" class="tabs tabs-bordered mb-4">
37
+ <% if @actor.totp_secret %>
38
+ <input
39
+ checked
40
+ name="factor2"
41
+ type="radio"
42
+ role="tab"
43
+ class="tab whitespace-nowrap"
44
+ aria-label="<%= t('.tab.one_time_code') %>"
45
+ />
46
+ <div role="tabpanel" class="tab-content p-4 bg-base-100 rounded-b">
47
+ <p class="flex items-center gap-4 text-sm mb-4">
48
+ <%= lucide_icon("qr-code") %>
49
+ <%= t(".one_time_code") %>
50
+ </p>
51
+ <label class="form-control w-full">
52
+ <input
53
+ type="text"
54
+ data-action="session#updateCode"
55
+ data-session-target="oneTimeCode"
56
+ placeholder="<%= t('.placeholder.one_time_code') %>"
57
+ name="session[one_time_code]"
58
+ class="input input-bordered w-full"
59
+ />
60
+ </label>
61
+ </div>
62
+ <% end %>
63
+
64
+ <% if @actor.saved_backup_codes? %>
65
+ <input
66
+ type="radio"
67
+ name="factor2"
68
+ role="tab"
69
+ class="tab whitespace-nowrap"
70
+ aria-label="<%= t('.tab.backup_code') %>"
71
+ />
72
+ <div role="tabpanel" class="tab-content p-4 bg-base-100 rounded-b">
73
+ <p class="flex items-center gap-4 text-sm mb-4">
74
+ <%= lucide_icon("rotate-cw") %>
75
+ <%= t(".backup_code") %>
76
+ </p>
77
+ <label class="form-control w-full">
78
+ <input
79
+ type="text"
80
+ data-action="session#updateCode"
81
+ data-session-target="backupCode"
82
+ placeholder="<%= t('.placeholder.backup_code') %>"
83
+ name="session[backup_code]"
84
+ class="input input-bordered w-full"
85
+ />
86
+ </label>
87
+ </div>
88
+ <% end %>
89
+ </div>
90
+ </div>
91
+ <% elsif !logged_in? %>
92
+ <div class="flex flex-col gap-2">
93
+ <label class="form-control w-full">
94
+ <input
95
+ type="text"
96
+ data-action="session#updateNickname"
97
+ data-session-target="nickname"
98
+ placeholder="<%= t('.placeholder.nickname') %>"
99
+ name="session[nickname]"
100
+ class="input input-bordered w-full"
101
+ />
102
+ </label>
103
+ <label class="form-control w-full">
104
+ <input
105
+ type="password"
106
+ data-action="session#updatePassword"
107
+ data-session-target="password"
108
+ placeholder="<%= t('.placeholder.password') %>"
109
+ name="session[password]"
110
+ class="input input-bordered w-full"
111
+ />
112
+ <% if @config.site_links[:recover] %>
113
+ <div class="label">
114
+ <span class="label-text-alt opacity-60 hover:opacity-100"><a
115
+ class="hover:underline"
116
+ href="<%= @config.site_links[:recover] %>"
117
+ ><%= t(".recover_credentials") %></a></span>
118
+ </div>
119
+ <% end %>
120
+ </label>
121
+ </div>
122
+ <% end %>
123
+
124
+
125
+ <% unless logged_in? %>
126
+ <div class="flex items-center gap-4">
127
+ <%= form.submit t(".submit"),
128
+ class: "btn btn-active",
129
+ data: {
130
+ session_target: "submit",
131
+ } %>
132
+ <div class="form-control" data-session-target="remember">
133
+ <label class="label cursor-pointer">
134
+ <input type="checkbox" name="session[remember_me]" class="toggle toggle-sm"/>
135
+ <span class="label-text pl-2"><%= t(".remember_me") %></span>
136
+ </label>
137
+ </div>
138
+ </div>
139
+ <% end %>
140
+ <% end %>
141
+
142
+ <% if factor2_required? %>
143
+ <div class="mt-2 opacity-60 hover:opacity-100">
144
+ <%= form_with url: session_path, method: :delete do |form| %>
145
+ <span class="text-xs">
146
+ <%= t(".start_over.text") %>
147
+ <%= form.submit t(".start_over.link"), class: "cursor-pointer underline" %>
148
+ </span>
149
+
150
+ <% end %>
151
+ </div>
152
+ <% end %>
153
+ </div>
@@ -0,0 +1,28 @@
1
+ {
2
+ "ignored_warnings": [
3
+ {
4
+ "warning_type": "Cross-Site Request Forgery",
5
+ "warning_code": 7,
6
+ "fingerprint": "2c0ec97f978f7a612f1fa0567846c86ec02c072be7784e4c707fd4ba81fe5021",
7
+ "check_name": "ForgerySetting",
8
+ "message": "`protect_from_forgery` should be called in `ApplicationController`",
9
+ "file": "dummy/app/controllers/application_controller.rb",
10
+ "line": 1,
11
+ "link": "https://brakemanscanner.org/docs/warning_types/cross-site_request_forgery/",
12
+ "code": null,
13
+ "render_path": null,
14
+ "location": {
15
+ "type": "controller",
16
+ "controller": "ApplicationController"
17
+ },
18
+ "user_input": null,
19
+ "confidence": "High",
20
+ "cwe_id": [
21
+ 352
22
+ ],
23
+ "note": ""
24
+ }
25
+ ],
26
+ "updated": "2024-02-07 16:03:41 -0500",
27
+ "brakeman_version": "6.1.2"
28
+ }
@@ -0,0 +1,286 @@
1
+ # Files in the config/locales directory are used for internationalization and
2
+ # are automatically loaded by Rails. If you want to use locales other than
3
+ # English, add the necessary files in this directory.
4
+ #
5
+ # To use the locales, use `I18n.t`:
6
+ #
7
+ # I18n.t "hello"
8
+ #
9
+ # In views, this is aliased to just `t`:
10
+ #
11
+ # <%= t("hello") %>
12
+ #
13
+ # To use a different locale, set it with `I18n.locale`:
14
+ #
15
+ # I18n.locale = :es
16
+ #
17
+ # This would use the information in config/locales/es.yml.
18
+ #
19
+ # To learn more about the API, please read the Rails Internationalization guide
20
+ # at https://guides.rubyonrails.org/i18n.html.
21
+ #
22
+ # Be aware that YAML interprets the following case-insensitive strings as
23
+ # booleans: `true`, `false`, `on`, `off`, `yes`, `no`. Therefore, these strings
24
+ # must be quoted to be interpreted as strings. For example:
25
+ #
26
+ # en:
27
+ # "yes": yup
28
+ # enabled: "ON"
29
+
30
+ en:
31
+ layouts:
32
+ masks:
33
+ application:
34
+ meta:
35
+ title: masks
36
+ manage:
37
+ meta:
38
+ title: masks
39
+ masks:
40
+ application:
41
+ header:
42
+ logged_in: welcome
43
+ actor_mailer:
44
+ recover_credentials:
45
+ recover: reset password
46
+ nickname: your nickname
47
+ subheading: hey there, you recently requested help recovering your credentials...
48
+ call_to_action: your username is listed above. you can reset your password if you forgot it.
49
+ sign_off: reply to this email if you need more help. cheers
50
+ verify_email:
51
+ subject: verify your email - things
52
+ heading: verify your email
53
+ subheading: |
54
+ hey there, you recently added this email to your account. you must verify it's yours by pressing the button below...
55
+ subheading_plain: |
56
+ hey there, you recently added this email to your account. you must verify it's yours by visiting the link below...
57
+ call_to_action: once verified, this email will be usable future logins and account recovery.
58
+ sign_off: thanks
59
+ verify: "verify"
60
+ verify_plain: "verify here — "
61
+ added: added
62
+ actors:
63
+ current:
64
+ emails:
65
+ zero: no emails found
66
+ one: "%{email}"
67
+ other: "%{email}"
68
+ add_email: add...
69
+ add_more_email: add more...
70
+ change_password: change your password...
71
+ credentials: credentials
72
+ password: password
73
+ one_time_codes: one-time code
74
+ backup_codes: backup codes
75
+ created: created
76
+ manage: manage...
77
+ enable: enable...
78
+ logout: logout
79
+ never_logged_in: never...
80
+ last_accessed: last accessed
81
+ last_login: last login
82
+ ago: ago
83
+ devices: devices
84
+ change: change...
85
+ keys: keys
86
+ add_key: add...
87
+ add_more_key: add more...
88
+
89
+ passwords:
90
+ edit:
91
+ placeholder:
92
+ password: your current password...
93
+ change: your new password...
94
+ submit: change
95
+ one_time_code:
96
+ new:
97
+ tfa: secondary credential
98
+ disabled: disabled
99
+ enabled: enabled
100
+ enable_qr: to enable, scan this qr code into your authenticator app.
101
+ enable_manual: you can also enter the secret manually.
102
+ heading: one-time code
103
+ empty_detail: you must enable two-factor authentication to use backup codes.
104
+ disabled_heading: add a one-time password
105
+ placeholder:
106
+ otp: one-time code...
107
+ password: your password...
108
+ delete: enter your password...
109
+ secret: secret
110
+ submit: enable
111
+ delete: disable
112
+ delete_div: disable one-time code
113
+ backup_codes: save backup codes...
114
+ reset_codes: view backup codes...
115
+ backup_codes:
116
+ new:
117
+ tfa: secondary credential
118
+ disabled: disabled
119
+ enabled: enabled
120
+ heading: backup codes
121
+ empty_detail: backup codes are available once you add a secondary credential, like a one-time code.
122
+ disabled_heading: backup codes are disabled
123
+ save_codes: save your 10-digit backup codes somewhere safe, then press enable to use them as another secondary credential...
124
+ reset_codes: press delete to disable backup codes. afterward you can generate a new set of codes.
125
+ download: download
126
+ enable: enable
127
+ delete: delete
128
+ placeholder:
129
+ password: enter your password...
130
+ emails:
131
+ verify:
132
+ verified: verified!
133
+ verification_expired: email verification link expired
134
+ card_title: how verified emails work...
135
+ details: |
136
+ you can use your newly verified email:
137
+ list_html: |
138
+ <li>instead of your nickname during login
139
+ <li>for password-less login via email links
140
+ <li>to recover your nickname or password
141
+ privacy: your emails will never be shared.
142
+ manage: to manage it and others...
143
+ manage_expired: to try again...
144
+ added: manage it in
145
+ emails: view your emails
146
+ new:
147
+ page: your email
148
+ placeholder:
149
+ email:
150
+ zero: enter a new email address...
151
+ one: enter another email address...
152
+ other: enter another email address...
153
+ password: enter your password...
154
+ heading: no emails found
155
+ no_emails: no emails added
156
+ no_emails_detail: your email can act as an alternate way to access and recover your account.
157
+ heading_new:
158
+ zero: no emails found
159
+ one: your email
160
+ other: your emails
161
+ help_title: how it works
162
+ help_body: if you enter valid information you will be contacted with instructions to recover your credentials.
163
+ help_more: need more help?
164
+ help_contact: contact support
165
+ help_button: "help"
166
+ support_url:
167
+ submit: add
168
+ back: go back...
169
+ email_verified: verified %{ago} ago
170
+ email_taken: email already taken.
171
+ pending_verification: awaiting verification...
172
+ expired_verification: verification expired.
173
+ add: add an email...
174
+ keys:
175
+ new:
176
+ heading: your keys
177
+ added: allow automated tools to act on your behalf...
178
+ page: your key
179
+ placeholder:
180
+ name: enter a name...
181
+ password: enter your password...
182
+ secret: leave blank to generate a secret...
183
+ no_keys_detail: keys allow automated tools to act on your behalf...
184
+ heading_new:
185
+ zero: no keys found
186
+ one: your key
187
+ other: your keys
188
+ help_title: how it works
189
+ help_body: if you enter valid information you will be contacted with instructions to recover your credentials.
190
+ help_more: need more help?
191
+ help_contact: contact support
192
+ help_button: "help"
193
+ support_url:
194
+ submit: make key
195
+ back: go back...
196
+ key_verified: verified %{ago} ago
197
+ key_taken: key already taken.
198
+ pending_verification: awaiting verification...
199
+ expired_verification: verification expired.
200
+ add: add key
201
+ recoveries:
202
+ password:
203
+ placeholder: new password...
204
+ heading: reset your password
205
+ heading_success: password reset
206
+ heading_expired: password reset expired
207
+ subheading: enter a new password. you can use it to login to your account after it's changed...
208
+ subheading_success: your password has been changed. you can login using the password you just entered.
209
+ subheading_expired: this password reset link is expired or invalid.
210
+ help_title: how it works
211
+ help_body: if you enter valid information you will be contacted with instructions to recover your credentials.
212
+ help_more: need more help?
213
+ help_contact: contact support
214
+ help_button: "help"
215
+ support_url:
216
+ submit: reset
217
+ login: back to login
218
+ new:
219
+ placeholder: nickname, email or phone...
220
+ heading: recover your credentials
221
+ subheading: enter a nickname, email, or phone number associated with your account to recover your credentials...
222
+ help_title: how it works
223
+ help_body: if you enter valid information you will be contacted with instructions to recover your credentials.
224
+ help_more: need more help?
225
+ help_contact: contact support
226
+ help_button: "help"
227
+ support_url:
228
+ submit: recover
229
+ back: go back...
230
+ submitted:
231
+ heading: check your notifications...
232
+ description: if you have an account with us you'll receive an email or message on your phone with instructions on how to recover your account.
233
+ sessions:
234
+ new:
235
+ submit: continue
236
+ remember_me: remember me
237
+ start_over:
238
+ text: or
239
+ link: start over...
240
+ or_start_over: or
241
+ recover_credentials: "forgot your credentials?"
242
+ enter_factor2: enter a secondary credential to continue...
243
+ enter_credentials: "enter your credentials to continue..."
244
+ enter_password: "enter your password to continue..."
245
+ continue: "press continue to access things..."
246
+ one_time_code: enter a 6-digit one-time code from your authenticator app...
247
+ backup_code: enter one of your saved 10-digit backup codes...
248
+ logged_in: welcome!
249
+ tab:
250
+ one_time_code: one-time code
251
+ backup_code: backup code
252
+ placeholder:
253
+ nickname: nickname, email, or phone number...
254
+ password: password...
255
+ one_time_code: one-time code...
256
+ backup_code: backup code...
257
+ activerecord:
258
+ attributes:
259
+ masks/rails/actor:
260
+ nickname: nickname
261
+ password: password
262
+ signup: invalid
263
+ masks/rails/email:
264
+ email: email
265
+ masks/rails/key:
266
+ name: name
267
+ secret: secret
268
+ scopes: scopes
269
+ errors:
270
+ models:
271
+ masks/rails/actor:
272
+ format: is invalid
273
+ attributes:
274
+ signup:
275
+ disabled: credentials...
276
+ activemodel:
277
+ attributes:
278
+ masks/credentials/password:
279
+ password: password
280
+ masks/credentials/nickname:
281
+ nickname: nickname
282
+ errors:
283
+ models:
284
+ masks/session:
285
+ credentials: invalid credentials...
286
+ access: invalid access...
data/config/routes.rb ADDED
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ Masks::Engine.routes.draw do
4
+ get "/debug", to: "debug#show" if Rails.env.development?
5
+
6
+ # signup/login
7
+ get "session", to: "sessions#new", as: :session
8
+ post "session", to: "sessions#create"
9
+ delete "session", to: "sessions#destroy"
10
+
11
+ # recover credentials
12
+ get "recover", to: "recoveries#new", as: :recover
13
+ post "recover", to: "recoveries#create"
14
+ get "recovery", to: "recoveries#password", as: :recover_password
15
+ post "recovery", to: "recoveries#reset"
16
+
17
+ # manage account details, password, etc
18
+ get "me", to: "actors#current", as: :current
19
+ get "password", to: "passwords#edit", as: :password
20
+ post "password", to: "passwords#update"
21
+ post "device/:key", to: "devices#update", as: :device
22
+
23
+ # manage emails
24
+ get "emails", to: "emails#new", as: :emails
25
+ post "emails", to: "emails#create"
26
+ patch "emails", to: "emails#notify"
27
+ delete "emails", to: "emails#delete"
28
+ get "email/:email/verify", to: "emails#verify", as: :email_verify
29
+
30
+ # keys
31
+ get "keys", to: "keys#new", as: :keys
32
+ post "keys", to: "keys#create"
33
+ delete "keys", to: "keys#delete"
34
+
35
+ # manage 2nd factor options
36
+ get "one-time-codes", to: "one_time_code#new", as: :one_time_code
37
+ post "one-time-codes", to: "one_time_code#create"
38
+ delete "one-time-codes", to: "one_time_code#destroy"
39
+ get "backup-codes", to: "backup_codes#new", as: :backup_codes
40
+ post "backup-codes", to: "backup_codes#create"
41
+
42
+ # managers-only section
43
+ get "actors", to: "manage/actors#index", as: :actors
44
+ get "actors/:actor", to: "manage/actor#show", as: :actor
45
+ patch "actors/:actor", to: "manage/actor#update"
46
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateActors < ActiveRecord::Migration[7.1]
4
+ def change
5
+ create_table :actors do |t|
6
+ t.string :type
7
+ t.string :nickname
8
+ t.string :version
9
+ t.string :password_digest
10
+ t.string :phone_number
11
+ t.string :totp_secret
12
+ t.text :backup_codes
13
+
14
+ t.timestamps
15
+ t.datetime :last_login_at
16
+ t.datetime :changed_password_at
17
+ t.datetime :added_phone_number_at
18
+ t.datetime :added_totp_secret_at
19
+ t.datetime :saved_backup_codes_at
20
+ t.datetime :notified_inactive_at
21
+
22
+ t.index :nickname, unique: true
23
+ end
24
+
25
+ create_table :scopes do |t|
26
+ t.string :name
27
+ t.references :actor, polymorphic: true
28
+ t.index %i[name actor_id], unique: true
29
+ t.timestamps
30
+ end
31
+
32
+ create_table :roles do |t|
33
+ t.string :type
34
+ t.references :actor, polymorphic: true
35
+ t.references :record, polymorphic: true
36
+ t.timestamps
37
+ end
38
+
39
+ add_index :roles,
40
+ %i[type actor_id actor_type record_id record_type],
41
+ unique: true
42
+
43
+ create_table :emails do |t|
44
+ t.string :email
45
+ t.string :token
46
+ t.references :actor
47
+ t.boolean :verified, null: true
48
+ t.datetime :verified_at
49
+ t.datetime :notified_at
50
+ t.timestamps
51
+
52
+ t.index %i[email verified], unique: true
53
+ t.index %i[token], unique: true
54
+ end
55
+
56
+ create_table :recoveries do |t|
57
+ t.string :token
58
+ t.string :nickname, null: true
59
+ t.string :email, null: true
60
+ t.string :phone, null: true
61
+ t.references :actor
62
+ t.datetime :notified_at
63
+ t.timestamps
64
+
65
+ t.index %i[token actor_id], unique: true
66
+ end
67
+
68
+ create_table :devices do |t|
69
+ t.string :key
70
+ t.string :user_agent
71
+ t.string :ip_address
72
+ t.string :fingerprint
73
+ t.string :version
74
+
75
+ t.references :actor
76
+ t.datetime :accessed_at
77
+ t.timestamps
78
+
79
+ t.index %i[key actor_id], unique: true
80
+ end
81
+
82
+ create_table :keys do |t|
83
+ t.string :name
84
+ t.string :sha
85
+ t.text :scopes
86
+
87
+ t.references :actor
88
+ t.timestamps
89
+ t.datetime :accessed_at
90
+
91
+ t.index %i[sha], unique: true
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ bin/rails generate install Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Masks
4
+ # Generator for +rails g masks:install+.
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ source_root File.expand_path("templates", __dir__)
7
+
8
+ def add_routing
9
+ route 'mount Masks::Engine => "/"'
10
+ end
11
+
12
+ def copy_initializer_file
13
+ copy_file "initializer.rb", "config/initializers/masks.rb"
14
+ end
15
+
16
+ def copy_masks_json
17
+ copy_file "masks.json", "masks.json"
18
+ end
19
+
20
+ def add_migrations
21
+ if yes?("generate migrations for masks?")
22
+ rails_command "masks:install:migrations"
23
+ else
24
+ puts
25
+ puts 'run "rails masks:install:migrations" to add them later on...'
26
+ end
27
+
28
+ puts
29
+ puts "[masks] welcome!"
30
+ puts "[masks] visit https://masks.geiger.to for more information."
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ Masks.configure do |config|
4
+ # see https://masks.geiger.to/get-started for configuration options
5
+ end
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "<%= Rails.application.name %>",
3
+ "url": "http://localhost:3000",
4
+ "extend": "masks",
5
+ "masks": []
6
+ }