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/user.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
<!-- change fido2 fn -->
2
<div class="modal fade" id="fido2ChangeFn" tabindex="-1" role="dialog" aria-hidden="true">
3
<div class="modal-dialog modal-lg">
4
<div class="modal-content">
5
<div class="modal-header">
6
<h3 class="modal-title">{{ lang.fido2.set_fn }}</h3>
7
<p class="text-muted" style="word-break:break-all" id="fido2_subject_desc" data-fido2-subject=""></p>
8
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
9
</div>
10
<div class="modal-body">
11
<form class="form-horizontal" data-cached-form="false" data-id="fido2ChangeFn" role="form" method="post" autocomplete="off">
12
<input type="hidden" class="form-control" name="fido2_cid" id="fido2_cid">
13
<div class="row mb-4">
14
<label class="control-label col-sm-4 text-end" for="fido2_fn">{{ lang.fido2.fn }}:</label>
15
<div class="col-sm-8">
16
<input type="text" class="form-control" name="fido2_fn">
17
</div>
18
</div>
19
<div class="row">
20
<div class="offset-sm-4 col-sm-8">
21
<button class="btn btn-xs-lg d-block d-sm-inline btn-success" data-action="edit_selected" data-id="fido2ChangeFn" data-item="null" data-api-url='edit/fido2-fn' data-api-attr='{}' href="#">{{ lang.admin.save }}</button>
22
</div>
23
</div>
24
</form>
25
</div>
26
</div>
27
</div>
28
</div><!-- add domain admin modal -->
29
<!-- add sync job modal -->
30
<div class="modal fade" id="addSyncJobModal" tabindex="-1" role="dialog" aria-hidden="true">
31
<div class="modal-dialog modal-xl">
32
<div class="modal-content">
33
<div class="modal-header">
34
<h3 class="modal-title">{{ lang.add.syncjob }}</h3>
35
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
36
</div>
37
<div class="modal-body">
38
<p>{{ lang.add.syncjob_hint }}</p>
39
<form class="form-horizontal" data-cached-form="true" role="form" data-id="add_syncjob">
40
<div class="row mb-2">
41
<label class="control-label col-sm-2" for="host1">{{ lang.add.hostname }}</label>
42
<div class="col-sm-10">
43
<input type="text" class="form-control" name="host1" required>
44
</div>
45
</div>
46
<div class="row mb-4">
47
<label class="control-label col-sm-2" for="port1">{{ lang.add.port }}</label>
48
<div class="col-sm-10">
49
<input type="number" class="form-control" name="port1" min="1" max="65535" value="143" required>
50
<small class="text-muted">1-65535</small>
51
</div>
52
</div>
53
<div class="row mb-2">
54
<label class="control-label col-sm-2" for="user1">{{ lang.add.username }}</label>
55
<div class="col-sm-10">
56
<input type="text" class="form-control" name="user1" required>
57
</div>
58
</div>
59
<div class="row mb-4">
60
<label class="control-label col-sm-2" for="password1">{{ lang.add.password }}</label>
61
<div class="col-sm-10">
62
<input type="password" class="form-control" name="password1" data-hibp="true" required>
63
</div>
64
</div>
65
<div class="row mb-2">
66
<label class="control-label col-sm-2" for="enc1">{{ lang.add.enc_method }}</label>
67
<div class="col-sm-10">
68
<select name="enc1" title="{{ lang.add.select }}" required>
69
<option value="SSL" selected>SSL</option>
70
<option value="TLS">STARTTLS</option>
71
<option value="PLAIN">PLAIN</option>
72
</select>
73
</div>
74
</div>
75
<div class="row mb-2">
76
<label class="control-label col-sm-2" for="mins_interval">{{ lang.add.mins_interval }}</label>
77
<div class="col-sm-10">
78
<input type="number" class="form-control" name="mins_interval" min="1" max="43800" value="20" required>
79
<small class="text-muted">1-43800</small>
80
</div>
81
</div>
82
<div class="row mb-2">
83
<label class="control-label col-sm-2" for="subfolder2">{{ lang.edit.subfolder2|raw }}</label>
84
<div class="col-sm-10">
85
<input type="text" class="form-control" name="subfolder2" value="">
86
</div>
87
</div>
88
<div class="row mb-2">
89
<label class="control-label col-sm-2" for="maxage">{{ lang.edit.maxage|raw }}</label>
90
<div class="col-sm-10">
91
<input type="number" class="form-control" name="maxage" min="0" max="32000" value="0">
92
<small class="text-muted">0-32000</small>
93
</div>
94
</div>
95
<div class="row mb-2">
96
<label class="control-label col-sm-2" for="maxbytespersecond">{{ lang.edit.maxbytespersecond|raw }}</label>
97
<div class="col-sm-10">
98
<input type="number" class="form-control" name="maxbytespersecond" min="0" max="125000000" value="0">
99
<small class="text-muted">0-125000000</small>
100
</div>
101
</div>
102
<div class="row mb-2">
103
<label class="control-label col-sm-2" for="timeout1">{{ lang.edit.timeout1 }}</label>
104
<div class="col-sm-10">
105
<input type="number" class="form-control" name="timeout1" min="1" max="32000" value="600">
106
<small class="text-muted">1-32000</small>
107
</div>
108
</div>
109
<div class="row mb-2">
110
<label class="control-label col-sm-2" for="timeout2">{{ lang.edit.timeout2 }}</label>
111
<div class="col-sm-10">
112
<input type="number" class="form-control" name="timeout2" min="1" max="32000" value="600">
113
<small class="text-muted">1-32000</small>
114
</div>
115
</div>
116
<div class="row mb-2">
117
<label class="control-label col-sm-2" for="exclude">{{ lang.add.exclude }}</label>
118
<div class="col-sm-10">
119
<input type="text" class="form-control" name="exclude" value="(?i)spam|(?i)junk">
120
</div>
121
</div>
122
<div class="row mb-4">
123
<label class="control-label col-sm-2" for="custom_params">{{ lang.add.custom_params }}</label>
124
<div class="col-sm-10">
125
<input type="text" class="form-control" name="custom_params" placeholder="--delete2folders --otheroption">
126
</div>
127
</div>
128
<div class="row mb-2">
129
<div class="offset-sm-2 col-sm-10">
130
<div class="form-check">
131
<label><input type="checkbox" class="form-check-input" value="1" name="delete2duplicates" checked> {{ lang.add.delete2duplicates }} (--delete2duplicates)</label>
132
</div>
133
</div>
134
</div>
135
<div class="row mb-2">
136
<div class="offset-sm-2 col-sm-10">
137
<div class="form-check">
138
<label><input type="checkbox" class="form-check-input" value="1" name="delete1"> {{ lang.add.delete1 }} (--delete1)</label>
139
</div>
140
</div>
141
</div>
142
<div class="row mb-2">
143
<div class="offset-sm-2 col-sm-10">
144
<div class="form-check">
145
<label><input type="checkbox" class="form-check-input" value="1" name="delete2"> {{ lang.add.delete2 }} (--delete2)</label>
146
</div>
147
</div>
148
</div>
149
<div class="row mb-2">
150
<div class="offset-sm-2 col-sm-10">
151
<div class="form-check">
152
<label><input type="checkbox" class="form-check-input" value="1" name="automap" checked> {{ lang.add.automap }} (--automap)</label>
153
</div>
154
</div>
155
</div>
156
<div class="row mb-2">
157
<div class="offset-sm-2 col-sm-10">
158
<div class="form-check">
159
<label><input type="checkbox" class="form-check-input" value="1" name="skipcrossduplicates"> {{ lang.add.skipcrossduplicates }} (--skipcrossduplicates)</label>
160
</div>
161
</div>
162
</div>
163
<div class="row mb-2">
164
<div class="offset-sm-2 col-sm-10">
165
<div class="form-check">
166
<label><input type="checkbox" class="form-check-input" value="1" name="subscribeall" checked> {{ lang.add.subscribeall }} (--subscribeall)</label>
167
</div>
168
</div>
169
</div>
170
<div class="row mb-2">
171
<div class="offset-sm-2 col-sm-10">
172
<div class="form-check">
173
<label><input type="checkbox" class="form-check-input" value="1" name="dry" checked> {{ lang.add.dry }} (--dry)</label>
174
</div>
175
</div>
176
</div>
177
<div class="row mb-4">
178
<div class="offset-sm-2 col-sm-10">
179
<div class="form-check">
180
<label><input type="checkbox" class="form-check-input" value="1" name="active" checked> {{ lang.add.active }}</label>
181
</div>
182
</div>
183
</div>
184
<div class="row mb-2">
185
<div class="offset-sm-2 col-sm-10">
186
<button class="btn btn-xs-lg d-block d-sm-inline btn-success" data-action="add_item" data-id="add_syncjob" data-api-url='add/syncjob' data-api-attr='{}' href="#">{{ lang.admin.add }}</button>
187
</div>
188
</div>
189
</form>
190
</div>
191
</div>
192
</div>
193
</div><!-- add sync job modal -->
194
<!-- app passwd modal -->
195
<div class="modal fade" id="addAppPasswdModal" tabindex="-1" role="dialog" aria-hidden="true">
196
<div class="modal-dialog modal-lg">
197
<div class="modal-content">
198
<div class="modal-header">
199
<h3 class="modal-title">{{ lang.add.app_password }}</h3>
200
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
201
</div>
202
<div class="modal-body">
203
<form class="form-horizontal" data-cached-form="true" role="form" data-pwgen-length="32" data-id="add_apppasswd">
204
<div class="row mb-2">
205
<label class="control-label col-sm-2" for="app_name">{{ lang.add.app_name }}</label>
206
<div class="col-sm-10">
207
<input type="text" class="form-control" name="app_name" required>
208
</div>
209
</div>
210
<div class="row mb-4">
211
<label class="control-label col-sm-2" for="app_passwd">{{ lang.user.password }} (<a href="#" class="generate_password">{{ lang.user.generate }}</a>)</label>
212
<div class="col-sm-10">
213
<input type="password" data-pwgen-field="true" data-hibp="true" class="form-control" name="app_passwd" autocomplete="new-password" required>
214
</div>
215
</div>
216
<div class="row mb-2">
217
<label class="control-label col-sm-2" for="app_passwd2">{{ lang.user.password_repeat }}</label>
218
<div class="col-sm-10">
219
<input type="password" data-pwgen-field="true" class="form-control" name="app_passwd2" autocomplete="new-password" required>
220
<p class="text-muted">{{ lang.user.new_password_description }}</p>
221
</div>
222
</div>
223
<div class="row mb-4">
224
<label class="control-label col-sm-2" for="protocols">{{ lang.add.app_passwd_protocols }}</label>
225
<div class="col-sm-10">
226
<select class="full-width-select" data-live-search="true" id="protocols" name="protocols" multiple>
227
<option value="imap_access" selected>IMAP</option>
228
<option value="smtp_access" selected>SMTP</option>
229
<option value="eas_access" selected>EAS/ActiveSync</option>
230
<option value="dav_access" selected>CardDAV/CalDAV</option>
231
<option value="pop3_access" selected>POP3</option>
232
<option value="sieve_access" selected>Sieve</option>
233
</select>
234
</div>
235
</div>
236
<div class="row mb-2">
237
<div class="offset-sm-2 col-sm-10">
238
<div class="form-check">
239
<label><input type="checkbox" class="form-check-input" value="1" name="active" checked> {{ lang.add.active }}</label>
240
</div>
241
</div>
242
</div>
243
<div class="row mb-2">
244
<div class="offset-sm-2 col-sm-10">
245
<button class="btn btn-xs-lg d-block d-sm-inline btn-success" data-action="add_item" data-id="add_apppasswd" data-api-url='add/app-passwd' data-api-attr='{}' href="#">{{ lang.admin.add }}</button>
246
</div>
247
</div>
248
</form>
249
</div>
250
</div>
251
</div>
252
</div><!-- add app passwd modal -->
253
<!-- log modal -->
254
<div class="modal fade" id="syncjobLogModal" tabindex="-1" role="dialog" aria-labelledby="syncjobLogModalLabel">
255
<div class="modal-dialog modal-xl" role="document">
256
<div class="modal-content">
257
<div class="modal-header">
258
<h3 class="modal-title">Log</h3>
259
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
260
</div>
261
<div class="modal-body">
262
<textarea class="form-control textarea-code" rows="20" id="logText" spellcheck="false"></textarea>
263
</div>
264
</div>
265
</div>
266
</div><!-- log modal -->
267
<!-- pw change modal -->
268
<div class="modal fade" id="pwChangeModal" tabindex="-1" role="dialog" aria-labelledby="pwChangeModalLabel">
269
<div class="modal-dialog modal-lg" role="document">
270
<div class="modal-content">
271
<div class="modal-header">
272
<h3 class="modal-title">{{ lang.user.change_password }}</h3>
273
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
274
</div>
275
<div class="modal-body">
276
<form class="form-horizontal" data-cached-form="false" data-id="pwchange" role="form" method="post" autocomplete="off">
277
<div class="row">
278
<label class="control-label col-sm-3" for="user_new_pass">{{ lang.user.new_password }} (<a href="#" class="generate_password">{{ lang.user.generate }}</a>)</label>
279
<div class="col-sm-9">
280
<input type="password" data-pwgen-field="true" data-hibp="true" class="form-control" name="user_new_pass" autocomplete="new-password" required>
281
</div>
282
</div>
283
<div class="row">
284
<label class="control-label col-sm-3" for="user_new_pass2">{{ lang.user.new_password_repeat }}</label>
285
<div class="col-sm-9">
286
<input type="password" data-pwgen-field="true" class="form-control" name="user_new_pass2" autocomplete="new-password" required>
287
<p class="text-muted">{{ lang.user.new_password_description }}</p>
288
</div>
289
</div>
290
<hr>
291
<div class="row mb-4">
292
<label class="control-label col-sm-3" for="user_old_pass">{{ lang.user.password_now }}</label>
293
<div class="col-sm-9">
294
<input type="password" class="form-control" name="user_old_pass" autocomplete="off" required>
295
{% if number_of_app_passwords > 0 %}
296
<div class="invalid-feedback d-block">
297
{{ lang.user.change_password_hint_app_passwords|format(number_of_app_passwords) }}
298
</div>
299
{% endif %}
300
</div>
301
</div>
302
<div class="row">
303
<div class="offset-sm-3 col-sm-9">
304
<button class="btn btn-xs-lg d-block d-sm-inline btn-success" data-action="edit_selected" data-id="pwchange" data-item="null" data-api-url='edit/self' data-api-attr='{}' href="#">{{ lang.user.change_password }}</button>
305
</div>
306
</div>
307
</form>
308
</div>
309
</div>
310
</div>
311
</div><!-- pw change modal -->
312
<!-- pw recovery email modal -->
313
<div class="modal fade" id="pwRecoveryEmailModal" tabindex="-1" role="dialog" aria-labelledby="pwRecoveryEmailModalLabel">
314
<div class="modal-dialog modal-lg" role="document">
315
<div class="modal-content">
316
<div class="modal-header">
317
<h3 class="modal-title">{{ lang.user.pw_recovery_email }}</h3>
318
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
319
</div>
320
<div class="modal-body">
321
<form class="form-horizontal" data-cached-form="false" data-id="pw_recovery_change" role="form" method="post" autocomplete="off">
322
<div class="row mb-4">
323
<label class="control-label col-sm-3" for="pw_recovery_email">{{ lang.user.email }}</label>
324
<div class="col-sm-9">
325
<input type="email" class="form-control" name="pw_recovery_email" value="{{ mailboxdata.attributes.recovery_email }}">
326
<small class="text-muted">{{ lang.user.password_reset_info }}</small>
327
</div>
328
</div>
329
<div class="row mb-4">
330
<label class="control-label col-sm-3" for="user_old_pass">{{ lang.user.password_now }}</label>
331
<div class="col-sm-9">
332
<input type="password" class="form-control" name="user_old_pass" autocomplete="off" required>
333
</div>
334
</div>
335
<div class="row">
336
<div class="offset-sm-3 col-sm-9">
337
<button class="btn btn-xs-lg d-block d-sm-inline btn-success" data-action="edit_selected" data-id="pw_recovery_change" data-item="null" data-api-url='edit/self' data-api-attr='{}' href="#">{{ lang.user.save }}</button>
338
</div>
339
</div>
340
</form>
341
</div>
342
</div>
343
</div>
344
</div><!-- pw recovery email modal -->
345
<!-- temp alias modal -->
346
<div class="modal fade" id="tempAliasModal" tabindex="-1" role="dialog" aria-labelledby="tempAliasModalLabel">
347
<div class="modal-dialog modal-lg" role="document">
348
<div class="modal-content">
349
<div class="modal-header">
350
<h3 class="modal-title">{{ lang.user.alias_create_random }}</h3>
351
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
352
</div>
353
<div class="modal-body">
354
<form class="form-horizontal" data-cached-form="false" data-id="tempaliascreate" role="form" method="post" autocomplete="off">
355
<div class="row mb-4">
356
<label class="control-label col-sm-3" for="description">{{ lang.user.description }}</label>
357
<div class="col-sm-5">
358
<input type="hidden" id="temp_alias_domain" name="domain">
359
<input type="description" id="temp_alias_description" class="form-control" name="description" autocomplete="off">
360
</div>
361
</div>
362
<div class="row">
363
<div class="offset-sm-3 col-sm-9">
364
<button class="btn btn-xs-lg d-block d-sm-inline btn-success" data-action="add_item" data-id="tempaliascreate" data-item="null" data-api-url='add/time_limited_alias' data-api-attr='' href="#">{{ lang.admin.add }}</button>
365
</div>
366
</div>
367
</form>
368
</div>
369
</div>
370
</div>
371
</div><!-- temp alias modal -->
372
<!-- sieve filter modal -->
373
<div class="modal fade" id="userFilterModal" tabindex="-1" role="dialog">
374
<div class="modal-dialog modal-lg" role="document">
375
<div class="modal-content">
376
<div class="modal-header">
377
<h3 class="modal-title">{{ lang.user.active_sieve }}</h3>
378
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
379
</div>
380
<div class="modal-body">
381
<pre id="user_sieve_filter"></pre>
382
</div>
383
</div>
384
</div>
385
</div><!-- sieve filter modal -->