masks-server 0.13.0 → 0.14.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/manage_controller.rb +1 -0
- data/app/controllers/masks/server/scim/metadata_controller.rb +1 -1
- data/app/models/masks/server/app_preset.rb +1 -1
- data/app/models/masks/server/client.rb +24 -0
- data/app/views/masks/server/handshakes/show.html.erb +2 -8
- data/app/views/masks/server/logins/_consent.html.erb +43 -44
- data/app/views/masks/server/logins/_enrol.html.erb +1 -1
- data/app/views/masks/server/logins/_setup_configure.html.erb +2 -6
- data/app/views/masks/server/logins/_signup.html.erb +2 -9
- data/app/views/masks/server/logins/_signup_credentials.html.erb +1 -2
- data/app/views/masks/server/logins/_signup_head.html.erb +1 -11
- data/config/locales/de/account.yml +4 -4
- data/config/locales/de/handshakes.yml +6 -6
- data/config/locales/de/logins.yml +44 -30
- data/config/locales/en/account.yml +4 -4
- data/config/locales/en/handshakes.yml +6 -6
- data/config/locales/en/logins.yml +44 -30
- data/config/locales/es/account.yml +4 -4
- data/config/locales/es/handshakes.yml +6 -6
- data/config/locales/es/logins.yml +42 -28
- data/config/locales/fr/account.yml +4 -4
- data/config/locales/fr/handshakes.yml +6 -6
- data/config/locales/fr/logins.yml +43 -29
- data/lib/masks/server/schema_reference.rb +1 -1
- data/public/masks-assets/.vite/manifest.json +3 -3
- data/public/masks-assets/assets/app-Cfbt-A5V.css +2 -0
- data/public/masks-assets/assets/login-BDggujiZ.js +6 -0
- data/public/masks-assets/assets/login-BDggujiZ.js.map +1 -0
- data/public/masks-assets/assets/{manage-DpVxe5sv.js → manage-VgOqKj7N.js} +2 -2
- data/public/masks-assets/assets/manage-VgOqKj7N.js.map +1 -0
- data/version.txt +1 -1
- metadata +6 -6
- data/public/masks-assets/assets/app-BXOScMjL.css +0 -2
- data/public/masks-assets/assets/login-C21_jb6L.js +0 -4
- data/public/masks-assets/assets/login-C21_jb6L.js.map +0 -1
- data/public/masks-assets/assets/manage-DpVxe5sv.js.map +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 475ac0de6cacc1cec932c465ef03e11e494cca4c53c2e4450a8bbd1299b07830
|
|
4
|
+
data.tar.gz: 305e006530de29f816aef4e49f6173ca18f524ad5a21631700bc09efbf463f98
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2856b2e35e55cf7fb8724dcfd00e3007eaedf14ff49f8bce48b2936d8afc987dd13506c476e3d4efb1f492b5c25db557a73f37b9edb9efc60dcd3b4b30dd664b
|
|
7
|
+
data.tar.gz: c588ee7cd4211a8205e08cb8a2957448981c6c8ae34c1e0723987f06c7675cb380084564d09e2ee5ba596af6baf83476a484b5a3c5a84fadd575aecde8d33a6d
|
|
@@ -7,7 +7,7 @@ module Masks
|
|
|
7
7
|
def service_provider_config
|
|
8
8
|
scim({
|
|
9
9
|
"schemas" => [ Scim::SERVICE_PROVIDER_CONFIG ],
|
|
10
|
-
"documentationUri" => "#{::Rails.configuration.masks.docs_url}/
|
|
10
|
+
"documentationUri" => "#{::Rails.configuration.masks.docs_url}/build/sso-saml/#provisioning",
|
|
11
11
|
"patch" => { "supported" => true },
|
|
12
12
|
"bulk" => { "supported" => false, "maxOperations" => 0, "maxPayloadSize" => 0 },
|
|
13
13
|
"filter" => { "supported" => true, "maxResults" => Scim::MAX_RESULTS },
|
|
@@ -10,7 +10,7 @@ module Masks
|
|
|
10
10
|
key: "proxy", name: "Any app behind Caddy, Traefik, or nginx", forward: true,
|
|
11
11
|
redirects: [ "{base}/masks-auth/callback" ],
|
|
12
12
|
scopes: %w[openid],
|
|
13
|
-
guide: "https://masks.pages.dev/
|
|
13
|
+
guide: "https://masks.pages.dev/build/forward-auth/",
|
|
14
14
|
settings: [
|
|
15
15
|
[ "Caddy", "{host} {\n forward_auth {masks_origin} {\n uri /forward-auth\n header_up Host {masks_host}\n" \
|
|
16
16
|
" copy_headers Remote-User Remote-Email Remote-Name Remote-Groups\n }\n reverse_proxy your-app:8080\n}" ],
|
|
@@ -101,6 +101,9 @@ module Masks
|
|
|
101
101
|
belongs_to :enrolled_by, class_name: "Client", optional: true, inverse_of: :enrolled
|
|
102
102
|
belongs_to :sign_in_policy, optional: true
|
|
103
103
|
|
|
104
|
+
CONSOLE_ID = "masks-manage".freeze
|
|
105
|
+
CONSOLE_SCOPES = [ Scopes::OPENID, Scopes::PROFILE, Scopes::EMAIL, Scopes::MANAGE, *ManageRoles::SCOPES ].uniq.freeze
|
|
106
|
+
|
|
104
107
|
scope :approved, -> { where.not(approved_at: nil) }
|
|
105
108
|
scope :speaking, ->(protocol) { active.where(protocol: protocol) }
|
|
106
109
|
|
|
@@ -113,6 +116,27 @@ module Masks
|
|
|
113
116
|
LOOPBACK.include?(host) || host.end_with?(".localhost")
|
|
114
117
|
end
|
|
115
118
|
|
|
119
|
+
def console!(issuer)
|
|
120
|
+
approved_for(issuer.manage_resource) || create!(
|
|
121
|
+
client_id: CONSOLE_ID,
|
|
122
|
+
name: "Manage #{Current.tenant.name}",
|
|
123
|
+
redirect_uris: [ "#{issuer.manage_resource}/callback" ],
|
|
124
|
+
post_logout_redirect_uris: [ issuer.manage_resource ],
|
|
125
|
+
resources: [ issuer.manage_resource ],
|
|
126
|
+
allowed_scopes: Scopes.join(CONSOLE_SCOPES),
|
|
127
|
+
grant_types: %w[authorization_code refresh_token],
|
|
128
|
+
response_types: [ "code" ],
|
|
129
|
+
token_endpoint_auth_method: "none",
|
|
130
|
+
client_uri: issuer.url,
|
|
131
|
+
handshake_return_to: issuer.manage_resource,
|
|
132
|
+
consent_required: false,
|
|
133
|
+
dynamic: false,
|
|
134
|
+
approved_at: Time.current
|
|
135
|
+
)
|
|
136
|
+
rescue ActiveRecord::RecordNotUnique
|
|
137
|
+
find_by!(client_id: CONSOLE_ID)
|
|
138
|
+
end
|
|
139
|
+
|
|
116
140
|
def approve!(handshake, actor:)
|
|
117
141
|
client = approved_for(handshake.resource) || new(client_id: SecureRandom.uuid)
|
|
118
142
|
|
|
@@ -12,21 +12,15 @@
|
|
|
12
12
|
<% hot, rest = @scopes.to_a.partition { |scope, _| heeded_scope?(scope) } %>
|
|
13
13
|
<% after_sign_out = @handshake.try(:post_logout_redirect_uri) %>
|
|
14
14
|
|
|
15
|
-
<div class="auth-
|
|
15
|
+
<div class="auth-solo">
|
|
16
16
|
<span class="auth-mark auth-mark-client" aria-hidden="true"><%= name.to_s.first&.upcase %></span>
|
|
17
|
-
<span class="auth-wire"></span>
|
|
18
|
-
<%= tenant_mark(Masks::Server::Current.tenant) %>
|
|
19
17
|
</div>
|
|
20
18
|
|
|
21
19
|
<div class="prompt-head">
|
|
22
20
|
<h1 class="prompt-title"><%= t(@existing ? ".title_again" : ".title", name: name, tenant: tenant) %></h1>
|
|
23
21
|
|
|
24
|
-
<p class="handshake-origin">
|
|
25
|
-
<span class="handshake-origin-label"><%= t(".runs_at") %></span>
|
|
26
|
-
<span class="handshake-origin-value"><%= @handshake.origin %></span>
|
|
27
|
-
</p>
|
|
28
|
-
|
|
29
22
|
<p class="prompt-lede">
|
|
23
|
+
<%= t(".runs_at", name: name, origin: @handshake.origin) %>
|
|
30
24
|
<%= t(@existing ? ".lede_again_html" : ".lede_html", name: name, tenant: tenant) %>
|
|
31
25
|
</p>
|
|
32
26
|
</div>
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
<% state = login.state("consent") %>
|
|
2
2
|
<% client = login.client_json || {} %>
|
|
3
3
|
<% hot, rest = ranked_scopes(Masks::Server::ResourceMetadata.describe(state.audience, state.scopes)) %>
|
|
4
|
+
<% all = hot + rest %>
|
|
4
5
|
|
|
5
|
-
<div class="auth-
|
|
6
|
+
<div class="auth-solo">
|
|
6
7
|
<% if client["logo"] %>
|
|
7
8
|
<%= image_tag client["logo"], alt: "", class: "auth-mark auth-mark-client auth-mark-logo", referrerpolicy: "no-referrer" %>
|
|
8
9
|
<% else %>
|
|
9
10
|
<span class="auth-mark auth-mark-client" aria-hidden="true"><%= client["name"].to_s.strip.first&.upcase %></span>
|
|
10
11
|
<% end %>
|
|
11
|
-
<span class="auth-wire"></span>
|
|
12
|
-
<%= tenant_mark(Masks::Server::Current.tenant) %>
|
|
13
12
|
</div>
|
|
14
13
|
|
|
15
14
|
<%= render "masks/server/logins/head", title: t(".title", client: login.client&.name) %>
|
|
@@ -20,48 +19,30 @@
|
|
|
20
19
|
<div class="ledger-row">
|
|
21
20
|
<span class="ledger-label"><%= t(".access") %></span>
|
|
22
21
|
|
|
23
|
-
<% if
|
|
22
|
+
<% if all.empty? %>
|
|
24
23
|
<p class="empty"><%= t(".no_access") %></p>
|
|
24
|
+
<% else %>
|
|
25
|
+
<ul class="plain-list">
|
|
26
|
+
<% all.each do |_, description| %>
|
|
27
|
+
<li><%= description %></li>
|
|
28
|
+
<% end %>
|
|
29
|
+
</ul>
|
|
25
30
|
<% end %>
|
|
26
|
-
|
|
27
|
-
<ul class="grant-scopes">
|
|
28
|
-
<% hot.each do |scope, description| %>
|
|
29
|
-
<li class="grant-scope grant-scope-hot">
|
|
30
|
-
<span><%= description %></span>
|
|
31
|
-
<span class="chip-key"><%= scope %></span>
|
|
32
|
-
</li>
|
|
33
|
-
<% end %>
|
|
34
|
-
|
|
35
|
-
<% if hot.any? && rest.any? %>
|
|
36
|
-
<li class="grant-scope-split"></li>
|
|
37
|
-
<% end %>
|
|
38
|
-
|
|
39
|
-
<% rest.each do |scope, description| %>
|
|
40
|
-
<li class="grant-scope">
|
|
41
|
-
<span><%= description %></span>
|
|
42
|
-
<span class="chip-key"><%= scope %></span>
|
|
43
|
-
</li>
|
|
44
|
-
<% end %>
|
|
45
|
-
</ul>
|
|
46
31
|
</div>
|
|
47
32
|
|
|
48
33
|
<% if state.audience.any? %>
|
|
49
34
|
<div class="ledger-row">
|
|
50
|
-
<span class="
|
|
51
|
-
<% state.audience.each do |resource| %>
|
|
52
|
-
<span class="ledger-value aside-mono"><%= resource %></span>
|
|
53
|
-
<% end %>
|
|
35
|
+
<span class="aside"><%= t(".audience", resources: state.audience.join(", ")) %></span>
|
|
54
36
|
</div>
|
|
55
37
|
<% end %>
|
|
56
38
|
|
|
57
39
|
<% if (details = state.details&.described).present? %>
|
|
58
40
|
<div class="ledger-row">
|
|
59
41
|
<span class="ledger-label"><%= t(".details") %></span>
|
|
60
|
-
<ul class="
|
|
42
|
+
<ul class="plain-list">
|
|
61
43
|
<% details.each do |detail| %>
|
|
62
|
-
<li
|
|
63
|
-
|
|
64
|
-
<span class="chip-key"><%= detail["type"] %></span>
|
|
44
|
+
<li>
|
|
45
|
+
<%= detail["label"] %>
|
|
65
46
|
<% if detail["fields"].any? %>
|
|
66
47
|
<dl class="grant-fields">
|
|
67
48
|
<% detail["fields"].each do |name, value| %>
|
|
@@ -75,23 +56,41 @@
|
|
|
75
56
|
</ul>
|
|
76
57
|
</div>
|
|
77
58
|
<% end %>
|
|
59
|
+
</div>
|
|
78
60
|
|
|
79
|
-
|
|
61
|
+
<% links = { "site" => t(".site", client: client["name"]), "terms" => t(".terms"), "privacy" => t(".privacy") }.select { |key, _| client[key] } %>
|
|
62
|
+
<details class="disclosure handshake-more">
|
|
63
|
+
<summary class="textlink"><%= t(".more") %></summary>
|
|
64
|
+
|
|
65
|
+
<div class="slab">
|
|
80
66
|
<div class="ledger-row">
|
|
81
|
-
<span class="ledger-label"><%= t(".
|
|
82
|
-
<
|
|
67
|
+
<span class="ledger-label"><%= t(".scopes") %></span>
|
|
68
|
+
<ul class="grant-scopes">
|
|
69
|
+
<% all.each do |scope, description| %>
|
|
70
|
+
<li class="grant-scope">
|
|
71
|
+
<span><%= description %></span>
|
|
72
|
+
<span class="chip-key"><%= scope %></span>
|
|
73
|
+
</li>
|
|
74
|
+
<% end %>
|
|
75
|
+
</ul>
|
|
83
76
|
</div>
|
|
84
|
-
<% end %>
|
|
85
|
-
</div>
|
|
86
77
|
|
|
87
|
-
<%
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
78
|
+
<% if client["returnsTo"] %>
|
|
79
|
+
<div class="ledger-row">
|
|
80
|
+
<span class="ledger-label"><%= t(".returns_to") %></span>
|
|
81
|
+
<span class="ledger-value aside-mono"><%= client["returnsTo"] %></span>
|
|
82
|
+
</div>
|
|
92
83
|
<% end %>
|
|
93
|
-
|
|
94
|
-
<%
|
|
84
|
+
|
|
85
|
+
<% if links.any? %>
|
|
86
|
+
<p class="aside client-links">
|
|
87
|
+
<% links.each do |key, label| %>
|
|
88
|
+
<%= link_to label, client[key], class: "textlink", rel: "noopener noreferrer", target: "_blank" %>
|
|
89
|
+
<% end %>
|
|
90
|
+
</p>
|
|
91
|
+
<% end %>
|
|
92
|
+
</div>
|
|
93
|
+
</details>
|
|
95
94
|
|
|
96
95
|
<div class="action-row">
|
|
97
96
|
<%= form_with url: login_path, method: :post, id: "consent", class: "action-grow" do |form| %>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<div class="flow<%= " setup" if signing_up %>">
|
|
9
9
|
<% if signing_up %>
|
|
10
|
-
<%= render "masks/server/logins/signup_head", login: login, at: 2
|
|
10
|
+
<%= render "masks/server/logins/signup_head", login: login, at: 2 %>
|
|
11
11
|
|
|
12
12
|
<p class="aside"><%= enrolment["required"] ? t(".lede") : t(".lede_optional") %></p>
|
|
13
13
|
<% else %>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<% configure = login.state("configure").as_json["configure"] %>
|
|
2
2
|
|
|
3
3
|
<div class="setup flow">
|
|
4
|
-
<%= render "masks/server/logins/signup_head", login: login, at: 3
|
|
4
|
+
<%= render "masks/server/logins/signup_head", login: login, at: 3 %>
|
|
5
5
|
|
|
6
6
|
<%= form_with url: login_path, method: :post, id: "setup-configure", class: "flow" do |form| %>
|
|
7
7
|
<%= hidden_field_tag :rid, login.rid %>
|
|
@@ -12,11 +12,6 @@
|
|
|
12
12
|
<%= form.text_field :called, value: configure["called"], class: "control" %>
|
|
13
13
|
<span class="field-hint"><%= t(".called_hint") %></span>
|
|
14
14
|
</label>
|
|
15
|
-
|
|
16
|
-
<div class="ledger-row">
|
|
17
|
-
<span class="ledger-label"><%= t("logins.signing_up.origin") %></span>
|
|
18
|
-
<span class="ledger-value aside-mono"><%= Masks::Server::Current.origin %></span>
|
|
19
|
-
</div>
|
|
20
15
|
</div>
|
|
21
16
|
|
|
22
17
|
<button type="submit" name="event" value="setup-configure" class="action">
|
|
@@ -25,6 +20,7 @@
|
|
|
25
20
|
<% end %>
|
|
26
21
|
|
|
27
22
|
<p class="aside">
|
|
23
|
+
<%= t("logins.signing_up.origin", origin: Masks::Server::Current.origin) %>
|
|
28
24
|
<%= t("logins.signing_up.once") %>
|
|
29
25
|
<%= link_to t("logins.signing_up.docs"), Rails.configuration.masks.docs_url,
|
|
30
26
|
class: "textlink", rel: "noopener", target: "_blank" %>
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
<% done = ->(field) { " ledger-step-done" if value.(field).present? } %>
|
|
5
5
|
|
|
6
6
|
<div class="setup flow">
|
|
7
|
-
<%= render "masks/server/logins/signup_head", login: login, at: 1
|
|
8
|
-
mark: value.("nickname").presence || value.("email") %>
|
|
7
|
+
<%= render "masks/server/logins/signup_head", login: login, at: 1 %>
|
|
9
8
|
|
|
10
9
|
<%= form_with url: login_path, method: :post, id: "signup", class: "flow" do |form| %>
|
|
11
10
|
<%= hidden_field_tag :rid, login.rid %>
|
|
@@ -51,13 +50,6 @@
|
|
|
51
50
|
<%= render "masks/server/logins/hint", login: login, field: "phone" %>
|
|
52
51
|
</label>
|
|
53
52
|
<% end %>
|
|
54
|
-
|
|
55
|
-
<% if login.signing_up["firstRun"] %>
|
|
56
|
-
<div class="ledger-row">
|
|
57
|
-
<span class="ledger-label"><%= t("logins.signing_up.origin") %></span>
|
|
58
|
-
<span class="ledger-value aside-mono"><%= Masks::Server::Current.origin %></span>
|
|
59
|
-
</div>
|
|
60
|
-
<% end %>
|
|
61
53
|
</div>
|
|
62
54
|
|
|
63
55
|
<% if signup["work"] %>
|
|
@@ -71,6 +63,7 @@
|
|
|
71
63
|
|
|
72
64
|
<% if login.signing_up["firstRun"] %>
|
|
73
65
|
<p class="aside">
|
|
66
|
+
<%= t("logins.signing_up.origin", origin: Masks::Server::Current.origin) %>
|
|
74
67
|
<%= t("logins.signing_up.once") %>
|
|
75
68
|
<%= link_to t("logins.signing_up.docs"), Rails.configuration.masks.docs_url,
|
|
76
69
|
class: "textlink", rel: "noopener", target: "_blank" %>
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
<% rows = %w[name nickname email phone].filter_map { |field| [ field, signup[field] ] if signup[field].present? } %>
|
|
3
3
|
|
|
4
4
|
<div class="setup flow">
|
|
5
|
-
<%= render "masks/server/logins/signup_head", login: login, at: 2
|
|
6
|
-
mark: signup["nickname"].presence || signup["email"] %>
|
|
5
|
+
<%= render "masks/server/logins/signup_head", login: login, at: 2 %>
|
|
7
6
|
|
|
8
7
|
<%= form_with url: login_path, method: :post, id: "signup-credentials", class: "flow" do |form| %>
|
|
9
8
|
<%= hidden_field_tag :rid, login.rid %>
|
|
@@ -1,20 +1,10 @@
|
|
|
1
1
|
<% tenant = Masks::Server::Current.tenant&.name.to_s %>
|
|
2
2
|
<% signing_up = login.signing_up %>
|
|
3
3
|
|
|
4
|
-
<div class="auth-pair">
|
|
5
|
-
<span class="auth-mark auth-mark-client<%= " auth-mark-pending" if mark.blank? %>" aria-hidden="true"><%= mark.to_s.first&.upcase %></span>
|
|
6
|
-
<span class="auth-wire"></span>
|
|
7
|
-
<% if signing_up["firstRun"] %>
|
|
8
|
-
<img src="/masks-public/icon.svg" alt="" class="auth-mark auth-mark-rose">
|
|
9
|
-
<% else %>
|
|
10
|
-
<%= tenant_mark(Masks::Server::Current.tenant) %>
|
|
11
|
-
<% end %>
|
|
12
|
-
</div>
|
|
13
|
-
|
|
14
4
|
<% if signing_up["firstRun"] %>
|
|
15
5
|
<%= render "masks/server/logins/head", cap: t("logins.signing_up.setup_cap"), title: t("logins.signing_up.setup_title"), name: tenant %>
|
|
16
6
|
<% else %>
|
|
17
|
-
<%= render "masks/server/logins/head", title: t("logins.signing_up.signup_title")
|
|
7
|
+
<%= render "masks/server/logins/head", title: t("logins.signing_up.signup_title") %>
|
|
18
8
|
<% end %>
|
|
19
9
|
|
|
20
10
|
<%= render "masks/server/logins/steps", steps: signing_up["steps"], at: local_assigns[:at] || signing_up["steps"].length %>
|
|
@@ -62,7 +62,7 @@ de:
|
|
|
62
62
|
set:
|
|
63
63
|
one: "1 eingerichtet"
|
|
64
64
|
other: "%{count} eingerichtet"
|
|
65
|
-
explained: "Statt ein Passwort
|
|
65
|
+
explained: "Statt ein Passwort einzutippen, prüft Ihr Gerät so, dass Sie es sind, wie es sich ohnehin entsperrt. Es zählt auch als Ihr zweiter Schritt, also müssen Sie auf keinen Code warten."
|
|
66
66
|
used: "zuletzt verwendet vor %{age}"
|
|
67
67
|
never_used: "nie verwendet"
|
|
68
68
|
remove: "Entfernen"
|
|
@@ -209,11 +209,11 @@ de:
|
|
|
209
209
|
remembered: "%{label}, ohne Nachfrage bis %{date}"
|
|
210
210
|
heading: "Apps, die Sie zugelassen haben"
|
|
211
211
|
none_yet: "Bisher hat nichts angefragt. Eine App erscheint hier, sobald Sie sich bei ihr anmelden, zusammen mit dem, was sie sehen darf."
|
|
212
|
-
revoke: "Zugriff
|
|
212
|
+
revoke: "Zugriff entfernen"
|
|
213
213
|
more:
|
|
214
214
|
one: "und eine weitere"
|
|
215
215
|
other: "und %{count} weitere"
|
|
216
|
-
confirm_revoke: "%{client}
|
|
216
|
+
confirm_revoke: "%{client} den Zugriff entfernen? Alles, was es gerade hält, funktioniert nicht mehr, und es muss bei der nächsten Anmeldung erneut fragen."
|
|
217
217
|
|
|
218
218
|
connections:
|
|
219
219
|
heading: "Verbundene Konten"
|
|
@@ -258,7 +258,7 @@ de:
|
|
|
258
258
|
|
|
259
259
|
export:
|
|
260
260
|
heading: "Ihr Konto herunterladen"
|
|
261
|
-
state: "
|
|
261
|
+
state: "Eine Datei"
|
|
262
262
|
lede: "Eine Datei mit Ihrem Profil, Ihren Anmeldemethoden, Organisationen, Apps, verbundenen Konten und Geräten sowie der Aktivität, die masks aufbewahrt hat. Sie enthält keine Passwörter, Codes oder Schlüssel."
|
|
263
263
|
again: "Ihre Anmeldung ist eine Weile her, daher werden Sie zuerst gebeten, sich erneut anzumelden."
|
|
264
264
|
submit: "Herunterladen"
|
|
@@ -3,29 +3,29 @@ de:
|
|
|
3
3
|
show:
|
|
4
4
|
page_title: "%{name} verbinden"
|
|
5
5
|
page_title_again: "%{name} neu verbinden"
|
|
6
|
-
title: "%{name}
|
|
6
|
+
title: "%{name} verbinden?"
|
|
7
7
|
title_again: "%{name} neu verbinden?"
|
|
8
|
-
runs_at: "
|
|
8
|
+
runs_at: "%{name} läuft unter %{origin}."
|
|
9
9
|
lede_html: "Alle können sich dann mit ihrem %{tenant}-Konto bei <strong>%{name}</strong> anmelden. Vorerst haben nur Sie Zugang, und Sie legen später fest, wer noch hinein darf."
|
|
10
10
|
lede_again_html: "<strong>%{name}</strong> ist bereits mit %{tenant} verbunden. Beim neuen Verbinden wird die App neu eingerichtet. Vorerst haben nur Sie Zugang, und Sie legen später fest, wer noch hinein darf."
|
|
11
11
|
stops_working: "Die bisherige Verbindung zu %{name} funktioniert dann nicht mehr."
|
|
12
12
|
connected_by_you: "Sie haben %{name} am %{date} verbunden."
|
|
13
13
|
connected_by: "%{who} hat %{name} am %{date} verbunden."
|
|
14
|
-
signed_in_as: "Sie
|
|
14
|
+
signed_in_as: "Sie verbinden als"
|
|
15
15
|
unconfirmed: "(E-Mail noch nicht bestätigt)"
|
|
16
|
-
check: "
|
|
16
|
+
check: "Bevor Sie verbinden"
|
|
17
17
|
heed:
|
|
18
18
|
offline_access: "%{name} kann Personen angemeldet halten, ohne erneut zu fragen, bis sie sich abmelden."
|
|
19
19
|
delegates_title: "Personen bitten, ihre anderen Konten zu verbinden"
|
|
20
20
|
delegates: "Jede Person entscheidet selbst. %{name} kann diese Konten dann nutzen, während sie nicht da sind."
|
|
21
21
|
delegate: "%{name} kann dieses Konto nutzen, während Sie nicht da sind, bis Sie es beenden."
|
|
22
22
|
manage: "Alle, die sich über %{name} anmelden, können jede Einstellung auf diesem Server ändern."
|
|
23
|
-
sees: "%{name}
|
|
23
|
+
sees: "%{name} erfährt"
|
|
24
24
|
area: "Eigene Berechtigungen von %{name}"
|
|
25
25
|
area_says_html: "%{name} erhält eigene Berechtigungen mit dem Namen %{namespaces}. Sie entscheiden, wer sie bekommt."
|
|
26
26
|
area_yours: " Sie erhalten sie jetzt alle."
|
|
27
27
|
also: "%{name} kann außerdem"
|
|
28
|
-
details: "
|
|
28
|
+
details: "Details"
|
|
29
29
|
scopes: "Scopes"
|
|
30
30
|
client: "Zugangsdaten"
|
|
31
31
|
credentials:
|
|
@@ -16,7 +16,7 @@ de:
|
|
|
16
16
|
name: "Name"
|
|
17
17
|
phone: "Telefon"
|
|
18
18
|
password: "Passwort"
|
|
19
|
-
not_you: "
|
|
19
|
+
not_you: "Ein anderes Konto verwenden"
|
|
20
20
|
sign_out: "Abmelden"
|
|
21
21
|
use_passkey: "Passkey verwenden"
|
|
22
22
|
or: "oder"
|
|
@@ -40,10 +40,12 @@ de:
|
|
|
40
40
|
tab_confirmation: "Bestätigung"
|
|
41
41
|
setup_cap: "Willkommen!"
|
|
42
42
|
setup_title: "Einrichten"
|
|
43
|
-
signup_title: "Konto
|
|
43
|
+
signup_title: "Konto anlegen"
|
|
44
44
|
token: "Einrichtungstoken"
|
|
45
|
-
token_hint: "
|
|
46
|
-
origin: "
|
|
45
|
+
token_hint: "Es steht im Protokoll des Servers."
|
|
46
|
+
origin: "Dieses masks antwortet unter %{origin}."
|
|
47
|
+
pick_nickname: "Einen Spitznamen wählen"
|
|
48
|
+
nickname_hint: "Andere sehen ihn. Lassen Sie es, wie es ist, um %{suggested} zu verwenden."
|
|
47
49
|
once: "Dieser Bildschirm erscheint nicht wieder."
|
|
48
50
|
docs: "Dokumentation lesen."
|
|
49
51
|
confirm: "Passwort bestätigen"
|
|
@@ -57,15 +59,15 @@ de:
|
|
|
57
59
|
proving: "Browser wird geprüft"
|
|
58
60
|
|
|
59
61
|
identify:
|
|
60
|
-
heading: "
|
|
62
|
+
heading: "Anmelden"
|
|
61
63
|
heading_to: "Bei %{client} anmelden"
|
|
62
|
-
identifier: "
|
|
63
|
-
signup_hint: "Neu hier? Geben Sie
|
|
64
|
+
identifier: "E-Mail oder Spitzname"
|
|
65
|
+
signup_hint: "Neu hier? Geben Sie Ihre E-Mail-Adresse ein, und masks legt ein Konto für Sie an."
|
|
64
66
|
|
|
65
67
|
first_factor:
|
|
66
68
|
title: "Geben Sie Ihr Passwort ein"
|
|
67
69
|
title_code: "Mit einem Code anmelden"
|
|
68
|
-
forgot: "
|
|
70
|
+
forgot: "Passwort vergessen?"
|
|
69
71
|
email_me: "Stattdessen einen Code per E-Mail senden"
|
|
70
72
|
email_only: "Code per E-Mail senden"
|
|
71
73
|
|
|
@@ -76,16 +78,16 @@ de:
|
|
|
76
78
|
sent_again: "Gesendet"
|
|
77
79
|
|
|
78
80
|
second_factor:
|
|
79
|
-
title: "
|
|
80
|
-
title_passkey: "
|
|
81
|
-
trust: "
|
|
81
|
+
title: "Bestätigen Sie, dass Sie es sind"
|
|
82
|
+
title_passkey: "Bestätigen Sie mit Ihrem Passkey, dass Sie es sind"
|
|
83
|
+
trust: "Auf diesem Gerät %{duration} lang überspringen"
|
|
82
84
|
use_backup_code: "Backup-Code verwenden"
|
|
83
85
|
stuck_insecure: "Der zweite Faktor dieses Kontos ist ein Passkey, und der Browser bietet Passkeys nur Seiten an, die über HTTPS ausgeliefert werden. Öffnen Sie diese Seite über HTTPS, um fortzufahren."
|
|
84
86
|
stuck_unsupported: "Der zweite Faktor dieses Kontos ist ein Passkey, und dieser Browser unterstützt keine Passkeys. Öffnen Sie diese Seite in einem Browser, der sie unterstützt, um fortzufahren."
|
|
85
87
|
stuck_no_script: "Der zweite Faktor dieses Kontos ist ein Passkey, und ein Passkey braucht JavaScript. Aktivieren Sie JavaScript, um fortzufahren."
|
|
86
88
|
stuck_inbox: "Diese Anmeldung hat in Ihrem Posteingang begonnen, daher kann ein dorthin gesendeter Code sie nicht bestätigen. Beginnen Sie von vorn und melden Sie sich mit Ihrem Passwort an, um einen Code per E-Mail zu verwenden."
|
|
87
89
|
stuck_nothing: "Dieses Konto hat keinen zweiten Faktor, den diese Anmeldung verwenden kann. Ein Verwalter kann ihn zurücksetzen."
|
|
88
|
-
recovery_request: "Ich kann
|
|
90
|
+
recovery_request: "Ich kann keinen davon verwenden"
|
|
89
91
|
recovery_ask: "Einen Verwalter um Hilfe bitten"
|
|
90
92
|
recovery_requested: "Ein Verwalter wurde gebeten, Ihre zweiten Faktoren zurückzusetzen. Er wird Sie möglicherweise kontaktieren, um sicherzugehen, dass Sie es sind. Danach melden Sie sich erneut an, um einen neuen einzurichten."
|
|
91
93
|
sent_to: "Gesendet an %{to}."
|
|
@@ -101,16 +103,26 @@ de:
|
|
|
101
103
|
approval_checked: "Ich habe genehmigt"
|
|
102
104
|
|
|
103
105
|
enrol:
|
|
104
|
-
title: "
|
|
105
|
-
lede: "
|
|
106
|
-
lede_optional: "
|
|
106
|
+
title: "Konto schützen"
|
|
107
|
+
lede: "Wählen Sie einen Weg, mit dem Sie bei der Anmeldung bestätigen, dass Sie es sind. Weitere können Sie später hinzufügen."
|
|
108
|
+
lede_optional: "Wählen Sie einen Weg, mit dem Sie bei der Anmeldung bestätigen, dass Sie es sind, oder überspringen Sie das vorerst."
|
|
109
|
+
on_title: "Ihr Konto ist geschützt"
|
|
110
|
+
on_lede: "So bestätigen Sie bei der Anmeldung, dass Sie es sind."
|
|
111
|
+
on_label: "Eingeschaltet"
|
|
112
|
+
passkey: "Passkey"
|
|
107
113
|
otp: "Authenticator-App"
|
|
114
|
+
otp_about: "Eine App wie Google Authenticator oder 1Password zeigt einen sechsstelligen Code."
|
|
108
115
|
otp_on: "Aktiv"
|
|
109
|
-
scan_hint: "Scannen Sie
|
|
116
|
+
scan_hint: "Scannen Sie das mit Ihrer Authenticator-App, oder tippen Sie den Schlüssel dort ein:"
|
|
117
|
+
passkey_about: "Ihr Telefon oder Computer prüft mit Gesicht, Fingerabdruck oder PIN, dass Sie es sind."
|
|
118
|
+
codes_email_about: "Bei jeder Anmeldung geht ein Code an %{to}."
|
|
119
|
+
codes_sms_about: "Bei jeder Anmeldung geht ein Code per SMS an %{to}."
|
|
120
|
+
another_way: "Einen anderen Weg wählen"
|
|
121
|
+
add_way: "Einen weiteren Weg hinzufügen"
|
|
110
122
|
open: "In Ihrer Authenticator-App öffnen"
|
|
111
123
|
turn_on: "Aktivieren"
|
|
112
124
|
passkeys: "Passkeys"
|
|
113
|
-
passkeys_none: "Noch
|
|
125
|
+
passkeys_none: "Noch keiner."
|
|
114
126
|
passkeys_some: "%{count} hinzugefügt"
|
|
115
127
|
add_passkey: "Passkey hinzufügen"
|
|
116
128
|
add_another_passkey: "Weiteren hinzufügen"
|
|
@@ -118,17 +130,17 @@ de:
|
|
|
118
130
|
codes_email_hint: "Ein an %{to} gesendeter Code bestätigt jede Anmeldung."
|
|
119
131
|
codes_sms: "Codes per SMS"
|
|
120
132
|
codes_sms_hint: "Ein per SMS an %{to} gesendeter Code bestätigt jede Anmeldung."
|
|
121
|
-
send_code: "Code
|
|
133
|
+
send_code: "Code schicken"
|
|
122
134
|
sent_to: "Gesendet an %{to}."
|
|
123
135
|
backup_codes: "Backup-Codes"
|
|
124
|
-
backup_codes_waiting: "Werden
|
|
125
|
-
backup_codes_hint: "Jeder meldet einmal an,
|
|
136
|
+
backup_codes_waiting: "Werden erstellt, sobald ein Weg oben eingeschaltet ist."
|
|
137
|
+
backup_codes_hint: "Jeder Code meldet Sie einmal an, falls Sie Ihren anderen Weg verlieren. Sichern Sie sie jetzt. Sie werden nicht noch einmal gezeigt."
|
|
126
138
|
backup_codes_left: "%{count} übrig"
|
|
127
139
|
backup_codes_file: "Backup-Codes für %{account} bei %{origin}"
|
|
128
140
|
copy: "Kopieren"
|
|
129
141
|
copied: "Kopiert"
|
|
130
142
|
download: "Herunterladen"
|
|
131
|
-
kept: "Ich habe meine Backup-Codes
|
|
143
|
+
kept: "Ich habe meine Backup-Codes gesichert"
|
|
132
144
|
done: "Weiter"
|
|
133
145
|
skip: "Vorerst überspringen"
|
|
134
146
|
|
|
@@ -163,7 +175,7 @@ de:
|
|
|
163
175
|
prove_email:
|
|
164
176
|
title: "Prüfen Sie Ihre E-Mails"
|
|
165
177
|
lede: "Ein sechsstelliger Code ist unterwegs an %{email}. Geben Sie ihn ein, um fortzufahren."
|
|
166
|
-
no_mailer: "Dieser Server kann noch keine E-Mails senden,
|
|
178
|
+
no_mailer: "Dieser Server kann noch keine E-Mails senden, also kann er Ihre Adresse nicht prüfen. Melden Sie sich mit Ihrem Spitznamen an, oder bitten Sie den Betreiber, die Adresse für Sie zu bestätigen."
|
|
167
179
|
|
|
168
180
|
setup_configure:
|
|
169
181
|
called: "Dieser Server heißt"
|
|
@@ -202,17 +214,19 @@ de:
|
|
|
202
214
|
as: "%{organization}, als %{role}"
|
|
203
215
|
|
|
204
216
|
consent:
|
|
205
|
-
title: "%{client}
|
|
206
|
-
access: "
|
|
207
|
-
no_access: "
|
|
208
|
-
audience: "
|
|
217
|
+
title: "%{client} möchte Sie anmelden"
|
|
218
|
+
access: "Es erfährt"
|
|
219
|
+
no_access: "Nur, dass Sie hier ein Konto haben."
|
|
220
|
+
audience: "Es kann für Sie handeln bei %{resources}."
|
|
209
221
|
details: "Genau dies"
|
|
210
222
|
returns_to: "Danach zurück zu"
|
|
223
|
+
more: "Details"
|
|
224
|
+
scopes: "Berechtigungen"
|
|
211
225
|
site: "Über %{client}"
|
|
212
226
|
terms: "Nutzungsbedingungen"
|
|
213
227
|
privacy: "Datenschutzerklärung"
|
|
214
228
|
allow: "Erlauben"
|
|
215
|
-
deny: "
|
|
229
|
+
deny: "Jetzt nicht"
|
|
216
230
|
working: "Wird erlaubt"
|
|
217
231
|
|
|
218
232
|
settled:
|
|
@@ -221,7 +235,7 @@ de:
|
|
|
221
235
|
waiting: "Sie werden zurückgeleitet"
|
|
222
236
|
|
|
223
237
|
warnings:
|
|
224
|
-
invalid-credentials: "Spitzname und Passwort passen nicht zusammen."
|
|
238
|
+
invalid-credentials: "Diese E-Mail oder dieser Spitzname und das Passwort passen nicht zusammen."
|
|
225
239
|
invalid-code: "Dieser Code ist ungültig."
|
|
226
240
|
invalid-backup-code: "Dieser Backup-Code ist ungültig."
|
|
227
241
|
invalid-passkey: "Dieser Passkey konnte nicht verwendet werden."
|
|
@@ -233,7 +247,7 @@ de:
|
|
|
233
247
|
passkey-crowded: "Dieses Konto hat bereits so viele Passkeys, wie dieser Server speichert."
|
|
234
248
|
second-factor-required: "Aktivieren Sie mindestens einen zweiten Faktor, um fortzufahren."
|
|
235
249
|
backup-codes-unkept: "Bewahren Sie Ihre Backup-Codes auf, bevor Sie fortfahren."
|
|
236
|
-
missing-identifier: "Geben Sie
|
|
250
|
+
missing-identifier: "Geben Sie Ihre E-Mail oder Ihren Spitznamen ein."
|
|
237
251
|
missing-first-factor: "Dieser Schritt ist abgelaufen. Beginnen Sie von vorn."
|
|
238
252
|
too-many-attempts: "Zu viele Versuche. Warten Sie einige Minuten."
|
|
239
253
|
too-many-attempts-for-account: "Zu viele Versuche für dieses Konto."
|
|
@@ -258,7 +272,7 @@ de:
|
|
|
258
272
|
work-unsolved: "Dieser Browser hat die Prüfung gegen automatisierte Registrierungen nicht abgeschlossen. Versuchen Sie es erneut."
|
|
259
273
|
invitation-expired: "Diese Einladung ist nicht mehr gültig. Fordern Sie eine neue an."
|
|
260
274
|
reset-expired: "Dieser Link zum Zurücksetzen ist nicht mehr gültig. Fordern Sie einen neuen an."
|
|
261
|
-
no-mailer: "Dieser Server kann keine E-Mails senden.
|
|
275
|
+
no-mailer: "Dieser Server kann noch keine E-Mails senden, also kann er Ihr Passwort nicht zurücksetzen. Bitten Sie den Betreiber um einen Link zum Zurücksetzen."
|
|
262
276
|
sso-failed: "Diese Anmeldung wurde nicht abgeschlossen. Versuchen Sie es erneut."
|
|
263
277
|
sso-expired: "Diese Anmeldung hat zu lange gedauert. Versuchen Sie es erneut."
|
|
264
278
|
sso-unavailable: "Diese Art der Anmeldung ist nicht verfügbar."
|
|
@@ -62,7 +62,7 @@ en:
|
|
|
62
62
|
set:
|
|
63
63
|
one: "1 set up"
|
|
64
64
|
other: "%{count} set up"
|
|
65
|
-
explained: "Instead of typing a password, your device checks it is you the way it already unlocks. It counts as
|
|
65
|
+
explained: "Instead of typing a password, your device checks it is you the way it already unlocks. It also counts as your second step, so there is no code to wait for."
|
|
66
66
|
used: "last used %{age} ago"
|
|
67
67
|
never_used: "never used"
|
|
68
68
|
remove: "Remove"
|
|
@@ -209,11 +209,11 @@ en:
|
|
|
209
209
|
remembered: "%{label}, without asking until %{date}"
|
|
210
210
|
heading: "Apps you have let in"
|
|
211
211
|
none_yet: "Nothing has asked yet. An app appears here once you sign in to it, with what you agreed it may see."
|
|
212
|
-
revoke: "
|
|
212
|
+
revoke: "Remove access"
|
|
213
213
|
more:
|
|
214
214
|
one: "and one more"
|
|
215
215
|
other: "and %{count} more"
|
|
216
|
-
confirm_revoke: "
|
|
216
|
+
confirm_revoke: "Remove %{client}'s access? Anything it is holding stops working, and it has to ask again the next time you sign in."
|
|
217
217
|
|
|
218
218
|
connections:
|
|
219
219
|
heading: "Connected accounts"
|
|
@@ -258,7 +258,7 @@ en:
|
|
|
258
258
|
|
|
259
259
|
export:
|
|
260
260
|
heading: "Download your account"
|
|
261
|
-
state: "
|
|
261
|
+
state: "A file"
|
|
262
262
|
lede: "A file with your profile, how you sign in, your organizations, apps, connected accounts, and devices, and the activity masks has kept. It holds no passwords, codes, or keys."
|
|
263
263
|
again: "You signed in a while ago, so you will be asked to sign in again first."
|
|
264
264
|
submit: "Download"
|