masks 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +50 -0
- data/Rakefile +11 -0
- data/app/assets/builds/application.css +4764 -0
- data/app/assets/builds/application.js +8236 -0
- data/app/assets/builds/application.js.map +7 -0
- data/app/assets/builds/masks/application.css +1 -0
- data/app/assets/builds/masks/application.js +7122 -0
- data/app/assets/builds/masks/application.js.map +7 -0
- data/app/assets/images/masks.png +0 -0
- data/app/assets/javascripts/application.js +2 -0
- data/app/assets/javascripts/controllers/application.js +9 -0
- data/app/assets/javascripts/controllers/emails_controller.js +28 -0
- data/app/assets/javascripts/controllers/index.js +12 -0
- data/app/assets/javascripts/controllers/keys_controller.js +20 -0
- data/app/assets/javascripts/controllers/recover_controller.js +21 -0
- data/app/assets/javascripts/controllers/recover_password_controller.js +21 -0
- data/app/assets/javascripts/controllers/session_controller.js +94 -0
- data/app/assets/manifest.js +2 -0
- data/app/assets/masks_manifest.js +2 -0
- data/app/assets/stylesheets/application.css +26 -0
- data/app/controllers/concerns/masks/controller.rb +114 -0
- data/app/controllers/masks/actors_controller.rb +15 -0
- data/app/controllers/masks/application_controller.rb +35 -0
- data/app/controllers/masks/backup_codes_controller.rb +34 -0
- data/app/controllers/masks/debug_controller.rb +9 -0
- data/app/controllers/masks/devices_controller.rb +20 -0
- data/app/controllers/masks/emails_controller.rb +60 -0
- data/app/controllers/masks/error_controller.rb +14 -0
- data/app/controllers/masks/keys_controller.rb +45 -0
- data/app/controllers/masks/manage/actor_controller.rb +35 -0
- data/app/controllers/masks/manage/actors_controller.rb +12 -0
- data/app/controllers/masks/manage/base_controller.rb +12 -0
- data/app/controllers/masks/one_time_code_controller.rb +49 -0
- data/app/controllers/masks/passwords_controller.rb +33 -0
- data/app/controllers/masks/recoveries_controller.rb +43 -0
- data/app/controllers/masks/sessions_controller.rb +53 -0
- data/app/helpers/masks/application_helper.rb +49 -0
- data/app/jobs/masks/application_job.rb +7 -0
- data/app/jobs/masks/expire_actors_job.rb +15 -0
- data/app/jobs/masks/expire_recoveries_job.rb +15 -0
- data/app/mailers/masks/actor_mailer.rb +22 -0
- data/app/mailers/masks/application_mailer.rb +15 -0
- data/app/models/concerns/masks/access.rb +162 -0
- data/app/models/concerns/masks/actor.rb +132 -0
- data/app/models/concerns/masks/adapter.rb +68 -0
- data/app/models/concerns/masks/role.rb +9 -0
- data/app/models/concerns/masks/scoped.rb +54 -0
- data/app/models/masks/access/actor_password.rb +20 -0
- data/app/models/masks/access/actor_scopes.rb +18 -0
- data/app/models/masks/access/actor_signup.rb +22 -0
- data/app/models/masks/actors/anonymous.rb +40 -0
- data/app/models/masks/actors/system.rb +24 -0
- data/app/models/masks/adapters/active_record.rb +85 -0
- data/app/models/masks/application_model.rb +15 -0
- data/app/models/masks/application_record.rb +8 -0
- data/app/models/masks/check.rb +192 -0
- data/app/models/masks/credential.rb +166 -0
- data/app/models/masks/credentials/backup_code.rb +30 -0
- data/app/models/masks/credentials/device.rb +59 -0
- data/app/models/masks/credentials/email.rb +48 -0
- data/app/models/masks/credentials/factor2.rb +71 -0
- data/app/models/masks/credentials/key.rb +38 -0
- data/app/models/masks/credentials/last_login.rb +12 -0
- data/app/models/masks/credentials/masquerade.rb +32 -0
- data/app/models/masks/credentials/nickname.rb +63 -0
- data/app/models/masks/credentials/one_time_code.rb +34 -0
- data/app/models/masks/credentials/password.rb +28 -0
- data/app/models/masks/credentials/recovery.rb +71 -0
- data/app/models/masks/credentials/session.rb +67 -0
- data/app/models/masks/device.rb +30 -0
- data/app/models/masks/error.rb +51 -0
- data/app/models/masks/event.rb +14 -0
- data/app/models/masks/mask.rb +255 -0
- data/app/models/masks/rails/actor.rb +190 -0
- data/app/models/masks/rails/actor_role.rb +12 -0
- data/app/models/masks/rails/device.rb +47 -0
- data/app/models/masks/rails/email.rb +96 -0
- data/app/models/masks/rails/key.rb +61 -0
- data/app/models/masks/rails/recovery.rb +116 -0
- data/app/models/masks/rails/role.rb +20 -0
- data/app/models/masks/rails/scope.rb +15 -0
- data/app/models/masks/session.rb +447 -0
- data/app/models/masks/sessions/access.rb +26 -0
- data/app/models/masks/sessions/inline.rb +16 -0
- data/app/models/masks/sessions/request.rb +42 -0
- data/app/resources/masks/actor_resource.rb +9 -0
- data/app/resources/masks/session_resource.rb +15 -0
- data/app/views/layouts/masks/application.html.erb +17 -0
- data/app/views/layouts/masks/mailer.html.erb +17 -0
- data/app/views/layouts/masks/mailer.text.erb +1 -0
- data/app/views/layouts/masks/manage.html.erb +25 -0
- data/app/views/masks/actor_mailer/recover_credentials.html.erb +33 -0
- data/app/views/masks/actor_mailer/recover_credentials.text.erb +1 -0
- data/app/views/masks/actor_mailer/verify_email.html.erb +34 -0
- data/app/views/masks/actor_mailer/verify_email.text.erb +8 -0
- data/app/views/masks/actors/current.html.erb +152 -0
- data/app/views/masks/application/_header.html.erb +31 -0
- data/app/views/masks/backup_codes/new.html.erb +103 -0
- data/app/views/masks/emails/new.html.erb +103 -0
- data/app/views/masks/emails/verify.html.erb +51 -0
- data/app/views/masks/keys/new.html.erb +127 -0
- data/app/views/masks/manage/actor/show.html.erb +126 -0
- data/app/views/masks/manage/actors/index.html.erb +40 -0
- data/app/views/masks/one_time_code/new.html.erb +150 -0
- data/app/views/masks/passwords/edit.html.erb +58 -0
- data/app/views/masks/recoveries/new.html.erb +71 -0
- data/app/views/masks/recoveries/password.html.erb +64 -0
- data/app/views/masks/sessions/new.html.erb +153 -0
- data/config/brakeman.ignore +28 -0
- data/config/locales/en.yml +286 -0
- data/config/routes.rb +46 -0
- data/db/migrate/20231205173845_create_actors.rb +94 -0
- data/lib/generators/masks/install/USAGE +8 -0
- data/lib/generators/masks/install/install_generator.rb +33 -0
- data/lib/generators/masks/install/templates/initializer.rb +5 -0
- data/lib/generators/masks/install/templates/masks.json +6 -0
- data/lib/masks/configuration.rb +236 -0
- data/lib/masks/engine.rb +25 -0
- data/lib/masks/middleware.rb +70 -0
- data/lib/masks/version.rb +5 -0
- data/lib/masks.rb +183 -0
- data/lib/tasks/masks_tasks.rake +71 -0
- data/masks.json +274 -0
- 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,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
|