@igea/oac_frontend 1.0.17 → 1.0.19
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.
- package/package.json +1 -1
- package/src/controllers/captcha.js +33 -0
- package/src/index.js +7 -1
- package/src/locales/en.json +9 -0
- package/src/locales/it.json +9 -0
- package/src/models/DataModel +4 -2
- package/src/public/images/captcha/01.jpg +0 -0
- package/src/public/images/captcha/02.jpg +0 -0
- package/src/public/images/captcha/03.jpg +0 -0
- package/src/public/images/captcha/04.jpg +0 -0
- package/src/public/images/captcha/05.jpg +0 -0
- package/src/public/images/captcha/06.jpg +0 -0
- package/src/public/images/captcha/07.jpg +0 -0
- package/src/public/images/captcha/08.jpg +0 -0
- package/src/public/images/captcha/09.jpg +0 -0
- package/src/public/images/captcha/10.jpg +0 -0
- package/src/public/images/captcha/11.jpg +0 -0
- package/src/public/images/captcha/12.jpg +0 -0
- package/src/public/images/captcha/13.jpg +0 -0
- package/src/public/images/captcha/14.jpg +0 -0
- package/src/public/images/captcha/15.jpg +0 -0
- package/src/public/images/captcha/16.jpg +0 -0
- package/src/public/images/captcha/17.jpg +0 -0
- package/src/public/images/captcha/18.jpg +0 -0
- package/src/public/js/app/vue-users-edit.js +4 -1
- package/src/public/js/app/vue-users-manage.js +2 -1
- package/src/views/sidebar.twig +28 -16
- package/src/views/users/edit.twig +3 -1
- package/src/views/users/manage.twig +1 -0
package/package.json
CHANGED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const router = express.Router();
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
|
|
6
|
+
// folder where your images are stored
|
|
7
|
+
const IMAGES_DIR = path.join(__dirname, '..', 'public', 'images', 'captcha');
|
|
8
|
+
|
|
9
|
+
router.get('/random-image', (req, res) => {
|
|
10
|
+
fs.readdir(IMAGES_DIR, (err, files) => {
|
|
11
|
+
if (err) {
|
|
12
|
+
console.error(err);
|
|
13
|
+
return res.status(500).send('Error reading images directory');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// filter only images (jpg, png, gif, etc.)
|
|
17
|
+
const imageFiles = files.filter(f =>
|
|
18
|
+
/\.(jpg|jpeg|png|gif|webp)$/i.test(f)
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
if (imageFiles.length === 0) {
|
|
22
|
+
return res.status(404).send('No images found');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// pick a random file
|
|
26
|
+
const randomFile = imageFiles[Math.floor(Math.random() * imageFiles.length)];
|
|
27
|
+
|
|
28
|
+
// send the image file
|
|
29
|
+
res.sendFile(path.join(IMAGES_DIR, randomFile));
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
module.exports = router;
|
package/src/index.js
CHANGED
|
@@ -12,7 +12,8 @@ const jwtLib = jwtLibFactory({
|
|
|
12
12
|
secret: process.env.JWT_SECRET || config.jwt_secret,
|
|
13
13
|
excludePaths: [
|
|
14
14
|
`/${serviceName}/`,
|
|
15
|
-
`/${serviceName}/health
|
|
15
|
+
`/${serviceName}/health`,
|
|
16
|
+
`/${serviceName}/captcha/random-image`
|
|
16
17
|
],
|
|
17
18
|
signOptions: { expiresIn: '15m' },
|
|
18
19
|
redirectTo: `/${serviceName}/`
|
|
@@ -74,6 +75,11 @@ getPort.default({
|
|
|
74
75
|
|
|
75
76
|
const usersRouter = require('./controllers/users.js')(serviceName);
|
|
76
77
|
app.use(`/${serviceName}/users`, usersRouter);
|
|
78
|
+
|
|
79
|
+
const captchaRouter = require('./controllers/captcha.js');
|
|
80
|
+
app.use(`/${serviceName}/captcha`, captchaRouter);
|
|
81
|
+
// ---------------------------------------------------------------------
|
|
82
|
+
// Application routes
|
|
77
83
|
// ---------------------------------------------------------------------
|
|
78
84
|
app.get(`/${serviceName}`, (req, res) => {
|
|
79
85
|
res.render('login', { root: serviceName, title: 'Login' });
|
package/src/locales/en.json
CHANGED
package/src/locales/it.json
CHANGED
package/src/models/DataModel
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -10,6 +10,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
10
10
|
data() {
|
|
11
11
|
return {
|
|
12
12
|
root: el.dataset.root,
|
|
13
|
+
cur_id: parseInt(el.dataset.cur_id),
|
|
14
|
+
cur_role: parseInt(el.dataset.cur_role),
|
|
13
15
|
labels: {
|
|
14
16
|
role_sudo: el.dataset.role_sudo,
|
|
15
17
|
role_admin: el.dataset.role_admin,
|
|
@@ -79,9 +81,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
79
81
|
username: this.user.username,
|
|
80
82
|
email: this.user.email,
|
|
81
83
|
mobile: this.user.mobile,
|
|
82
|
-
password: this.user.password,
|
|
83
84
|
role: this.user.role
|
|
84
85
|
};
|
|
86
|
+
if(this.user.password.length > 0)
|
|
87
|
+
payload["password"] = this.user.password;
|
|
85
88
|
let request;
|
|
86
89
|
if(this.user.id == 0) {
|
|
87
90
|
delete payload["id"];
|
|
@@ -11,6 +11,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
11
11
|
return {
|
|
12
12
|
root: el.dataset.root,
|
|
13
13
|
cur_id: parseInt(el.dataset.cur_id) || 0,
|
|
14
|
+
cur_role: parseInt(el.dataset.cur_role),
|
|
14
15
|
labels: {
|
|
15
16
|
role_sudo: el.dataset.role_sudo,
|
|
16
17
|
role_admin: el.dataset.role_admin,
|
|
@@ -29,7 +30,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
29
30
|
axios.get("/backend/users/").then(response => {
|
|
30
31
|
var data = response.data;
|
|
31
32
|
if(data.success) {
|
|
32
|
-
this.users = data.data;
|
|
33
|
+
this.users = data.data.filter(u => u.role != 0 || this.cur_role == 0);
|
|
33
34
|
} else {
|
|
34
35
|
console.error("Failed to fetch users:", data.message);
|
|
35
36
|
}
|
package/src/views/sidebar.twig
CHANGED
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
{% block sidebar %}
|
|
2
|
-
|
|
3
|
-
{% if user.id > 0 %}
|
|
4
|
-
|
|
5
|
-
<!-- abilitare solo per utenti ADMIN -->
|
|
6
|
-
{% if cur_role != "admin" %}
|
|
7
|
-
<div class="menu-item">
|
|
8
|
-
<a href="/{{ root }}/users/manage">
|
|
9
|
-
<i class="fa-solid fa-users-between-lines"></i>
|
|
10
|
-
<span>{{ t('users.manage.title') }}</span>
|
|
11
|
-
</a>
|
|
12
|
-
</div>
|
|
13
|
-
{% endif %}
|
|
14
2
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
<!-- abilitare solo per utenti ADMIN -->
|
|
4
|
+
{% if user.role == 0 or user.role == 1 %}
|
|
5
|
+
<div class="menu-item">
|
|
6
|
+
<a href="/{{ root }}/users/manage">
|
|
7
|
+
<i class="fa-solid fa-users-between-lines"></i>
|
|
8
|
+
<span>{{ t('users.manage.title') }}</span>
|
|
19
9
|
</a>
|
|
20
10
|
</div>
|
|
11
|
+
{% endif %}
|
|
21
12
|
|
|
13
|
+
{% if user.id > 0 %}
|
|
14
|
+
<div class="menu-item">
|
|
15
|
+
<a href="/{{ root }}/users/{{ cur_id }}">
|
|
16
|
+
<i class="fa-solid fa-id-badge"></i>
|
|
17
|
+
{{ t('users.profile.title') }}
|
|
18
|
+
</a>
|
|
19
|
+
</div>
|
|
22
20
|
{% endif %}
|
|
23
21
|
|
|
22
|
+
<div class="menu-item">
|
|
23
|
+
<a href="/{{ root }}/search/fast">
|
|
24
|
+
<i class="fa-solid fa-magnifying-glass"></i>
|
|
25
|
+
{{ t('search.fast.title') }}
|
|
26
|
+
</a>
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div class="menu-item">
|
|
30
|
+
<a href="/{{ root }}/search/advanced">
|
|
31
|
+
<i class="fa-solid fa-magnifying-glass-dollar"></i>
|
|
32
|
+
{{ t('search.advanced.title') }}
|
|
33
|
+
</a>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
24
36
|
{% endblock %}
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
data-role_reader="{{ t('users.role.reader') }}"
|
|
16
16
|
data-user_id = "{{ id }}"
|
|
17
17
|
data-save_ok="{{ t('users.edit.save_ok') }}"
|
|
18
|
+
data-cur_id="{{ cur_id }}"
|
|
19
|
+
data-cur_role="{{ user.role }}"
|
|
18
20
|
>
|
|
19
21
|
<h2 style="display:flex; justify-content:space-between; align-items:center;">
|
|
20
22
|
{% if id == 0 %}
|
|
@@ -90,7 +92,7 @@
|
|
|
90
92
|
<!-- Role -->
|
|
91
93
|
<div class="col-md-6">
|
|
92
94
|
<label for="role" class="form-label">{{ t('users.manage.role') }}:</label>
|
|
93
|
-
<select v-model.number="user.role" id="role" class="form-select">
|
|
95
|
+
<select v-model.number="user.role" id="role" class="form-select" :disabled="cur_id==user.id">
|
|
94
96
|
<option :value="0">{{ t('users.role.sudo') }}</option>
|
|
95
97
|
<option :value="1">{{ t('users.role.admin') }}</option>
|
|
96
98
|
<option :value="2">{{ t('users.role.editor') }}</option>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
data-role_reader="{{ t('users.role.reader') }}"
|
|
17
17
|
data-confirm_delete="{{ t('users.manage.confirm_delete') }}"
|
|
18
18
|
data-cur_id="{{ cur_id }}"
|
|
19
|
+
data-cur_role="{{ user.role }}"
|
|
19
20
|
>
|
|
20
21
|
<h2 style="display:flex; justify-content:space-between; align-items:center;">
|
|
21
22
|
<span>{{ t('users.manage.title') }}</span>
|