masks-server 0.10.0 → 0.12.0
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.
- checksums.yaml +4 -4
- data/app/controllers/masks/server/account_controller.rb +3 -0
- data/app/controllers/masks/server/app_passwords_controller.rb +41 -0
- data/app/controllers/masks/server/authorize_controller.rb +33 -2
- data/app/controllers/masks/server/discovery_controller.rb +36 -0
- data/app/controllers/masks/server/enrollments_controller.rb +17 -0
- data/app/controllers/masks/server/forward_auth_controller.rb +104 -12
- data/app/controllers/masks/server/logins_controller.rb +4 -3
- data/app/controllers/masks/server/organization_access_controller.rb +39 -0
- data/app/controllers/masks/server/organization_members_controller.rb +3 -1
- data/app/graphql/masks/server/manage/mutations/base_mutation.rb +7 -0
- data/app/graphql/masks/server/manage/mutations/create_group.rb +6 -4
- data/app/graphql/masks/server/manage/mutations/decline_access.rb +27 -0
- data/app/graphql/masks/server/manage/mutations/grant_access.rb +29 -0
- data/app/graphql/masks/server/manage/mutations/group_source.rb +34 -0
- data/app/graphql/masks/server/manage/mutations/issue_ldap_credential.rb +5 -2
- data/app/graphql/masks/server/manage/mutations/refresh_group.rb +21 -0
- data/app/graphql/masks/server/manage/mutations/remove_group_member.rb +2 -0
- data/app/graphql/masks/server/manage/mutations/run_health_checks.rb +19 -0
- data/app/graphql/masks/server/manage/mutations/unenroll_client.rb +28 -0
- data/app/graphql/masks/server/manage/mutations/update_client.rb +6 -0
- data/app/graphql/masks/server/manage/mutations/update_group.rb +7 -4
- data/app/graphql/masks/server/manage/mutations/update_tenant.rb +14 -1
- data/app/graphql/masks/server/manage/types/access_request_type.rb +21 -0
- data/app/graphql/masks/server/manage/types/actor_type.rb +6 -0
- data/app/graphql/masks/server/manage/types/client_type.rb +18 -0
- data/app/graphql/masks/server/manage/types/group_condition_input.rb +16 -0
- data/app/graphql/masks/server/manage/types/group_condition_type.rb +29 -0
- data/app/graphql/masks/server/manage/types/group_member_type.rb +16 -0
- data/app/graphql/masks/server/manage/types/group_type.rb +17 -1
- data/app/graphql/masks/server/manage/types/health_check_type.rb +18 -0
- data/app/graphql/masks/server/manage/types/ldap_credential_type.rb +1 -0
- data/app/graphql/masks/server/manage/types/mutation_type.rb +5 -0
- data/app/graphql/masks/server/manage/types/query_type.rb +24 -0
- data/app/graphql/masks/server/manage/types/release_type.rb +16 -0
- data/app/graphql/masks/server/manage/types/tenant_type.rb +6 -1
- data/app/helpers/masks/server/account_helper.rb +4 -0
- data/app/jobs/masks/server/application_job.rb +28 -0
- data/app/jobs/masks/server/check_domain_claims_job.rb +1 -3
- data/app/jobs/masks/server/cleanup_job.rb +5 -6
- data/app/jobs/masks/server/health_check_job.rb +21 -0
- data/app/jobs/masks/server/idle_accounts_job.rb +1 -3
- data/app/jobs/masks/server/prune_queue_job.rb +19 -0
- data/app/jobs/masks/server/refresh_groups_job.rb +18 -0
- data/app/jobs/masks/server/refresh_saml_metadata_job.rb +1 -3
- data/app/jobs/masks/server/release_check_job.rb +21 -0
- data/app/jobs/masks/server/rotate_signing_keys_job.rb +1 -3
- data/app/jobs/masks/server/text_job.rb +12 -1
- data/app/ldap/masks/server/ldap/connection.rb +3 -2
- data/app/ldap/masks/server/ldap/gate.rb +31 -4
- data/app/logins/masks/server/login_states/second_factor.rb +1 -1
- data/app/mailers/masks/server/actor_mailer.rb +31 -0
- data/app/models/masks/server/access_request.rb +103 -0
- data/app/models/masks/server/actor.rb +6 -0
- data/app/models/masks/server/app_password.rb +91 -0
- data/app/models/masks/server/app_passwords.rb +82 -0
- data/app/models/masks/server/app_preset.rb +102 -0
- data/app/models/masks/server/boot_task.rb +41 -0
- data/app/models/masks/server/client.rb +15 -0
- data/app/models/masks/server/connection.rb +7 -0
- data/app/models/masks/server/declared.rb +10 -2
- data/app/models/masks/server/email_verification.rb +2 -2
- data/app/models/masks/server/enrollment_token.rb +1 -1
- data/app/models/masks/server/event.rb +15 -1
- data/app/models/masks/server/federation/protocol.rb +1 -1
- data/app/models/masks/server/federation/saml.rb +1 -1
- data/app/models/masks/server/forward_auth_rules.rb +162 -0
- data/app/models/masks/server/group.rb +207 -4
- data/app/models/masks/server/group_member.rb +7 -0
- data/app/models/masks/server/group_rule.rb +63 -0
- data/app/models/masks/server/health.rb +243 -0
- data/app/models/masks/server/health_check.rb +27 -0
- data/app/models/masks/server/invitation.rb +2 -2
- data/app/models/masks/server/job_failures.rb +25 -0
- data/app/models/masks/server/ldap_credential.rb +2 -2
- data/app/models/masks/server/login.rb +28 -2
- data/app/models/masks/server/mail_previews.rb +5 -0
- data/app/models/masks/server/mail_template.rb +2 -0
- data/app/models/masks/server/membership.rb +10 -3
- data/app/models/masks/server/notifications.rb +3 -1
- data/app/models/masks/server/password_reset.rb +2 -2
- data/app/models/masks/server/provider.rb +1 -0
- data/app/models/masks/server/queue.rb +60 -0
- data/app/models/masks/server/release.rb +74 -0
- data/app/models/masks/server/session.rb +8 -0
- data/app/models/masks/server/tenant.rb +39 -2
- data/app/models/masks/server/token.rb +2 -1
- data/app/views/masks/server/account/_app_passwords.html.erb +83 -0
- data/app/views/masks/server/account/_organizations.html.erb +33 -0
- data/app/views/masks/server/account/index.html.erb +5 -0
- data/app/views/masks/server/actor_mailer/access_declined.html.erb +5 -0
- data/app/views/masks/server/actor_mailer/access_declined.text.erb +5 -0
- data/app/views/masks/server/actor_mailer/access_granted.html.erb +7 -0
- data/app/views/masks/server/actor_mailer/access_granted.text.erb +7 -0
- data/app/views/masks/server/authorize/error.html.erb +25 -0
- data/config/locales/de/access_requests.yml +43 -0
- data/config/locales/de/account/app_passwords.yml +42 -0
- data/config/locales/de/events.yml +9 -0
- data/config/locales/de/flashes.yml +1 -0
- data/config/locales/de/group_sources.yml +5 -0
- data/config/locales/de/manage/access_requests.yml +12 -0
- data/config/locales/de/manage/app_passwords.yml +16 -0
- data/config/locales/de/manage/client.yml +1 -1
- data/config/locales/de/manage/forward_auth_rules.yml +29 -0
- data/config/locales/de/manage/group_sources.yml +44 -0
- data/config/locales/de/manage/health.yml +78 -0
- data/config/locales/de/manage/links.yml +20 -0
- data/config/locales/de/manage/machines.yml +13 -0
- data/config/locales/de/manage/namespaces.yml +1 -1
- data/config/locales/en/access_requests.yml +43 -0
- data/config/locales/en/account/app_passwords.yml +42 -0
- data/config/locales/en/events.yml +9 -0
- data/config/locales/en/flashes.yml +1 -0
- data/config/locales/en/group_sources.yml +5 -0
- data/config/locales/en/manage/access_requests.yml +12 -0
- data/config/locales/en/manage/app_passwords.yml +16 -0
- data/config/locales/en/manage/forward_auth_rules.yml +29 -0
- data/config/locales/en/manage/group_sources.yml +44 -0
- data/config/locales/en/manage/health.yml +78 -0
- data/config/locales/en/manage/links.yml +20 -0
- data/config/locales/en/manage/machines.yml +13 -0
- data/config/locales/es/access_requests.yml +43 -0
- data/config/locales/es/account/app_passwords.yml +42 -0
- data/config/locales/es/events.yml +9 -0
- data/config/locales/es/flashes.yml +1 -0
- data/config/locales/es/group_sources.yml +5 -0
- data/config/locales/es/handshakes.yml +1 -1
- data/config/locales/es/manage/access_requests.yml +12 -0
- data/config/locales/es/manage/app_passwords.yml +16 -0
- data/config/locales/es/manage/forward_auth_rules.yml +29 -0
- data/config/locales/es/manage/group_sources.yml +44 -0
- data/config/locales/es/manage/health.yml +78 -0
- data/config/locales/es/manage/links.yml +20 -0
- data/config/locales/es/manage/machines.yml +13 -0
- data/config/locales/fr/access_requests.yml +43 -0
- data/config/locales/fr/account/app_passwords.yml +42 -0
- data/config/locales/fr/events.yml +9 -0
- data/config/locales/fr/flashes.yml +1 -0
- data/config/locales/fr/group_sources.yml +5 -0
- data/config/locales/fr/handshakes.yml +1 -1
- data/config/locales/fr/manage/access_requests.yml +12 -0
- data/config/locales/fr/manage/app_passwords.yml +16 -0
- data/config/locales/fr/manage/client.yml +1 -1
- data/config/locales/fr/manage/clients.yml +1 -1
- data/config/locales/fr/manage/forward_auth_rules.yml +29 -0
- data/config/locales/fr/manage/group_sources.yml +44 -0
- data/config/locales/fr/manage/health.yml +78 -0
- data/config/locales/fr/manage/links.yml +20 -0
- data/config/locales/fr/manage/machines.yml +13 -0
- data/config/locales/fr/manage/providers.yml +1 -1
- data/config/routes.rb +6 -0
- data/db/migrate/20261019140000_add_indexes_for_cleanup_and_metrics.rb +10 -0
- data/db/migrate/20261020100000_create_access_requests.rb +28 -0
- data/db/migrate/20261020110000_add_app_passwords_to_clients.rb +5 -0
- data/db/migrate/20261020120000_add_forward_auth_rules_to_clients.rb +6 -0
- data/db/migrate/20261020130000_add_sources_to_groups.rb +15 -0
- data/db/migrate/20261020140000_create_health_checks.rb +25 -0
- data/db/migrate/20261020150000_add_link_lifetimes_to_tenants.rb +8 -0
- data/db/migrate/20261021100000_add_pinned_origin_to_tenants.rb +5 -0
- data/lib/generators/masks/server/install/install_generator.rb +3 -2
- data/lib/masks/server/configuration.rb +6 -11
- data/lib/masks/server/schema_reference.rb +12 -0
- data/lib/masks/server/tenancy/middleware.rb +17 -6
- data/lib/tasks/masks.rake +31 -7
- data/public/masks-assets/.vite/manifest.json +13 -13
- data/public/masks-assets/assets/{account-D46qDQCo.js → account-h7I6VUPR.js} +2 -2
- data/public/masks-assets/assets/{account-D46qDQCo.js.map → account-h7I6VUPR.js.map} +1 -1
- data/public/masks-assets/assets/{app-D7W0gAyT.css → app-BXOScMjL.css} +1 -1
- data/public/masks-assets/assets/{handshake-DIFZPSAK.js → handshake-YQpRNMIs.js} +2 -2
- data/public/masks-assets/assets/{handshake-DIFZPSAK.js.map → handshake-YQpRNMIs.js.map} +1 -1
- data/public/masks-assets/assets/initial-Cn-UuAsy.js +3 -0
- data/public/masks-assets/assets/{initial-C1GpCiEh.js.map → initial-Cn-UuAsy.js.map} +1 -1
- data/public/masks-assets/assets/{login-C_6igRZ3.js → login-C21_jb6L.js} +3 -3
- data/public/masks-assets/assets/{login-C_6igRZ3.js.map → login-C21_jb6L.js.map} +1 -1
- data/public/masks-assets/assets/{manage-DR9qQiBU.js → manage-DpVxe5sv.js} +86 -50
- data/public/masks-assets/assets/manage-DpVxe5sv.js.map +1 -0
- data/public/masks-assets/assets/passkey-5UYPVD3c.js +2 -0
- data/public/masks-assets/assets/{passkey-DIj_5LCY.js.map → passkey-5UYPVD3c.js.map} +1 -1
- data/version.txt +1 -1
- metadata +96 -14
- data/public/masks-assets/assets/initial-C1GpCiEh.js +0 -3
- data/public/masks-assets/assets/manage-DR9qQiBU.js.map +0 -1
- data/public/masks-assets/assets/passkey-DIj_5LCY.js +0 -2
|
@@ -64,6 +64,12 @@ module Masks
|
|
|
64
64
|
|
|
65
65
|
IDLE_DAYS = (60..3650)
|
|
66
66
|
RETENTION_DAYS = (30..2555)
|
|
67
|
+
LINK_LIFETIMES = {
|
|
68
|
+
invitation_lifetime: (1.hour.to_i..30.days.to_i),
|
|
69
|
+
organization_invitation_lifetime: (1.hour.to_i..30.days.to_i),
|
|
70
|
+
password_reset_lifetime: (5.minutes.to_i..1.day.to_i),
|
|
71
|
+
email_verification_lifetime: (1.hour.to_i..14.days.to_i)
|
|
72
|
+
}.freeze
|
|
67
73
|
|
|
68
74
|
validates :named_by, inclusion: { in: NAMES }, allow_nil: true
|
|
69
75
|
validates :accent_color, format: { with: ACCENT }, allow_nil: true
|
|
@@ -71,6 +77,18 @@ module Masks
|
|
|
71
77
|
validates :dynamic_registration, inclusion: { in: REGISTRATIONS }, allow_nil: true
|
|
72
78
|
validates :suspend_after, :delete_after, numericality: { only_integer: true, in: IDLE_DAYS }, allow_nil: true
|
|
73
79
|
validates :event_retention_days, numericality: { only_integer: true, in: RETENTION_DAYS }, allow_nil: true
|
|
80
|
+
def self.spoken(seconds)
|
|
81
|
+
unit, length = { "day" => 1.day, "hour" => 1.hour, "minute" => 1.minute }.find { |_, held| (seconds % held).zero? }
|
|
82
|
+
count = seconds / length
|
|
83
|
+
|
|
84
|
+
"#{count} #{unit.pluralize(count)}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
LINK_LIFETIMES.each do |name, range|
|
|
88
|
+
shortest, longest = [ range.begin, range.end ].map { |seconds| spoken(seconds) }
|
|
89
|
+
|
|
90
|
+
validates name, numericality: { only_integer: true, in: range, message: "must be from #{shortest} to #{longest}" }
|
|
91
|
+
end
|
|
74
92
|
validates :delete_after, comparison: { greater_than: :suspend_after, message: "must be longer than suspend after" },
|
|
75
93
|
if: -> { suspend_after && delete_after }
|
|
76
94
|
|
|
@@ -104,8 +122,20 @@ module Masks
|
|
|
104
122
|
event_retention_days&.days || Event::RETENTION
|
|
105
123
|
end
|
|
106
124
|
|
|
125
|
+
def self.link_lifetime(name, tenant = Current.tenant)
|
|
126
|
+
(tenant ? tenant[name] : column_defaults.fetch(name.to_s)).seconds
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def self.default_link_lifetime(name)
|
|
130
|
+
column_defaults.fetch(name.to_s)
|
|
131
|
+
end
|
|
132
|
+
|
|
107
133
|
def public_origin
|
|
108
|
-
custom_origin || templated_origin
|
|
134
|
+
custom_origin || templated_origin || held_origin
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def held_origin
|
|
138
|
+
pinned_origin if self.class.pins_origin?
|
|
109
139
|
end
|
|
110
140
|
|
|
111
141
|
def templated_origin
|
|
@@ -246,6 +276,10 @@ module Masks
|
|
|
246
276
|
serving(host) || named(host)
|
|
247
277
|
end
|
|
248
278
|
|
|
279
|
+
def pins_origin?
|
|
280
|
+
::Rails.configuration.masks.public_origin_template.nil? && ::Rails.configuration.masks.pin_origin
|
|
281
|
+
end
|
|
282
|
+
|
|
249
283
|
def served_domain
|
|
250
284
|
template = ::Rails.configuration.masks.public_origin_template
|
|
251
285
|
|
|
@@ -403,7 +437,10 @@ module Masks
|
|
|
403
437
|
end
|
|
404
438
|
|
|
405
439
|
def set_up!
|
|
406
|
-
|
|
440
|
+
self.setup_token = nil
|
|
441
|
+
self.pinned_origin ||= Current.origin.presence if self.class.pins_origin?
|
|
442
|
+
|
|
443
|
+
save! if changed?
|
|
407
444
|
end
|
|
408
445
|
|
|
409
446
|
def setup_announcement
|
|
@@ -22,7 +22,8 @@ module Masks
|
|
|
22
22
|
"pushed" => "PushedRequest",
|
|
23
23
|
"approval" => "SignInApproval",
|
|
24
24
|
"forward_code" => "ForwardCode",
|
|
25
|
-
"forward_session" => "ForwardSession"
|
|
25
|
+
"forward_session" => "ForwardSession",
|
|
26
|
+
"app_password" => "AppPassword"
|
|
26
27
|
}.freeze
|
|
27
28
|
|
|
28
29
|
self.inheritance_column = "kind"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<section class="group" id="app-passwords">
|
|
2
|
+
<h2><%= account_text("app_passwords.heading") %></h2>
|
|
3
|
+
|
|
4
|
+
<div class="entries">
|
|
5
|
+
<details class="entry" <%= "open" if app_password %>>
|
|
6
|
+
<summary>
|
|
7
|
+
<span class="entry-icon"><%= account_icon(:password) %></span>
|
|
8
|
+
<span class="entry-label"><%= account_text("app_passwords.entry") %></span>
|
|
9
|
+
<span class="entry-state">
|
|
10
|
+
<%= app_passwords.any? ? app_passwords.size : account_text("app_passwords.state.none") %>
|
|
11
|
+
</span>
|
|
12
|
+
<span class="entry-mark" aria-hidden="true"></span>
|
|
13
|
+
</summary>
|
|
14
|
+
|
|
15
|
+
<div class="entry-body">
|
|
16
|
+
<p class="aside"><%= account_text("app_passwords.lede") %></p>
|
|
17
|
+
|
|
18
|
+
<% if app_password %>
|
|
19
|
+
<p class="aside aside-bad" role="alert">
|
|
20
|
+
<%= account_text("app_passwords.shown_once", name: app_password["name"], app: app_password["app"]) %>
|
|
21
|
+
</p>
|
|
22
|
+
|
|
23
|
+
<ol class="codes">
|
|
24
|
+
<li><code><%= app_password["secret"] %></code></li>
|
|
25
|
+
</ol>
|
|
26
|
+
<% end %>
|
|
27
|
+
|
|
28
|
+
<% if app_passwords.any? %>
|
|
29
|
+
<div class="items">
|
|
30
|
+
<% app_passwords.each do |held| %>
|
|
31
|
+
<div class="item">
|
|
32
|
+
<span class="item-name">
|
|
33
|
+
<span><%= held.name %></span>
|
|
34
|
+
<span class="tag"><%= held.client.name %></span>
|
|
35
|
+
</span>
|
|
36
|
+
|
|
37
|
+
<span class="item-meta">
|
|
38
|
+
<%= account_text("app_passwords.made_ago", age: time_ago_in_words(held.created_at)) %>
|
|
39
|
+
·
|
|
40
|
+
<% if held.used_at %>
|
|
41
|
+
<%= account_text("app_passwords.used_ago", age: time_ago_in_words(held.used_at)) %>
|
|
42
|
+
<% else %>
|
|
43
|
+
<%= account_text("app_passwords.never_used") %>
|
|
44
|
+
<% end %>
|
|
45
|
+
</span>
|
|
46
|
+
|
|
47
|
+
<%= button_to account_text("app_passwords.revoke"),
|
|
48
|
+
account_app_password_path(held.id), method: :delete,
|
|
49
|
+
class: "action action-quiet action-sm", form_class: "item-act",
|
|
50
|
+
form: { data: { turbo_confirm: account_text("app_passwords.confirm_revoke", name: held.name) } } %>
|
|
51
|
+
</div>
|
|
52
|
+
<% end %>
|
|
53
|
+
</div>
|
|
54
|
+
<% end %>
|
|
55
|
+
|
|
56
|
+
<% if offered.any? %>
|
|
57
|
+
<%= form_with url: account_app_passwords_path, method: :post, class: "member-add" do |form| %>
|
|
58
|
+
<label class="field member-add-email">
|
|
59
|
+
<span class="field-label"><%= account_text("app_passwords.name") %></span>
|
|
60
|
+
<%= form.text_field :name, required: true, autocomplete: "off", class: "control", id: "app-password-name",
|
|
61
|
+
maxlength: Masks::Server::AppPassword::NAME_LIMIT,
|
|
62
|
+
placeholder: account_text("app_passwords.name_placeholder") %>
|
|
63
|
+
</label>
|
|
64
|
+
|
|
65
|
+
<label class="field member-add-role">
|
|
66
|
+
<span class="field-label"><%= account_text("app_passwords.app") %></span>
|
|
67
|
+
<%= form.select :client_id, offered.map { |client| [ client.name, client.client_id ] }, {}, class: "control",
|
|
68
|
+
id: "app-password-client" %>
|
|
69
|
+
</label>
|
|
70
|
+
|
|
71
|
+
<button type="submit" class="action action-sm member-add-go">
|
|
72
|
+
<%= account_text(fresh ? "app_passwords.make" : "app_passwords.make_again") %>
|
|
73
|
+
</button>
|
|
74
|
+
|
|
75
|
+
<span class="field-hint member-add-hint"><%= account_text("app_passwords.hint") %></span>
|
|
76
|
+
<% end %>
|
|
77
|
+
<% else %>
|
|
78
|
+
<p class="aside"><%= account_text("app_passwords.none_offered") %></p>
|
|
79
|
+
<% end %>
|
|
80
|
+
</div>
|
|
81
|
+
</details>
|
|
82
|
+
</div>
|
|
83
|
+
</section>
|
|
@@ -135,6 +135,39 @@
|
|
|
135
135
|
<% end %>
|
|
136
136
|
</div>
|
|
137
137
|
|
|
138
|
+
<% asked = account_access_requests(organization) %>
|
|
139
|
+
<% if asked.any? %>
|
|
140
|
+
<p class="aside"><strong><%= account_text("access.heading") %></strong> <%= account_text("access.lede", organization: organization.name) %></p>
|
|
141
|
+
|
|
142
|
+
<div class="items" id="access-requests-<%= organization.key %>">
|
|
143
|
+
<% asked.each do |request| %>
|
|
144
|
+
<% roles = request.organization_roles.filter_map { |key, role| role if key == organization.key } %>
|
|
145
|
+
<div class="item item-member access-request" id="access-request-<%= request.id %>">
|
|
146
|
+
<span class="item-name"><%= request.actor.identifier %></span>
|
|
147
|
+
<span class="item-meta">
|
|
148
|
+
<%= account_text("access.asked", app: request.client.name, age: time_ago_in_words(request.created_at)) %>
|
|
149
|
+
</span>
|
|
150
|
+
|
|
151
|
+
<div class="item-act item-acts">
|
|
152
|
+
<%= form_with url: account_organization_access_path(organization.key, request.id), method: :post,
|
|
153
|
+
class: "item-acts" do |form| %>
|
|
154
|
+
<%= form.select :role, roles, {}, class: "control control-sm",
|
|
155
|
+
id: "access-role-#{organization.key}-#{request.id}",
|
|
156
|
+
aria: { label: account_text("access.role_of", name: request.actor.identifier) } %>
|
|
157
|
+
<button type="submit" class="action action-sm"><%= account_text("access.grant") %></button>
|
|
158
|
+
<% end %>
|
|
159
|
+
|
|
160
|
+
<%= button_to account_text("access.decline"),
|
|
161
|
+
account_organization_access_path(organization.key, request.id), method: :delete,
|
|
162
|
+
class: "action action-quiet action-sm",
|
|
163
|
+
form: { data: { turbo_confirm: account_text("access.confirm_decline", identifier: request.actor.identifier,
|
|
164
|
+
app: request.client.name) } } %>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
<% end %>
|
|
168
|
+
</div>
|
|
169
|
+
<% end %>
|
|
170
|
+
|
|
138
171
|
<%= form_with url: account_organization_members_path(organization.key), method: :post, class: "member-add" do |form| %>
|
|
139
172
|
<label class="field member-add-email">
|
|
140
173
|
<span class="field-label"><%= account_text("organizations.add_email") %></span>
|
|
@@ -31,6 +31,11 @@
|
|
|
31
31
|
|
|
32
32
|
<%= render "masks/server/account/apps", apps: @apps, connections: @connections, linkable: @linkable %>
|
|
33
33
|
|
|
34
|
+
<% if @app_passwords.any? || @app_password_clients.any? %>
|
|
35
|
+
<%= render "masks/server/account/app_passwords", app_passwords: @app_passwords, offered: @app_password_clients,
|
|
36
|
+
app_password: @app_password, fresh: @fresh %>
|
|
37
|
+
<% end %>
|
|
38
|
+
|
|
34
39
|
<%= render "masks/server/account/info", actor: @actor, directed: @directed, fresh: @fresh %>
|
|
35
40
|
|
|
36
41
|
<%= render "masks/server/account/activity", events: @events %>
|
|
@@ -9,4 +9,29 @@
|
|
|
9
9
|
<p class="said"><%= @error_code %> — <%= @error_description %></p>
|
|
10
10
|
|
|
11
11
|
<p class="prompt-lede"><%= @refused ? t(".nothing_shared") : t(".contact") %></p>
|
|
12
|
+
|
|
13
|
+
<% if @asking %>
|
|
14
|
+
<div id="ask-access" class="flow" data-waiting="<%= @waiting.present? %>">
|
|
15
|
+
<% if flash[:alert].present? %>
|
|
16
|
+
<p class="note note-bad" role="alert"><%= flash[:alert] %></p>
|
|
17
|
+
<% elsif flash[:notice].present? %>
|
|
18
|
+
<p class="note note-plain" role="status"><%= flash[:notice] %></p>
|
|
19
|
+
<% end %>
|
|
20
|
+
|
|
21
|
+
<% if @waiting %>
|
|
22
|
+
<p class="prompt-lede"><%= t(".waiting", app: @asking.name) %></p>
|
|
23
|
+
<% else %>
|
|
24
|
+
<p class="prompt-lede"><%= t(".asking", app: @asking.name) %></p>
|
|
25
|
+
|
|
26
|
+
<%= form_with url: authorize_access_request_path, method: :post do |form| %>
|
|
27
|
+
<%= form.hidden_field :rid, value: params[:rid] %>
|
|
28
|
+
<button type="submit" class="action"><%= t(".ask") %></button>
|
|
29
|
+
<% end %>
|
|
30
|
+
<% end %>
|
|
31
|
+
</div>
|
|
32
|
+
<% end %>
|
|
33
|
+
|
|
34
|
+
<% if @return_to %>
|
|
35
|
+
<a class="action action-quiet" id="back-to-app" href="<%= @return_to %>"><%= t(".back", app: @asking&.name || t(".the_app")) %></a>
|
|
36
|
+
<% end %>
|
|
12
37
|
</div>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
de:
|
|
2
|
+
authorize:
|
|
3
|
+
error:
|
|
4
|
+
asking: "Ihr Konto ist in keiner Gruppe, die %{app} nutzen darf. Sie können um Zugang bitten. Die Betreiber von %{app} entscheiden, und Sie erhalten in jedem Fall eine E-Mail."
|
|
5
|
+
ask: "Um Zugang bitten"
|
|
6
|
+
asked: "Ihre Anfrage wurde gesendet. Sie erhalten eine E-Mail, sobald sie entschieden ist."
|
|
7
|
+
waiting: "Ihre Anfrage, %{app} zu nutzen, wartet. Sie erhalten eine E-Mail, sobald sie entschieden ist."
|
|
8
|
+
slow_down: "Sie haben vor weniger als einer Stunde um Zugang zu dieser App gebeten. Warten Sie auf die Antwort."
|
|
9
|
+
back: "Zurück zu %{app}"
|
|
10
|
+
the_app: "der App"
|
|
11
|
+
|
|
12
|
+
account:
|
|
13
|
+
index:
|
|
14
|
+
access:
|
|
15
|
+
heading: "Um Zugang gebeten"
|
|
16
|
+
lede: "Diese Personen wurden von einer App abgewiesen, die Mitglieder von %{organization} zulässt. Mit Genehmigen werden sie Mitglied mit der Rolle, die Sie wählen."
|
|
17
|
+
asked: "Hat vor %{age} gebeten, %{app} zu nutzen"
|
|
18
|
+
role_of: "Rolle für %{name}"
|
|
19
|
+
grant: "Genehmigen"
|
|
20
|
+
decline: "Ablehnen"
|
|
21
|
+
confirm_decline: "Die Anfrage von %{identifier}, %{app} zu nutzen, ablehnen? Die Person erhält eine E-Mail und kann in einer Stunde erneut bitten."
|
|
22
|
+
|
|
23
|
+
organization_access:
|
|
24
|
+
granted: "%{identifier} ist jetzt %{role} von %{organization} und kann %{app} nutzen."
|
|
25
|
+
declined: "Die Anfrage von %{identifier}, %{app} zu nutzen, ist abgelehnt."
|
|
26
|
+
unknown: "Diese Anfrage wartet nicht auf %{organization}."
|
|
27
|
+
|
|
28
|
+
actor_mailer:
|
|
29
|
+
access_granted:
|
|
30
|
+
subject: "Sie können %{app} jetzt nutzen"
|
|
31
|
+
lede: "Ihre Anfrage, %{app} bei %{tenant} zu nutzen, wurde genehmigt. Melden Sie sich erneut bei %{app} an, und Sie werden eingelassen."
|
|
32
|
+
action: "%{app} öffnen"
|
|
33
|
+
access_declined:
|
|
34
|
+
subject: "Ihre Anfrage, %{app} zu nutzen, wurde abgelehnt"
|
|
35
|
+
lede: "Jemand, der %{app} bei %{tenant} betreibt, hat Ihre Anfrage um Zugang abgelehnt."
|
|
36
|
+
again: "Wenn Sie das für einen Fehler halten, fragen Sie die Person direkt. In einer Stunde können Sie erneut bitten."
|
|
37
|
+
|
|
38
|
+
events:
|
|
39
|
+
actions:
|
|
40
|
+
access:
|
|
41
|
+
requested: "Um Zugang zu einer App gebeten"
|
|
42
|
+
granted: "Zugang zu einer App genehmigt"
|
|
43
|
+
declined: "Zugang zu einer App abgelehnt"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
de:
|
|
2
|
+
account:
|
|
3
|
+
index:
|
|
4
|
+
app_passwords:
|
|
5
|
+
heading: "App-Passwörter"
|
|
6
|
+
entry: "App-Passwörter"
|
|
7
|
+
state:
|
|
8
|
+
none: "Keine"
|
|
9
|
+
lede: "Mit einem App-Passwort meldet sich eine einzelne App, etwa ein Medienserver oder ein NAS, ohne Ihren zweiten Faktor als Sie an. Es gilt nur für die App, für die es erstellt wurde."
|
|
10
|
+
shown_once: "Das ist das App-Passwort für %{name}. Es wird nur einmal angezeigt. Geben Sie es jetzt in %{app} ein."
|
|
11
|
+
made_ago: "erstellt vor %{age}"
|
|
12
|
+
used_ago: "zuletzt verwendet vor %{age}"
|
|
13
|
+
never_used: "nie verwendet"
|
|
14
|
+
revoke: "Widerrufen"
|
|
15
|
+
confirm_revoke: "%{name} widerrufen? Die App kann sich damit sofort nicht mehr anmelden."
|
|
16
|
+
name: "Name"
|
|
17
|
+
name_placeholder: "Jellyfin auf dem Fernseher"
|
|
18
|
+
app: "App"
|
|
19
|
+
make: "App-Passwort erstellen"
|
|
20
|
+
make_again: "Zum Erstellen erneut anmelden"
|
|
21
|
+
hint: "Ihr eigenes Passwort und Ihre Passkeys bleiben unverändert. Das Widerrufen eines App-Passworts ändert sonst nichts."
|
|
22
|
+
none_offered: "Noch keine App akzeptiert App-Passwörter."
|
|
23
|
+
app_passwords:
|
|
24
|
+
again: "Melden Sie sich erneut an, um ein App-Passwort zu erstellen. Ihre letzte Anmeldung liegt eine Weile zurück."
|
|
25
|
+
unknown: "Dieses Konto hat kein solches App-Passwort."
|
|
26
|
+
revoked: "%{name} ist widerrufen."
|
|
27
|
+
refused:
|
|
28
|
+
name: "Geben Sie dem App-Passwort einen Namen mit höchstens 64 Zeichen."
|
|
29
|
+
app: "Diese App akzeptiert keine App-Passwörter."
|
|
30
|
+
too_many: "Sie haben bereits %{most} App-Passwörter. Widerrufen Sie zuerst eines."
|
|
31
|
+
events:
|
|
32
|
+
actions:
|
|
33
|
+
app_password:
|
|
34
|
+
created: "App-Passwort erstellt"
|
|
35
|
+
used: "Mit einem App-Passwort angemeldet"
|
|
36
|
+
revoked: "App-Passwort widerrufen"
|
|
37
|
+
actor_mailer:
|
|
38
|
+
notification:
|
|
39
|
+
said:
|
|
40
|
+
app_password:
|
|
41
|
+
created: "Für Ihr %{tenant}-Konto wurde ein App-Passwort erstellt. Damit meldet sich eine App ohne Ihren zweiten Faktor an."
|
|
42
|
+
revoked: "Ein App-Passwort Ihres %{tenant}-Kontos wurde widerrufen."
|
|
@@ -157,6 +157,13 @@ de:
|
|
|
157
157
|
exported: "Aktivität exportiert"
|
|
158
158
|
mail_template:
|
|
159
159
|
updated: "E-Mail-Vorlage geändert"
|
|
160
|
+
job:
|
|
161
|
+
failed: "Hintergrundjob für diesen Mandanten fehlgeschlagen"
|
|
162
|
+
health:
|
|
163
|
+
failing: "Zustandsprüfung fehlgeschlagen"
|
|
164
|
+
recovered: "Zustandsprüfung wieder in Ordnung"
|
|
165
|
+
release:
|
|
166
|
+
available: "Neue Version verfügbar"
|
|
160
167
|
stream:
|
|
161
168
|
created: "Event-Stream hinzugefügt"
|
|
162
169
|
updated: "Event-Stream geändert"
|
|
@@ -171,6 +178,8 @@ de:
|
|
|
171
178
|
signal:
|
|
172
179
|
undelivered: "Shared Signal nicht zugestellt"
|
|
173
180
|
received: "Anbieter hat Abmeldung signalisiert"
|
|
181
|
+
text:
|
|
182
|
+
undelivered: "SMS nicht zugestellt"
|
|
174
183
|
organization:
|
|
175
184
|
created: "Organisation hinzugefügt"
|
|
176
185
|
updated: "Organisation geändert"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
de:
|
|
2
|
+
manage:
|
|
3
|
+
access_requests:
|
|
4
|
+
title: "Zugangsanfragen"
|
|
5
|
+
lede: "Akteure, die von diesem Client abgewiesen wurden und um Zugang gebeten haben. Mit Genehmigen kommen sie in eine der Gruppen, die er zulässt, und sie erhalten in jedem Fall eine E-Mail."
|
|
6
|
+
empty: "Niemand wartet auf Zugang."
|
|
7
|
+
asked: "Gebeten %{day}"
|
|
8
|
+
as: "Gruppe, in die sie kommen"
|
|
9
|
+
grant: "Genehmigen"
|
|
10
|
+
decline: "Ablehnen"
|
|
11
|
+
granted: "%{identifier} ist jetzt in %{label} und kann sich anmelden."
|
|
12
|
+
declined: "Die Anfrage von %{identifier} ist abgelehnt."
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
de:
|
|
2
|
+
manage:
|
|
3
|
+
client:
|
|
4
|
+
sign_in:
|
|
5
|
+
app_passwords: "App-Passwörter akzeptieren"
|
|
6
|
+
app_passwords_help: "Akteure erstellen auf ihrer Kontoseite ein App-Passwort für diesen Client. Es meldet sie über LDAP und Forward-Auth ohne zweiten Faktor an, nur bei diesem Client."
|
|
7
|
+
notices:
|
|
8
|
+
app_passwords_on: "Akteure können jetzt ein App-Passwort dafür erstellen."
|
|
9
|
+
app_passwords_off: "Seine App-Passwörter werden ab jetzt abgelehnt."
|
|
10
|
+
ldap:
|
|
11
|
+
connect:
|
|
12
|
+
app: "App"
|
|
13
|
+
no_app: "Keine App"
|
|
14
|
+
app_help: "Wählen Sie den Client, als der der Dienst registriert ist. App-Passwörter der Akteure für diesen Client binden dann auf einer Verbindung, die sich zuerst mit diesem Zugang gebunden hat."
|
|
15
|
+
credentials:
|
|
16
|
+
app: "Akzeptiert App-Passwörter für %{name}"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
de:
|
|
2
|
+
manage:
|
|
3
|
+
forward_auth_rules:
|
|
4
|
+
title: "Regeln"
|
|
5
|
+
lede: "Die erste Regel, die eine Anfrage abdeckt, entscheidet sie. Eine Anfrage ohne passende Regel braucht eine angemeldete Person, die sich anmelden darf."
|
|
6
|
+
empty: "Es gibt keine Regeln. Jede Anfrage braucht eine angemeldete Person, die sich anmelden darf."
|
|
7
|
+
paths: "Pfade"
|
|
8
|
+
paths_hint: "Einer pro Zeile. * deckt ein Segment ab und ** jede Tiefe, also deckt /admin/** /admin und alles darunter ab. Leer deckt jeden Pfad ab."
|
|
9
|
+
methods: "Methoden"
|
|
10
|
+
methods_hint: "GET, POST und so weiter. Leer deckt jede Methode ab."
|
|
11
|
+
networks: "Netzwerke"
|
|
12
|
+
networks_hint: "Adressen oder Bereiche wie 192.168.0.0/16. Leer deckt jede Adresse ab."
|
|
13
|
+
groups: "Gruppen"
|
|
14
|
+
groups_hint: "Gruppenschlüssel oder Rollen als schlüssel:rolle. Leer deckt alle ab."
|
|
15
|
+
outcome: "Ergebnis"
|
|
16
|
+
outcomes:
|
|
17
|
+
open: "Offen für alle, ohne Anmeldung"
|
|
18
|
+
one_factor: "Eine angemeldete Person, ohne zweiten Faktor"
|
|
19
|
+
two_factor: "Eine angemeldete Person, mit ihrem zweiten Faktor"
|
|
20
|
+
token: "Eine angemeldete Person oder ein Skript mit einem Zugriffstoken"
|
|
21
|
+
deny: "Für alle gesperrt"
|
|
22
|
+
rule: "Regel %{number}"
|
|
23
|
+
add: "Regel hinzufügen"
|
|
24
|
+
remove: "Entfernen"
|
|
25
|
+
up: "Nach oben"
|
|
26
|
+
down: "Nach unten"
|
|
27
|
+
save: "Regeln speichern"
|
|
28
|
+
saved: "Regeln gespeichert."
|
|
29
|
+
trust: "Eine Netzwerkregel vertraut der Adresse, die der Proxy sendet. Stellen Sie sicher, dass der Proxy X-Forwarded-For selbst setzt."
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
de:
|
|
2
|
+
manage:
|
|
3
|
+
group_sources:
|
|
4
|
+
source: "Füllt sich aus"
|
|
5
|
+
sources:
|
|
6
|
+
manual: "Von Hand hinzugefügte Personen"
|
|
7
|
+
rule: "Einer Regel"
|
|
8
|
+
provider: "Einem Anbieter"
|
|
9
|
+
group: "Anderen Gruppen"
|
|
10
|
+
ledes:
|
|
11
|
+
manual: "Ein Verwalter fügt Personen auf deren eigenen Seiten hinzu und entfernt sie dort."
|
|
12
|
+
rule: "Alle, die jede Bedingung erfüllen. Eine E-Mail-Adresse zählt, sobald sie bestätigt ist. Ein Profilfeld zählt nur, wenn ein Verzeichnis es setzt, denn solche Felder können Personen nicht ändern. Geprüft bei jeder Profiländerung und jede Stunde."
|
|
13
|
+
provider: "Alle, deren letzte Anmeldung über den Anbieter die Gruppe aufgeführt hat."
|
|
14
|
+
group: "Alle in einer der übergeordneten Gruppen oder Organisationsrollen."
|
|
15
|
+
change: "Ändern, wie sich %{name} füllt"
|
|
16
|
+
kinds:
|
|
17
|
+
email_domain: "E-Mail-Adresse endet auf"
|
|
18
|
+
profile: "Profilfeld ist gleich"
|
|
19
|
+
field: "Feld"
|
|
20
|
+
value: "Wert"
|
|
21
|
+
add_condition: "Bedingung hinzufügen"
|
|
22
|
+
remove_condition: "Bedingung entfernen"
|
|
23
|
+
provider: "Anbieter"
|
|
24
|
+
choose_provider: "Anbieter wählen"
|
|
25
|
+
no_providers: "Fügen Sie zuerst einen Anbieter hinzu."
|
|
26
|
+
upstream_group: "Gruppenname beim Anbieter"
|
|
27
|
+
parent_labels: "Übergeordnete Gruppen"
|
|
28
|
+
parent_labels_hint: "Gruppenschlüssel oder Organisationsrollen als schlüssel:rolle, durch Kommas getrennt."
|
|
29
|
+
save: "Speichern"
|
|
30
|
+
cancel: "Abbrechen"
|
|
31
|
+
saved: "%{name} füllt sich jetzt aus %{source}."
|
|
32
|
+
refresh: "Jetzt auffrischen"
|
|
33
|
+
refreshed: "%{name} ist aufgefrischt."
|
|
34
|
+
refreshed_at: "Aufgefrischt %{when}."
|
|
35
|
+
never_refreshed: "Noch nicht aufgefrischt."
|
|
36
|
+
summary:
|
|
37
|
+
rule: "Füllt sich per Regel"
|
|
38
|
+
provider: "Füllt sich aus %{provider}"
|
|
39
|
+
group: "Füllt sich aus %{parents}"
|
|
40
|
+
by_hand: "Von Hand hinzugefügt, daher entfernt nur ein Verwalter die Person."
|
|
41
|
+
from:
|
|
42
|
+
rule: "Durch die Regel in der Gruppe, daher entscheidet die Regel."
|
|
43
|
+
provider: "Durch eine Anmeldung beim Anbieter in der Gruppe, daher entscheidet der Anbieter."
|
|
44
|
+
group: "Über eine übergeordnete Gruppe in der Gruppe, daher entscheidet diese."
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
de:
|
|
2
|
+
manage:
|
|
3
|
+
health:
|
|
4
|
+
title: "Zustand"
|
|
5
|
+
lede: "Die Prüfungen laufen alle 10 Minuten. Jede sagt, was sie gefunden hat und was zu tun ist."
|
|
6
|
+
check_now: "Jetzt prüfen"
|
|
7
|
+
checking: "Prüft"
|
|
8
|
+
checked: "Geprüft %{when}"
|
|
9
|
+
never: "Die Prüfungen sind noch nicht gelaufen. Sie laufen alle 10 Minuten, sobald ein Worker läuft."
|
|
10
|
+
failed: "Die Prüfungen konnten nicht laufen: %{failure}"
|
|
11
|
+
statuses:
|
|
12
|
+
ok: "In Ordnung"
|
|
13
|
+
warning: "Braucht einen Blick"
|
|
14
|
+
failing: "Fehlgeschlagen"
|
|
15
|
+
checks:
|
|
16
|
+
jobs:
|
|
17
|
+
title: "Hintergrundjobs"
|
|
18
|
+
elsewhere: "Jobs laufen auf einem anderen Server."
|
|
19
|
+
none: "Am letzten Tag ist kein Job fehlgeschlagen."
|
|
20
|
+
failed:
|
|
21
|
+
one: "Eine Art Job ist am letzten Tag fehlgeschlagen: %{jobs}."
|
|
22
|
+
other: "%{count} Arten von Jobs sind am letzten Tag fehlgeschlagen: %{jobs}."
|
|
23
|
+
advice: "Lesen Sie den Fehler im Serverprotokoll. Jeder Job läuft nach seinem Zeitplan erneut."
|
|
24
|
+
worker:
|
|
25
|
+
title: "Worker"
|
|
26
|
+
elsewhere: "Jobs laufen auf einem anderen Server."
|
|
27
|
+
unchecked: "Die Worker-Prüfung ist aus."
|
|
28
|
+
reporting: "Ein Worker läuft."
|
|
29
|
+
silent: "In den letzten %{minutes} Minuten hat sich kein Worker gemeldet."
|
|
30
|
+
advice: "Starten Sie den Jobs-Prozess, oder setzen Sie MASKS_JOBS_IN_WEB_SERVER auf true, damit der Webserver die Jobs ausführt."
|
|
31
|
+
queue:
|
|
32
|
+
title: "Warteschlange"
|
|
33
|
+
elsewhere: "Jobs laufen auf einem anderen Server."
|
|
34
|
+
unchecked: "Die Warteschlangen-Prüfung ist aus."
|
|
35
|
+
moving: "Jobs starten pünktlich."
|
|
36
|
+
stuck: "Ein Job wartet seit %{since} auf seinen Start, länger als %{minutes} Minuten."
|
|
37
|
+
advice: "Fügen Sie einen Worker hinzu, oder erhöhen Sie JOB_CONCURRENCY, damit mehr Jobs gleichzeitig laufen."
|
|
38
|
+
ldap:
|
|
39
|
+
title: "LDAP"
|
|
40
|
+
tls: "LDAP antwortet mit TLS."
|
|
41
|
+
local: "LDAP antwortet nur auf der eigenen Maschine des Servers."
|
|
42
|
+
plain: "LDAP antwortet auf Port %{port} ohne TLS, also gehen Passwörter im Klartext durchs Netz."
|
|
43
|
+
advice: "Setzen Sie MASKS_LDAP_CERT und MASKS_LDAP_KEY, oder entfernen Sie MASKS_LDAP_PLAINTEXT."
|
|
44
|
+
metrics:
|
|
45
|
+
title: "Metriken"
|
|
46
|
+
"off": "Die Metrikseite ist aus."
|
|
47
|
+
"on": "Die Metrikseite beantwortet Anfragen, die ihr Token tragen."
|
|
48
|
+
short: "Das Metrik-Token ist %{length} Zeichen lang und lässt sich erraten."
|
|
49
|
+
advice: "Setzen Sie MASKS_METRICS_TOKEN auf mindestens %{needed} zufällige Zeichen."
|
|
50
|
+
mail:
|
|
51
|
+
title: "E-Mail"
|
|
52
|
+
none: "Kein E-Mail-Dienst ist eingerichtet."
|
|
53
|
+
answers: "Der Mailserver antwortet."
|
|
54
|
+
silent: "Der Mailserver hat nicht geantwortet: %{error}."
|
|
55
|
+
advice: "Prüfen Sie Server, Port und TLS-Einstellung auf der Seite Nachrichten, und ob der Server Verbindungen von hier zulässt."
|
|
56
|
+
origin:
|
|
57
|
+
title: "Öffentliche Adresse"
|
|
58
|
+
unset: "Keine öffentliche Adresse ist gesetzt, also folgt masks dem Host-Header jeder Anfrage."
|
|
59
|
+
matches: "Anfragen kommen an der öffentlichen Adresse dieses Mandanten an."
|
|
60
|
+
mismatch: "Anfragen kommen als %{seen} an, aber die Adresse dieses Mandanten ist %{origin}."
|
|
61
|
+
advice: "Lassen Sie den Proxy X-Forwarded-Proto und X-Forwarded-Host senden, und tragen Sie ihn in MASKS_TRUSTED_PROXIES ein."
|
|
62
|
+
domains:
|
|
63
|
+
title: "Domains"
|
|
64
|
+
none: "Keine Domain ist beansprucht."
|
|
65
|
+
proven: "Jede beanspruchte Domain hat noch ihren TXT-Eintrag."
|
|
66
|
+
missing: "Der TXT-Eintrag fehlt für %{domains}. Ein Anspruch wird eine Woche nach dem Verschwinden seines Eintrags freigegeben."
|
|
67
|
+
advice: "Legen Sie den TXT-Eintrag wieder unter dem Namen an, der auf der Seite Domains steht."
|
|
68
|
+
keys:
|
|
69
|
+
title: "Signaturschlüssel"
|
|
70
|
+
missing: "Dieser Mandant hat keinen aktiven Signaturschlüssel, also kann nichts signiert werden."
|
|
71
|
+
manual: "Schlüssel werden von Hand rotiert. Der aktive Schlüssel ist %{days} Tage alt."
|
|
72
|
+
fresh: "Der aktive Schlüssel ist %{days} Tage alt und rotiert alle %{period} Tage."
|
|
73
|
+
stale: "Der aktive Schlüssel ist %{days} Tage alt, älter als seine Rotation von %{period} Tagen."
|
|
74
|
+
advice: "Rotieren Sie den Schlüssel auf der Seite Einstellungen, oder lesen Sie den Job signing_keys im Serverprotokoll."
|
|
75
|
+
release:
|
|
76
|
+
available: "Version %{version} ist verfügbar."
|
|
77
|
+
operator: "Diese Version braucht einen Schritt von einem Betreiber. Lesen Sie ihre Hinweise vor dem Upgrade."
|
|
78
|
+
notes: "Versionshinweise"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
de:
|
|
2
|
+
manage:
|
|
3
|
+
links:
|
|
4
|
+
title: "Links"
|
|
5
|
+
help: "Wie lange jeder Link gültig ist, den masks per E-Mail sendet. Ein bereits gesendeter Link behält die Gültigkeit, mit der er gesendet wurde. Eine Einladung in eine Organisation zählt ab dem letzten Senden."
|
|
6
|
+
invitation: "Einladung zu einem Konto"
|
|
7
|
+
organization_invitation: "Einladung in eine Organisation"
|
|
8
|
+
password_reset: "Passwort zurücksetzen"
|
|
9
|
+
email_verification: "E-Mail-Bestätigung"
|
|
10
|
+
default: "%{length} (Standard)"
|
|
11
|
+
updated: "Gültigkeit des Links gespeichert."
|
|
12
|
+
minutes:
|
|
13
|
+
one: "%{count} Minute"
|
|
14
|
+
other: "%{count} Minuten"
|
|
15
|
+
hours:
|
|
16
|
+
one: "%{count} Stunde"
|
|
17
|
+
other: "%{count} Stunden"
|
|
18
|
+
days:
|
|
19
|
+
one: "%{count} Tag"
|
|
20
|
+
other: "%{count} Tage"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
de:
|
|
2
|
+
manage:
|
|
3
|
+
machines:
|
|
4
|
+
title: "Maschinen"
|
|
5
|
+
lede: "Clients, die diese App mit einem Registrierungstoken angemeldet hat. Jeder meldet sich mit einem eigenen Schlüssel an."
|
|
6
|
+
empty: "Diese App hat noch keine Maschine angemeldet."
|
|
7
|
+
last_seen: "Zuletzt angemeldet %{day}"
|
|
8
|
+
never: "Nie angemeldet"
|
|
9
|
+
enrolled: "Angemeldet %{day}"
|
|
10
|
+
enrolled_by: "Eine Maschine, angemeldet von"
|
|
11
|
+
revoke: "Widerrufen"
|
|
12
|
+
revoke_confirm: "%{name} widerrufen? Sie wird archiviert, jedes Token endet, und sie kann sich nicht mehr anmelden."
|
|
13
|
+
revoked: "%{name} ist widerrufen und kann sich nicht mehr anmelden."
|