1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
<main class="container">
<div id="users-block" class="my-3 p-3 bg-white rounded shadow">
<h6 class="border-bottom pb-2 mb-3">Registered Users</h6>
<div class="table-responsive-xl small">
<table id="users-table" class="table table-sm table-striped table-hover">
<thead>
<tr>
<th>User</th>
<th style="width:60px; min-width: 60px;">Items</th>
<th>Attachments</th>
<th style="min-width: 120px;">Organizations</th>
<th style="width: 140px; min-width: 140px;">Actions</th>
</tr>
</thead>
<tbody>
{{#each users}}
<tr>
<td>
<img class="float-left mr-2 rounded identicon" data-src="{{Email}}">
<div class="float-left">
<strong>{{Name}}</strong>
<span class="d-block">{{Email}}</span>
<span class="d-block">Created at: {{created_at}}</span>
<span class="d-block">Last active: {{last_active}}</span>
<span class="d-block">
{{#if TwoFactorEnabled}}
<span class="badge badge-success mr-2" title="2FA is enabled">2FA</span>
{{/if}}
{{#case _Status 1}}
<span class="badge badge-warning mr-2" title="User is invited">Invited</span>
{{/case}}
{{#if EmailVerified}}
<span class="badge badge-success mr-2" title="Email has been verified">Verified</span>
{{/if}}
</span>
</div>
</td>
<td>
<span class="d-block">{{cipher_count}}</span>
</td>
<td>
<span class="d-block"><strong>Amount:</strong> {{attachment_count}}</span>
{{#if attachment_count}}
<span class="d-block"><strong>Size:</strong> {{attachment_size}}</span>
{{/if}}
</td>
<td>
{{#each Organizations}}
<span class="badge badge-primary" data-orgtype="{{Type}}">{{Name}}</span>
{{/each}}
</td>
<td style="font-size: 90%; text-align: right; padding-right: 15px">
{{#if TwoFactorEnabled}}
<a class="d-block" href="#" onclick='remove2fa({{jsesc Id}})'>Remove all 2FA</a>
{{/if}}
<a class="d-block" href="#" onclick='deauthUser({{jsesc Id}})'>Deauthorize sessions</a>
<a class="d-block" href="#" onclick='deleteUser({{jsesc Id}}, {{jsesc Email}})'>Delete User</a>
</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
<div class="mt-3">
<button type="button" class="btn btn-sm btn-danger" onclick="updateRevisions();"
title="Force all clients to fetch new data next time they connect. Useful after restoring a backup to remove any stale data.">
Force clients to resync
</button>
<button type="button" class="btn btn-sm btn-primary float-right" onclick="reload();">Reload users</button>
</div>
</div>
<div id="invite-form-block" class="align-items-center p-3 mb-3 text-white-50 bg-secondary rounded shadow">
<div>
<h6 class="mb-0 text-white">Invite User</h6>
<small>Email:</small>
<form class="form-inline" id="invite-form" onsubmit="inviteUser(); return false;">
<input type="email" class="form-control w-50 mr-2" id="email-invite" placeholder="Enter email">
<button type="submit" class="btn btn-primary">Invite</button>
</form>
</div>
</div>
</main>
<link rel="stylesheet" href="{{urlpath}}/bwrs_static/datatables.css" />
<script src="{{urlpath}}/bwrs_static/jquery-3.5.1.slim.js"></script>
<script src="{{urlpath}}/bwrs_static/datatables.js"></script>
<script>
function deleteUser(id, mail) {
var input_mail = prompt("To delete user '" + mail + "', please type the email below")
if (input_mail != null) {
if (input_mail == mail) {
_post("{{urlpath}}/admin/users/" + id + "/delete",
"User deleted correctly",
"Error deleting user");
} else {
alert("Wrong email, please try again")
}
}
return false;
}
function remove2fa(id) {
_post("{{urlpath}}/admin/users/" + id + "/remove-2fa",
"2FA removed correctly",
"Error removing 2FA");
return false;
}
function deauthUser(id) {
_post("{{urlpath}}/admin/users/" + id + "/deauth",
"Sessions deauthorized correctly",
"Error deauthorizing sessions");
return false;
}
function updateRevisions() {
_post("{{urlpath}}/admin/users/update_revision",
"Success, clients will sync next time they connect",
"Error forcing clients to sync");
return false;
}
function inviteUser() {
inv = document.getElementById("email-invite");
data = JSON.stringify({ "email": inv.value });
inv.value = "";
_post("{{urlpath}}/admin/invite/", "User invited correctly",
"Error inviting user", data);
return false;
}
let OrgTypes = {
"0": { "name": "Owner", "color": "orange" },
"1": { "name": "Admin", "color": "blueviolet" },
"2": { "name": "User", "color": "blue" },
"3": { "name": "Manager", "color": "green" },
};
document.querySelectorAll("img.identicon").forEach(function (e, i) {
e.src = identicon(e.dataset.src);
});
document.querySelectorAll("[data-orgtype]").forEach(function (e, i) {
let orgtype = OrgTypes[e.dataset.orgtype];
e.style.backgroundColor = orgtype.color;
e.title = orgtype.name;
});
document.addEventListener("DOMContentLoaded", function(event) {
$('#users-table').DataTable({
"responsive": true,
"lengthMenu": [ [-1, 5, 10, 25, 50], ["All", 5, 10, 25, 50] ],
"pageLength": -1, // Default show all
"columns": [
null, // Userdata
null, // Items
null, // Attachments
null, // Organizations
{ "searchable": false, "orderable": false }, // Actions
],
});
});
</script>
|