Introduzione pagine di base
Aggiornamento pagine di segnalazione bug, informazioni utente e log degli accessi.
This commit is contained in:
parent
14a09053a1
commit
04ff4439ed
|
@ -2,107 +2,34 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Backup;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Emails\Account;
|
||||
use Notifications\EmailNotification;
|
||||
use Update;
|
||||
|
||||
class InfoController extends Controller
|
||||
{
|
||||
/** @var int Lunghezza minima della password */
|
||||
public static $min_length_password = 8;
|
||||
|
||||
protected static $bugEmail = 'info@openstamanager.com';
|
||||
|
||||
public function info()
|
||||
{
|
||||
return view('info.info');
|
||||
}
|
||||
|
||||
public function logs()
|
||||
{
|
||||
$user = auth()->getUser();
|
||||
|
||||
$query = 'SELECT * FROM `zz_logs`';
|
||||
if (!Auth::admin()) {
|
||||
$query .= ' WHERE `id_utente`='.prepare($user['id']);
|
||||
}
|
||||
$query .= ' ORDER BY `created_at` DESC LIMIT 0, 100';
|
||||
|
||||
$results = $this->database->fetchArray($query);
|
||||
|
||||
$status = Auth::getStatus();
|
||||
$data = [];
|
||||
foreach ($status as $state) {
|
||||
$color = 'warning';
|
||||
|
||||
$color = $state['code'] == $status['success']['code'] ? 'success' : $color;
|
||||
$color = $state['code'] == $status['failed']['code'] ? 'danger' : $color;
|
||||
|
||||
$data[$state['code']] = [
|
||||
'message' => $state['message'],
|
||||
'color' => $color,
|
||||
];
|
||||
}
|
||||
|
||||
$args['status'] = $data;
|
||||
$args['results'] = $results;
|
||||
|
||||
$response = $this->twig->render($response, '@resources/info/logs.twig', $args);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
$tokens = $user->getApiTokens();
|
||||
$token = $tokens[0]['token'];
|
||||
|
||||
$api = BASEURL.'/api/?token='.$token;
|
||||
|
||||
$args['api'] = $api;
|
||||
$args['token'] = $token;
|
||||
$args['sync_link'] = $api.'&resource=sync';
|
||||
|
||||
$response = $this->twig->render($response, '@resources/user/user.twig', $args);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function password()
|
||||
{
|
||||
$args['min_length_password'] = self::$min_length_password;
|
||||
|
||||
$response = $this->twig->render($response, '@resources/user/password.twig', $args);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
public function passwordPost()
|
||||
{
|
||||
$user = auth()->getUser();
|
||||
$password = post('password');
|
||||
|
||||
$user->password = $password;
|
||||
$user->save();
|
||||
|
||||
flash()->info(tr('Password aggiornata!'));
|
||||
|
||||
$response = $response->withRedirect($this->router->urlFor('user'));
|
||||
|
||||
return $response;
|
||||
return view('info');
|
||||
}
|
||||
|
||||
public function bug()
|
||||
{
|
||||
$args['mail'] = Account::where('predefined', true)->first();
|
||||
$args['bug_email'] = self::$bugEmail;
|
||||
$account = Account::where('predefined', true)->first();
|
||||
|
||||
$response = $this->twig->render($response, '@resources/info/bug.twig', $args);
|
||||
|
||||
return $response;
|
||||
return view('bug', [
|
||||
'mail' => $account,
|
||||
'bug_email' => self::$bugEmail,
|
||||
]);
|
||||
}
|
||||
|
||||
public function bugSend()
|
||||
public function send(Request $request)
|
||||
{
|
||||
$user = auth()->getUser();
|
||||
$user = auth()->user();
|
||||
$bug_email = self::$bugEmail;
|
||||
|
||||
// Preparazione email
|
||||
|
@ -112,16 +39,17 @@ class InfoController extends Controller
|
|||
$mail->AddAddress($bug_email);
|
||||
|
||||
// Oggetto
|
||||
$mail->Subject = 'Segnalazione bug OSM '.$args['version'];
|
||||
$mail->Subject = 'Segnalazione bug OSM '.Update::getVersion();
|
||||
|
||||
// Aggiunta dei file di log (facoltativo)
|
||||
if (!empty(post('log')) && file_exists(DOCROOT.'/logs/error.log')) {
|
||||
$mail->AddAttachment(DOCROOT.'/logs/error.log');
|
||||
$log_file = base_path('/logs/error.log');
|
||||
if (!empty($request->input('log')) && file_exists($log_file)) {
|
||||
$mail->AddAttachment($log_file);
|
||||
}
|
||||
|
||||
// Aggiunta della copia del database (facoltativo)
|
||||
if (!empty(post('sql'))) {
|
||||
$backup_file = DOCROOT.'/Backup OSM '.date('Y-m-d').' '.date('H_i_s').'.sql';
|
||||
if (!empty($request->input('sql'))) {
|
||||
$backup_file = base_path('backup/Backup OSM '.date('Y-m-d').' '.date('H_i_s').'.sql');
|
||||
Backup::database($backup_file);
|
||||
|
||||
$mail->AddAttachment($backup_file);
|
||||
|
@ -133,17 +61,17 @@ class InfoController extends Controller
|
|||
$infos = [
|
||||
'Utente' => $user['username'],
|
||||
'IP' => get_client_ip(),
|
||||
'Versione OSM' => $args['version'].' ('.($args['revision'] ? $args['revision'] : 'In sviluppo').')',
|
||||
'Versione OSM' => Update::getVersion().' ('.(Update::getRevision() ?: tr('In sviluppo')).')',
|
||||
'PHP' => phpversion(),
|
||||
];
|
||||
|
||||
// Aggiunta delle informazioni sul sistema (facoltativo)
|
||||
if (!empty(post('info'))) {
|
||||
if (!empty($request->input('info'))) {
|
||||
$infos['Sistema'] = $_SERVER['HTTP_USER_AGENT'].' - '.getOS();
|
||||
}
|
||||
|
||||
// Completamento del body
|
||||
$body = post('body').'<hr>';
|
||||
$body = $request->input('body').'<hr>';
|
||||
foreach ($infos as $key => $value) {
|
||||
$body .= '<p>'.$key.': '.$value.'</p>';
|
||||
}
|
||||
|
@ -160,12 +88,10 @@ class InfoController extends Controller
|
|||
}
|
||||
|
||||
// Rimozione del dump del database
|
||||
if (!empty(post('sql'))) {
|
||||
if (!empty($request->input('sql'))) {
|
||||
delete($backup_file);
|
||||
}
|
||||
|
||||
$response = $response->withRedirect($this->router->urlFor('bug'));
|
||||
|
||||
return $response;
|
||||
return redirect(route('bug'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Models\Log;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
/** @var int Lunghezza minima della password */
|
||||
public static $min_length_password = 8;
|
||||
|
||||
public function index()
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
$tokens = $user->getApiTokens();
|
||||
$token = $tokens[0]['token'];
|
||||
|
||||
$api = base_url().'/api/?token='.$token;
|
||||
|
||||
$args = [
|
||||
'user' => $user,
|
||||
'api' => $api,
|
||||
'token' => $token,
|
||||
'sync_link' => $api.'&resource=sync',
|
||||
];
|
||||
|
||||
return view('user.info', $args);
|
||||
}
|
||||
|
||||
public function password()
|
||||
{
|
||||
$args['min_length_password'] = self::$min_length_password;
|
||||
|
||||
return view('user.password', $args);
|
||||
}
|
||||
|
||||
public function save(Request $request)
|
||||
{
|
||||
$user = auth()->user();
|
||||
$password = $request->input('password');
|
||||
|
||||
$user->password = $password;
|
||||
$user->save();
|
||||
|
||||
flash()->info(tr('Password aggiornata!'));
|
||||
|
||||
return redirect(route('user-info'));
|
||||
}
|
||||
|
||||
public function logs()
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
$logs = Log::orderBy('created_at')->limit(100);
|
||||
if (!$user->isAdmin()) {
|
||||
$logs = $logs->where('id_utente', '=', $user->id);
|
||||
}
|
||||
|
||||
$logs = $logs->get();
|
||||
|
||||
return view('user.logs', [
|
||||
'logs' => $logs,
|
||||
]);
|
||||
}
|
||||
}
|
2
legacy
2
legacy
|
@ -1 +1 @@
|
|||
Subproject commit 0b21ecf084f81a8c4178fce4808c4026d937d12c
|
||||
Subproject commit a4c7c2c560cc34d7d48b81158db3795650968c8b
|
|
@ -0,0 +1,107 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', tr("Bug"))
|
||||
|
||||
@section('content')
|
||||
@if(empty($mail['from_address']) or empty($mail['server']))
|
||||
<div class="alert alert-warning">
|
||||
<i class="fa fa-warning"></i>
|
||||
<b>{{ tr('Attenzione!') }}</b> {{ tr('Per utilizzare correttamente il modulo di segnalazione bug devi configurare alcuni parametri riguardanti le impostazione delle email') }}.
|
||||
|
||||
{!! module('Account email')->link($mail['id'], tr('Correggi account'), null, 'class="btn btn-warning pull-right"') !!}
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="box box-outline box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><i class="fa fa-bug"></i> {{ tr('Segnalazione bug') }}</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<form method="post" action="{{ route('bug-send') }}">
|
||||
@csrf
|
||||
|
||||
<table class="table table-bordered table-condensed table-striped table-hover">
|
||||
<tr>
|
||||
<th width="150" class="text-right">{{ tr('Da') }}:</th>
|
||||
<td>{{ $mail['from_address'] }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- A -->
|
||||
<tr>
|
||||
<th class="text-right">{{ tr('A') }}:</th>
|
||||
<td>{{ $bug_email }}</td>
|
||||
</tr>
|
||||
|
||||
<!-- Versione -->
|
||||
<tr>
|
||||
<th class="text-right">{{ tr('Versione OSM') }}:</th>
|
||||
<td>{{ Update::getVersion() }} ({{ Update::getRevision() ?: tr('In sviluppo') }})</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
{[ "type": "checkbox", "label": "{{ tr('Allega file di log') }}", "name": "log", "value": "1" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
{[ "type": "checkbox", "label": "{{ tr('Allega copia del database') }}", "name": "sql" ]}
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
{[ "type": "checkbox", "label": "{{ tr('Allega informazioni sul PC') }}", "name": "info", "value": "1" ]}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<br>
|
||||
|
||||
{[ "type": "ckeditor", "label": "{{ tr('Descrizione del bug') }}", "name": "body" ]}
|
||||
|
||||
<!-- PULSANTI -->
|
||||
<div class="row">
|
||||
<div class="col-md-12 text-right">
|
||||
<button type="submit" class="btn btn-primary" id="send" disabled>
|
||||
<i class="fa fa-envelope"></i> {{ tr('Invia segnalazione') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
init();
|
||||
|
||||
// Impostazione del messaggio
|
||||
var html = `<p>{{ tr('Se hai riscontrato un bug ricordati di specificare') }}:</p>
|
||||
<ul>
|
||||
<li>{{ tr('Modulo esatto (o pagina relativa) in cui questi si è verificato') }};</li>
|
||||
<li>{{ tr('Dopo quali specifiche operazioni hai notato il malfunzionamento') }}.</li>
|
||||
</ul>
|
||||
<p>{{ tr("Assicurati inoltre di controllare che il checkbox relativo ai file di log sia contrassegnato, oppure riporta qui l'errore visualizzato") }}.</p>
|
||||
<p>{{ tr('Ti ringraziamo per il tuo contributo') }},<br>
|
||||
{{ tr('Lo staff di OSM') }}</p>`;
|
||||
let editor = input("body");
|
||||
var firstFocus = true;
|
||||
/*
|
||||
editor.set(html);
|
||||
|
||||
editor.on("key", function() {
|
||||
setTimeout(function(){
|
||||
$("#send").prop("disabled", editor.get() === "");
|
||||
}, 10);
|
||||
});
|
||||
|
||||
editor.on("focus", function() {
|
||||
if (firstFocus) {
|
||||
editor.set("");
|
||||
firstFocus = 0;
|
||||
}
|
||||
});*/
|
||||
});
|
||||
</script>
|
||||
@endsection
|
|
@ -5,6 +5,8 @@
|
|||
$module = \Models\Module::getCurrent();
|
||||
$id_module = $module ? $module->id : null;
|
||||
$id_record = isset($id_record) ? $id_record : null;
|
||||
|
||||
$user = auth()->user();
|
||||
@endphp
|
||||
|
||||
@section('js')
|
||||
|
@ -70,7 +72,7 @@
|
|||
'hookMultiple': "{{ tr('Hai _NUM_ notifiche') }}",
|
||||
'hookSingle': "{{ tr('Hai 1 notifica') }}",
|
||||
'hookNone': "{{ tr('Nessuna notifica') }}",
|
||||
'singleCalendar': {{ tr("E' presente un solo periodo!") }}",
|
||||
'singleCalendar': "{{ tr("E' presente un solo periodo!") }}",
|
||||
ajax: {
|
||||
"missing": {
|
||||
"title": "{{ tr('Errore') }}",
|
||||
|
@ -239,17 +241,17 @@
|
|||
<aside class="main-sidebar"><!-- sidebar-dark-primary elevation-4 -->
|
||||
<section class="sidebar">
|
||||
<!-- Sidebar user panel -->
|
||||
<a href="{{ route('user') }}" class="user-panel text-center info" style="height: 60px">
|
||||
<a href="{{ route('user-info') }}" class="user-panel text-center info" style="height: 60px">
|
||||
<div class="text-center mt-2">
|
||||
@if (auth()->user()->photo)
|
||||
<img src="{{ base_url() }}{{ auth()->user()->photo }}" class="profile-user-img img-fluid img-circle" alt="{{ auth()->user()->username }}" />
|
||||
@if ($user->photo)
|
||||
<img src="{{ base_url() }}{{ $user->photo }}" class="profile-user-img img-fluid img-circle" alt="{{ $user->username }}" />
|
||||
@else
|
||||
<i class="fa fa-user-circle-o fa-5x"></i>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<h3 class="profile-username text-center" style="width: 100%; padding-top: 10px;">
|
||||
{{ auth()->user()->username }}
|
||||
{{ $user->username }}
|
||||
</h3>
|
||||
<p class="text-center" id="datetime"></p>
|
||||
</a>
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
@extends('layouts.app')
|
||||
|
||||
@section('title', tr("Utenza corrente"))
|
||||
|
||||
@section('content')
|
||||
<div class="box box-widget widget-user">
|
||||
<div class="widget-user-header bg-primary">
|
||||
<h3 class="widget-user-username">{{ $user->username }}</h3>
|
||||
<h5 class="widget-user-desc">{{ $user->gruppo }}</h5>
|
||||
</div>
|
||||
|
||||
<div class="widget-user-image">
|
||||
@if($user->photo)
|
||||
<img src="{{ $user->photo }}" class="img-circle" alt="{{ $user->username }}" />
|
||||
@else
|
||||
<i class="fa fa-user-circle-o fa-4x pull-left"></i>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="box-footer">
|
||||
<div class="row">
|
||||
<div class="col-sm-4 border-right">
|
||||
<div class="description-block">
|
||||
<h5 class="description-header">{{ tr('Anagrafica associata') }}</h5>
|
||||
<span class="description-text">{{ $user->anagrafica['ragione_sociale'] ? $user->anagrafica['ragione_sociale'] : tr('Nessuna') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-4 border-right">
|
||||
<div class="description-block">
|
||||
<a class="btn btn-info btn-block tip" data-href="" data-toggle="modal" data-title="{{ tr('Cambia foto utente') }}">
|
||||
<i class="fa fa-picture-o"></i> {{ tr('Cambia foto utente') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-4 border-right">
|
||||
<div class="description-block">
|
||||
<a class="btn btn-warning btn-block tip" data-href="{{ route('user-password') }}" data-toggle="modal" data-title="{{ tr('Cambia password') }}">
|
||||
<i class="fa fa-unlock-alt"></i> {{ tr('Cambia password') }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
|
||||
<div class="box box-outline box-success">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">{{ tr('API') }}</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<p>{{ tr("Puoi utilizzare il token per accedere all'API del gestionale e per visualizzare il calendario su applicazioni esterne") }}.</p>
|
||||
|
||||
<p>{{ tr('Token personale') }}: <b>{{ $token }}</b></p>
|
||||
<p>{{ tr("URL dell'API") }}: <a href="{{ $api }}" target="_blank">{{ $api }}</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="box box-outline box-info">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title">{{ tr('Calendario interventi') }}</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body">
|
||||
<p>{{ tr("Per accedere al calendario eventi attraverso l'API, accedi al seguente link") }}:</p>
|
||||
<a href="{{ $sync_link }}" target="_blank">{{ $sync_link }}</a>
|
||||
|
||||
<hr>
|
||||
<h5>{{ tr('Configurazione') }}</h5>
|
||||
<p>{!! tr("Per _ANDROID_, scarica un'applicazione dedicata dal _LINK_", [
|
||||
'_ANDROID_' => '<b>'.tr('Android').'</b>',
|
||||
'_LINK_' => '<a href="https://play.google.com/store/search?q=iCalSync&c=apps" target="_blank">'.tr('Play Store').'</a>',
|
||||
]) !!}.</p>
|
||||
|
||||
<p>{!! tr("Per _APPLE_, puoi configurare un nuovo calendario dall'app standard del calendario", [
|
||||
'_APPLE_' => '<b>'.tr('Apple').'</b>',
|
||||
]) !!}.</p>
|
||||
|
||||
<p>{!! tr('Per _PC_ e altri client di posta, considerare le relative funzionalità o eventuali plugin', [
|
||||
'_PC_' => '<b>'.tr('PC').'</b>',
|
||||
]) !!}.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>$(document).ready(init)</script>
|
||||
@endsection
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', tr("Accessi"))
|
||||
|
||||
@section('content')
|
||||
<div class="box box-outline box-primary">
|
||||
<div class="box-header">
|
||||
<h3 class="box-title"><i class="fa fa-book"></i> {{ tr('Ultimi 100 accessi') }}</h3>
|
||||
</div>
|
||||
|
||||
<div class="box-body table-responsive">
|
||||
<table class="datatables table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ tr('Username') }}</th>
|
||||
<th>{{ tr('Data') }}</th>
|
||||
<th>{{ tr('Stato') }}</th>
|
||||
<th>{{ tr('Indirizzo IP') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
@foreach($logs as $log)
|
||||
<tr class="bg-{{ $log->color }}">
|
||||
<td>{{ $log->username }}</td>
|
||||
<td>{{ timestampFormat($log->created_at) }}</td>
|
||||
<td><span class="label label-{{ $log->color }}">{{ $log->message }}</span></td>
|
||||
<td>{{ $log->ip }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
|
@ -4,6 +4,7 @@ use App\Http\Controllers\ConfigurationController;
|
|||
use App\Http\Controllers\InfoController;
|
||||
use App\Http\Controllers\InitializationController;
|
||||
use App\Http\Controllers\Test;
|
||||
use App\Http\Controllers\UserController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
/*
|
||||
|
@ -91,18 +92,20 @@ Route::get('/info', [InfoController::class, 'info'])
|
|||
->name('info');
|
||||
|
||||
// Segnalazione bug
|
||||
Route::get('/bug', [Test::class, 'index'])
|
||||
Route::get('/bug', [InfoController::class, 'bug'])
|
||||
->name('bug');
|
||||
Route::post('/bug', [Test::class, 'index']);
|
||||
Route::post('/bug', [InfoController::class, 'send'])
|
||||
->name('bug-send');
|
||||
|
||||
// Log di accesso
|
||||
Route::get('/logs', [Test::class, 'index'])
|
||||
Route::get('/logs', [UserController::class, 'logs'])
|
||||
->name('logs');
|
||||
|
||||
// Informazioni sull'utente
|
||||
Route::get('/user', [Test::class, 'index'])
|
||||
->name('user');
|
||||
Route::get('/user', [UserController::class, 'index'])
|
||||
->name('user-info');
|
||||
|
||||
Route::get('/password', [Test::class, 'index'])
|
||||
Route::get('/password', [UserController::class, 'password'])
|
||||
->name('user-password');
|
||||
Route::post('/password', [Test::class, 'index']);
|
||||
Route::post('/password', [UserController::class, 'save'])
|
||||
->name('user-password-save');;
|
||||
|
|
Loading…
Reference in New Issue