public
nobgit
read
NobMail
Based on mailcow: dockerized
Languages
Repository composition by tracked source files.
PHP
49%
JavaScript
35%
HTML
9%
CSS
4%
Shell
2%
Python
1%
Lua
0%
Perl
0%
Ruby
0%
SCSS
0%
Create file
Wiki Documentation
Clone
https://nobgit.com/orgs/nobgit/nobmail.git
ssh://[email protected]:2222/orgs/nobgit/nobmail.git
Trace
data/web/templates/modals/footer.twig
Trace helps you understand code history line by line. See who changed each line, when it changed, and which commit introduced it.
Author
Date
Commit
Line
Code
1
{% if mailcow_cc_role %}
2
<div class="modal fade" id="YubiOTPModal" tabindex="-1" role="dialog" aria-labelledby="YubiOTPModalLabel">
3
<div class="modal-dialog" role="document">
4
<div class="modal-content">
5
<div class="modal-header">
6
<h3 class="modal-title">{{ lang.tfa.yubi_otp }}</h3>
7
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
8
</div>
9
<div class="modal-body">
10
<form role="form" method="post">
11
<div class="mb-4">
12
<input type="text" class="form-control" name="key_id" placeholder="{{ lang.tfa.key_id }}" autocomplete="off" required>
13
</div>
14
<hr>
15
<p class="text-muted">{{ lang.tfa.api_register|format(ui_texts.main_name)|raw }}</p>
16
<div class="mb-2">
17
<input type="text" class="form-control" name="yubico_id" placeholder="Yubico API ID" autocomplete="off" required>
18
</div>
19
<div class="mb-4">
20
<input type="text" class="form-control" name="yubico_key" placeholder="Yubico API Key" autocomplete="off" required>
21
</div>
22
<hr>
23
<div class="mb-4">
24
<input type="password" class="form-control" name="confirm_password" placeholder="{{ lang.user.password_now }}" autocomplete="off" required>
25
</div>
26
<div class="mb-4">
27
<div class="input-group">
28
<span class="input-group-text" id="yubi-addon"><img alt="Yubicon Icon" src="/img/yubi.ico"></span>
29
<input type="text" name="otp_token" class="form-control" placeholder="Touch Yubikey" aria-describedby="yubi-addon">
30
<input type="hidden" name="tfa_method" value="yubi_otp">
31
</div>
32
</div>
33
<button class="btn btn-sm d-block d-sm-inline btn-success" type="submit" name="set_tfa">{{ lang.user.save_changes }}</button>
34
</form>
35
</div>
36
</div>
37
</div>
38
</div>
40
<div class="modal fade" id="WebAuthnModal" tabindex="-1" role="dialog" aria-labelledby="WebAuthnModalLabel">
41
<div class="modal-dialog" role="document">
42
<div class="modal-content">
43
<div class="modal-header">
44
<h3 class="modal-title">{{ lang.tfa.webauthn }}</h3>
45
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
46
</div>
47
<div class="modal-body">
48
<form class="d-flex flex-column" role="form" method="post" id="webauthn_reg_form">
49
<div class="mb-2">
50
<input type="text" class="form-control" name="key_id" placeholder="{{ lang.tfa.key_id }}" autocomplete="off" required>
51
</div>
52
<div class="mb-4">
53
<input type="password" class="form-control" name="confirm_password" placeholder="{{ lang.user.password_now }}" autocomplete="off" required>
54
</div>
55
<hr>
56
<div class="text-center">
57
<div style="cursor:pointer" id="start_webauthn_register">
58
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 24 24">
59
<path d="M17.81 4.47c-.08 0-.16-.02-.23-.06C15.66 3.42 14 3 12.01 3c-1.98 0-3.86.47-5.57 1.41-.24.13-.54.04-.68-.2-.13-.24-.04-.55.2-.68C7.82 2.52 9.86 2 12.01 2c2.13 0 3.99.47 6.03 1.52.25.13.34.43.21.67-.09.18-.26.28-.44.28zM3.5 9.72c-.1 0-.2-.03-.29-.09-.23-.16-.28-.47-.12-.7.99-1.4 2.25-2.5 3.75-3.27C9.98 4.04 14 4.03 17.15 5.65c1.5.77 2.76 1.86 3.75 3.25.16.22.11.54-.12.7-.23.16-.54.11-.7-.12-.9-1.26-2.04-2.25-3.39-2.94-2.87-1.47-6.54-1.47-9.4.01-1.36.7-2.5 1.7-3.4 2.96-.08.14-.23.21-.39.21zm6.25 12.07c-.13 0-.26-.05-.35-.15-.87-.87-1.34-1.43-2.01-2.64-.69-1.23-1.05-2.73-1.05-4.34 0-2.97 2.54-5.39 5.66-5.39s5.66 2.42 5.66 5.39c0 .28-.22.5-.5.5s-.5-.22-.5-.5c0-2.42-2.09-4.39-4.66-4.39-2.57 0-4.66 1.97-4.66 4.39 0 1.44.32 2.77.93 3.85.64 1.15 1.08 1.64 1.85 2.42.19.2.19.51 0 .71-.11.1-.24.15-.37.15zm7.17-1.85c-1.19 0-2.24-.3-3.1-.89-1.49-1.01-2.38-2.65-2.38-4.39 0-.28.22-.5.5-.5s.5.22.5.5c0 1.41.72 2.74 1.94 3.56.71.48 1.54.71 2.54.71.24 0 .64-.03 1.04-.1.27-.05.53.13.58.41.05.27-.13.53-.41.58-.57.11-1.07.12-1.21.12zM14.91 22c-.04 0-.09-.01-.13-.02-1.59-.44-2.63-1.03-3.72-2.1-1.4-1.39-2.17-3.24-2.17-5.22 0-1.62 1.38-2.94 3.08-2.94 1.7 0 3.08 1.32 3.08 2.94 0 1.07.93 1.94 2.08 1.94s2.08-.87 2.08-1.94c0-3.77-3.25-6.83-7.25-6.83-2.84 0-5.44 1.58-6.61 4.03-.39.81-.59 1.76-.59 2.8 0 .78.07 2.01.67 3.61.1.26-.03.55-.29.64-.26.1-.55-.04-.64-.29-.49-1.31-.73-2.61-.73-3.96 0-1.2.23-2.29.68-3.24 1.33-2.79 4.28-4.6 7.51-4.6 4.55 0 8.25 3.51 8.25 7.83 0 1.62-1.38 2.94-3.08 2.94s-3.08-1.32-3.08-2.94c0-1.07-.93-1.94-2.08-1.94s-2.08.87-2.08 1.94c0 1.71.66 3.31 1.87 4.51.95.94 1.86 1.46 3.27 1.85.27.07.42.35.35.61-.05.23-.26.38-.47.38z"></path>
60
</svg>
61
<p>{{ lang.tfa.start_webauthn_validation }}</p>
62
</div>
63
</div>
64
<hr>
65
<p id="webauthn_status_reg"></p>
66
<div class="alert alert-danger" style="display:none" id="webauthn_return_code"></div>
67
<input type="hidden" name="token" id="webauthn_register_data"/>
68
<input type="hidden" name="tfa_method" value="webauthn">
69
<input type="hidden" name="set_tfa"/><br/>
70
</form>
71
</div>
72
</div>
73
</div>
74
</div>
76
<div class="modal fade" id="TOTPModal" tabindex="-1" role="dialog" aria-labelledby="TOTPModalLabel">
77
<div class="modal-dialog" role="document">
78
<div class="modal-content">
79
<div class="modal-header">
80
<h3 class="modal-title">{{ lang.tfa.totp }}</h3>
81
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
82
</div>
83
<div class="modal-body">
84
<form role="form" method="post">
85
<div class="mb-2">
86
<input type="text" class="form-control" name="key_id" placeholder="{{ lang.tfa.key_id_totp }}" autocomplete="off" required>
87
</div>
88
<div class="mb-4">
89
<input type="password" class="form-control" name="confirm_password" placeholder="{{ lang.user.password_now }}" autocomplete="off" required>
90
</div>
91
<hr>
92
<input type="hidden" value="{{ totp_secret }}" name="totp_secret">
93
<input type="hidden" name="tfa_method" value="totp">
94
<ol class="mb-4">
95
<li>
96
<p>{{ lang.tfa.scan_qr_code }}</p>
97
<img id="tfa-qr-img" data-totp-secret="{{ totp_secret }}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=">
98
<p class="text-muted">{{ lang.tfa.enter_qr_code }}:<br />
99
<code>{{ totp_secret }}</code>
100
</p>
101
</li>
102
<li>
103
<p>{{ lang.tfa.confirm_totp_token }}:</p>
104
<p><input type="number" style="width:33%" class="form-control" name="totp_confirm_token" autocomplete="off" required></p>
105
<p><button class="btn btn-sm d-block d-sm-inline btn-success" type="submit" name="set_tfa">{{ lang.tfa.confirm }}</button></p>
106
</li>
107
</ol>
108
</form>
109
</div>
110
</div>
111
</div>
112
</div>
114
<div class="modal fade" id="DisableTFAModal" tabindex="-1" role="dialog" aria-labelledby="DisableTFAModalLabel">
115
<div class="modal-dialog" role="document">
116
<div class="modal-content">
117
<div class="modal-header">
118
<h3 class="modal-title">{{ lang.tfa.delete_tfa }}</h3>
119
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
120
</div>
121
<div class="modal-body">
122
<form role="form" method="post">
123
<div class="input-group">
124
<input type="password" class="form-control" name="confirm_password" placeholder="{{ lang.user.password_now }}" autocomplete="off" required>
125
<button class="btn btn-sm d-block d-sm-inline btn-danger" type="submit" name="set_tfa">{{ lang.tfa.delete_tfa|replace({" ": " "})|raw }}</button>
126
</div>
127
<input type="hidden" name="tfa_method" value="none">
128
</form>
129
</div>
130
</div>
131
</div>
132
</div>
133
{% endif %}
134
{% if pending_tfa_methods %}
135
<div class="modal fade" id="ConfirmTFAModal" tabindex="-1" role="dialog" aria-labelledby="ConfirmTFAModalLabel">
136
<div class="modal-dialog" role="document">
137
<div class="modal-content">
138
<div class="modal-header">
139
<h3 class="modal-title">{{ lang.tfa.tfa }}</h3>
140
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
141
</div>
144
<div class="modal-body p-0 pt-4">
145
<ul class="nav nav-tabs px-1" id="tabContent">
146
{% if pending_tfa_authmechs["webauthn"] is defined and pending_tfa_authmechs["u2f"] is not defined %}
147
<li class="nav-item"><a class="nav-link active" href="#tfa_tab_webauthn" data-bs-toggle="tab" id="pending_tfa_tab_webauthn"><i class="bi bi-fingerprint"></i> WebAuthn</a></li>
148
{% endif %}
150
{% if pending_tfa_authmechs["yubi_otp"] is defined and pending_tfa_authmechs["u2f"] is not defined %}
151
<li class="nav-item">
152
<a class="nav-link {% if pending_tfa_authmechs["yubi_otp"] %}active{% endif %}" href="#tfa_tab_yubi_otp" data-bs-toggle="tab" id="pending_tfa_tab_yubi_otp"><i class="bi bi-usb-drive"></i> Yubi OTP</a>
153
</li>
154
{% endif %}
156
{% if pending_tfa_authmechs["totp"] is defined and pending_tfa_authmechs["u2f"] is not defined %}
157
<li class="nav-item">
158
<a class="nav-link {% if pending_tfa_authmechs["totp"] %}active{% endif %}" href="#tfa_tab_totp" data-bs-toggle="tab" id="pending_tfa_tab_totp"><i class="bi bi-clock-history"></i> Time-based OTP</a>
159
</li>
160
{% endif %}
162
<!-- <li class="nav-item"><a class="nav-link" href="#tfa_tab_hotp" data-bs-toggle="tab">HOTP</a></li> -->
163
{% if pending_tfa_authmechs["u2f"] is defined %}
164
<li class="nav-item"><a class="nav-link active" href="#tfa_tab_u2f" data-bs-toggle="tab"><i class="bi bi-x-octagon"></i> U2F</a></li>
165
{% endif %}
166
</ul>
168
<div class="tab-content">
169
{% if pending_tfa_authmechs["webauthn"] is defined and pending_tfa_authmechs["u2f"] is not defined %}
170
<div role="tabpanel" class="tab-pane active" id="tfa_tab_webauthn">
171
<div class="card border-0" style="margin-bottom: 0px;">
172
<div class="card-body">
173
<form role="form" method="post" id="webauthn_auth_form">
174
<legend class="mt-2 mb-2">
175
<i class="bi bi-shield-fill-check"></i>
176
{{ lang.tfa.authenticators }}
177
<hr />
178
</legend>
179
<div class="list-group">
180
{% for authenticator in pending_tfa_methods %}
181
{% if authenticator["authmech"] == "webauthn" %}
182
<a href="#" class="list-group-item webauthn-authenticator-selection">
183
<i class="bi bi-key-fill" style="margin-right: 5px"></i>
184
<span>{{ authenticator["key_id"] }}</span>
185
<input type="hidden" value="{{ authenticator["id"] }}" /><br/>
186
</a>
187
{% endif %}
188
{% endfor %}
189
</div>
190
<div class="collapse pending-tfa-collapse" id="collapseWebAuthnTFA">
191
<div class="row mt-4 mb-4">
192
<div class="col-12">
193
<div class="mt-4 d-flex align-items-center" id="webauthn_status_auth">
194
<div class="spinner-border me-2" role="status">
195
<span class="visually-hidden">Loading...</span>
196
</div>
197
{{ lang.tfa.init_webauthn }}
198
</div>
199
<div class="mt-4 alert alert-danger" style="display:none" id="webauthn_return_code"></div>
200
</div>
201
</div>
202
</div>
203
<input type="hidden" name="token" id="webauthn_auth_data"/>
204
<input type="hidden" name="tfa_method" value="webauthn">
205
<input type="hidden" name="verify_tfa_login"/>
206
<input type="hidden" name="id" id="webauthn_selected_id" /><br/>
207
</form>
208
</div>
209
</div>
210
</div>
211
{% endif %}
212
{% if pending_tfa_authmechs["yubi_otp"] is defined and pending_tfa_authmechs["u2f"] is not defined %}
213
<div role="tabpanel" class="tab-pane {% if pending_tfa_authmechs["yubi_otp"] %}active{% endif %}" id="tfa_tab_yubi_otp">
214
<div class="card border-0" style="margin-bottom: 0px;">
215
<div class="card-body">
216
<form role="form" method="post">
217
<legend class="mt-2 mb-2">
218
<i class="bi bi-shield-fill-check"></i>
219
{{ lang.tfa.authenticators }}
220
<hr />
221
</legend>
222
<div class="collapse show pending-tfa-collapse" id="collapseYubiTFA">
223
<div class="row mt-4 mb-4">
224
<div class="col-12">
225
<div class="input-group mt-4">
226
<span class="input-group-text" id="yubi-addon"><img alt="Yubicon Icon" src="/img/yubi.ico"></span>
227
<input type="text" name="token" class="form-control" autocomplete="off" placeholder="Touch Yubikey" aria-describedby="yubi-addon">
228
<input type="hidden" name="tfa_method" value="yubi_otp">
229
<input type="hidden" name="id" id="yubi_selected_id" />
230
</div>
231
</div>
232
</div>
233
<button class="btn btn-sm visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-secondary" type="submit" name="verify_tfa_login">{{ lang.login.login }}</button>
234
</div>
235
</form>
236
</div>
237
</div>
238
</div>
239
{% endif %}
240
{% if pending_tfa_authmechs["totp"] is defined and pending_tfa_authmechs["u2f"] is not defined %}
241
<div role="tabpanel" class="tab-pane {% if pending_tfa_authmechs["totp"] %}active{% endif %}" id="tfa_tab_totp">
242
<div class="card border-0" style="margin-bottom: 0px;">
243
<div class="card-body">
244
<form role="form" method="post">
245
<legend class="mt-2 mb-2">
246
<i class="bi bi-shield-fill-check"></i>
247
{{ lang.tfa.authenticators }}
248
<hr />
249
</legend>
250
<div class="list-group">
251
{% for authenticator in pending_tfa_methods %}
252
{% if authenticator["authmech"] == "totp" %}
253
<a href="#" class="list-group-item totp-authenticator-selection">
254
<i class="bi bi-key-fill" style="margin-right: 5px"></i>
255
<span>{{ authenticator["key_id"] }}</span>
256
<input type="hidden" value="{{ authenticator["id"] }}" />
257
</a>
258
{% endif %}
259
{% endfor %}
260
</div>
261
<div class="collapse pending-tfa-collapse" id="collapseTotpTFA">
262
<div class="row mt-4 mb-4">
263
<div class="col-12">
264
<div class="input-group mt-4">
265
<span class="input-group-text" id="tfa-addon"><i class="bi bi-shield-lock-fill"></i></span>
266
<input type="number" min="000000" max="999999" name="token" class="form-control" placeholder="123456" autocomplete="one-time-code" aria-describedby="tfa-addon">
267
<input type="hidden" name="tfa_method" value="totp">
268
<input type="hidden" name="id" id="totp_selected_id" /><br/>
269
</div>
270
<button class="mt-4 btn btn-sm visible-xs-block visible-sm-inline visible-md-inline visible-lg-inline btn-secondary" type="submit" name="verify_tfa_login">{{ lang.login.login }}</button>
271
</div>
272
</div>
273
</div>
274
</form>
275
</div>
276
</div>
277
</div>
278
{% endif %}
279
<!--
280
<div role="tabpanel" class="tab-pane" id="tfa_tab_hotp">
281
<div class="card" style="margin-bottom: 0px;">
282
<div class="card-body">
283
<div class="empty"></div>
284
</div>
285
</div>
286
</div>
287
-->
288
{% if pending_tfa_authmechs["u2f"] is defined %}
289
<div role="tabpanel" class="tab-pane active" id="tfa_tab_u2f">
290
<div class="card border-0" style="margin-bottom: 0px;">
291
<div class="card-body">
292
{# leave this here to inform users that u2f is deprecated #}
293
<form role="form" method="post" id="u2f_auth_form">
294
<div>
295
<p>{{ lang.tfa.u2f_deprecated }}</p>
296
<p><b>{{ lang.tfa.u2f_deprecated_important }}</b></p>
297
<input type="hidden" name="token" value="destroy" />
298
<input type="hidden" name="tfa_method" value="u2f">
299
<input type="hidden" name="verify_tfa_login"/><br/>
300
<button type="submit" class="btn btn-xs-lg btn-success" value="Login">{{ lang.login.login }}</button>
301
</div>
302
</form>
303
</div>
304
</div>
305
</div>
306
{% endif %}
307
</div>
309
</div>
310
</div>
311
</div>
312
</div>
313
{% endif %}
314
{% if pending_tfa_setup %}
315
<div class="modal fade" id="SetupTFAModal" tabindex="-1" role="dialog" aria-labelledby="SetupTFAModalLabel">
316
<div class="modal-dialog" role="document">
317
<div class="modal-content">
318
<div class="modal-header">
319
<h3 class="modal-title">{{ lang.tfa.setup_title }}</h3>
320
<form method="post" class="d-inline">
321
<button type="submit" name="logout" value="1" class="btn-close" aria-label="Close"></button>
322
</form>
323
</div>
324
<div class="modal-body">
325
<div class="alert alert-warning">
326
<i class="bi bi-shield-exclamation"></i> {{ lang.tfa.setup_required }}
327
</div>
328
<ul class="nav nav-tabs mb-3" id="setupTFATabNav">
329
<li class="nav-item">
330
<a class="nav-link active" href="#setup_tab_totp" data-bs-toggle="tab"><i class="bi bi-clock-history"></i> Time-based OTP</a>
331
</li>
332
<li class="nav-item">
333
<a class="nav-link" href="#setup_tab_webauthn" data-bs-toggle="tab"><i class="bi bi-fingerprint"></i> WebAuthn</a>
334
</li>
335
<li class="nav-item">
336
<a class="nav-link" href="#setup_tab_yubi" data-bs-toggle="tab"><i class="bi bi-usb-drive"></i> Yubi OTP</a>
337
</li>
338
</ul>
339
<div class="tab-content">
340
<div role="tabpanel" class="tab-pane active" id="setup_tab_totp">
341
<form role="form" method="post" id="setup_totp_form">
342
<div class="mb-2">
343
<input type="text" class="form-control" name="key_id" placeholder="{{ lang.tfa.key_id_totp }}" autocomplete="off" required>
344
</div>
345
<hr>
346
<input type="hidden" value="{{ totp_secret }}" name="totp_secret">
347
<input type="hidden" name="tfa_method" value="totp">
348
<ol class="mb-4">
349
<li>
350
<p>{{ lang.tfa.scan_qr_code }}</p>
351
<img id="setup-tfa-qr-img" data-totp-secret="{{ totp_secret }}" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=">
352
<p class="text-muted">{{ lang.tfa.enter_qr_code }}:<br />
353
<code>{{ totp_secret }}</code>
354
</p>
355
</li>
356
<li>
357
<p>{{ lang.tfa.confirm_totp_token }}:</p>
358
<p><input type="number" style="width:33%" class="form-control" name="totp_confirm_token" autocomplete="off" required></p>
359
<p><button class="btn btn-sm d-block d-sm-inline btn-success" type="submit" name="set_tfa">{{ lang.tfa.confirm }}</button></p>
360
</li>
361
</ol>
362
</form>
363
</div>
364
<div role="tabpanel" class="tab-pane" id="setup_tab_webauthn">
365
<form class="d-flex flex-column" role="form" method="post" id="setup_webauthn_reg_form">
366
<div class="mb-2">
367
<input type="text" class="form-control" name="key_id" placeholder="{{ lang.tfa.key_id }}" autocomplete="off" required>
368
</div>
369
<hr>
370
<div class="text-center">
371
<div style="cursor:pointer" id="start_setup_webauthn_register">
372
<i class="bi bi-fingerprint" style="font-size:4rem"></i>
373
<p>{{ lang.tfa.start_webauthn_validation }}</p>
374
</div>
375
</div>
376
<hr>
377
<p id="setup_webauthn_status_reg"></p>
378
<div class="alert alert-danger" style="display:none" id="setup_webauthn_return_code"></div>
379
<input type="hidden" name="token" id="setup_webauthn_register_data"/>
380
<input type="hidden" name="tfa_method" value="webauthn">
381
<input type="hidden" name="set_tfa"/><br/>
382
</form>
383
</div>
384
<div role="tabpanel" class="tab-pane" id="setup_tab_yubi">
385
<form role="form" method="post">
386
<div class="mb-4">
387
<input type="text" class="form-control" name="key_id" placeholder="{{ lang.tfa.key_id }}" autocomplete="off" required>
388
</div>
389
<hr>
390
<p class="text-muted">{{ lang.tfa.api_register|format(ui_texts.main_name)|raw }}</p>
391
<div class="mb-2">
392
<input type="text" class="form-control" name="yubico_id" placeholder="Yubico API ID" autocomplete="off" required>
393
</div>
394
<div class="mb-4">
395
<input type="text" class="form-control" name="yubico_key" placeholder="Yubico API Key" autocomplete="off" required>
396
</div>
397
<hr>
398
<div class="mb-4">
399
<div class="input-group">
400
<span class="input-group-text" id="yubi-setup-addon"><img alt="Yubicon Icon" src="/img/yubi.ico"></span>
401
<input type="text" name="otp_token" class="form-control" placeholder="Touch Yubikey" aria-describedby="yubi-setup-addon">
402
<input type="hidden" name="tfa_method" value="yubi_otp">
403
</div>
404
</div>
405
<button class="btn btn-sm d-block d-sm-inline btn-success" type="submit" name="set_tfa">{{ lang.user.save_changes }}</button>
406
</form>
407
</div>
408
</div>
409
</div>
410
</div>
411
</div>
412
</div>
413
{% endif %}
414
{% if pending_pw_update_modal and not pending_tfa_methods %}
415
<div class="modal fade" id="ChangePWModal" tabindex="-1" role="dialog" aria-labelledby="ChangePWModalLabel">
416
<div class="modal-dialog" role="document">
417
<div class="modal-content">
418
<div class="modal-header">
419
<h3 class="modal-title">{{ lang.user.change_password }}</h3>
420
<form method="post" class="d-inline">
421
<button type="submit" name="logout" value="1" class="btn-close" aria-label="Close"></button>
422
</form>
423
</div>
424
<div class="modal-body">
425
<div class="alert alert-warning">
426
<i class="bi bi-key"></i> {{ lang.user.pw_update_required }}
427
</div>
428
<form role="form" id="changePWModalForm">
429
<div class="mb-3">
430
<input type="password" class="form-control" id="changePWNew" placeholder="{{ lang.user.new_password }}" autocomplete="new-password" required>
431
</div>
432
<div class="mb-4">
433
<input type="password" class="form-control" id="changePWNew2" placeholder="{{ lang.user.new_password_repeat }}" autocomplete="new-password" required>
434
</div>
435
<div id="changePWAlert" class="alert alert-danger" style="display:none"></div>
436
<button class="btn btn-sm btn-success" type="submit">{{ lang.user.save_changes }}</button>
437
</form>
438
</div>
439
</div>
440
</div>
441
</div>
442
{% endif %}
443
{% if mailcow_cc_role == 'admin' %}
444
<div id="RestartContainer" class="modal fade" role="dialog">
445
<div class="modal-dialog">
446
<div class="modal-content">
447
<div class="modal-header">
448
<h4 class="modal-title">{{ lang.footer.restart_container }} (<code id="containerName"></code>)</h4>
449
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
450
</div>
451
<div class="modal-body">
452
<p>{{ lang.footer.restart_container_info|raw }}</p>
453
<hr>
454
<button class="btn btn-md d-block d-sm-inline btn-primary" id="triggerRestartContainer">{{ lang.footer.restart_now }}</button>
455
<br><br>
456
<div id="statusTriggerRestartContainer"></div>
457
</div>
458
</div>
459
</div>
460
</div>
461
{% endif %}
462
<div id="ConfirmDeleteModal" class="modal fade" role="dialog">
463
<div class="modal-dialog">
464
<div class="modal-content">
465
<div class="modal-header">
466
<h3 class="modal-title">{{ lang.footer.confirm_delete }}</h3>
467
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
468
</div>
469
<div class="modal-body">
470
<p id="DeleteText">{{ lang.footer.delete_these_items }}</p>
471
<ul id="ItemsToDelete"></ul>
472
<hr>
473
<button class="btn btn-sm btn-xs-half d-block d-sm-inline btn-danger" id="IsConfirmed">{{ lang.footer.delete_now }}</button>
474
<button class="btn btn-sm btn-xs-half d-block d-sm-inline btn-secondary" id="isCanceled">{{ lang.footer.cancel }}</button>
475
</div>
476
</div>
477
</div>
478
</div>
479
<!-- version modal -->
480
<div class="modal fade" id="showVersionModal" tabindex="-1" role="dialog" aria-hidden="true">
481
<div class="modal-dialog modal-lg">
482
<div class="modal-content">
483
<div class="modal-header">
484
<h5 class="modal-title"></h5>
485
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
486
</div>
487
<div class="modal-body d-flex flex-column mt-2 p-4">
488
<div class="spinner-border mx-auto" role="status">
489
<span class="visually-hidden">Loading...</span>
490
</div>
491
</div>
492
</div>
493
</div>
494
</div><!-- version modal -->