Update .gitignore, add environment variable operations
This commit is contained in:
parent
9ae3dc846a
commit
b04ab5aa20
|
@ -6,9 +6,8 @@
|
||||||
/storage/*.key
|
/storage/*.key
|
||||||
/vendor
|
/vendor
|
||||||
/dist-frontend
|
/dist-frontend
|
||||||
.env
|
.env*
|
||||||
.env.backup
|
!.env.example
|
||||||
.env.production
|
|
||||||
Homestead.json
|
Homestead.json
|
||||||
Homestead.yaml
|
Homestead.yaml
|
||||||
auth.json
|
auth.json
|
||||||
|
|
|
@ -188,6 +188,13 @@ class AdminController extends Controller
|
||||||
|
|
||||||
public function clearOptimization() {
|
public function clearOptimization() {
|
||||||
if(!request()->user()->hasPermission("admin-maintenance-update")) abort(401);
|
if(!request()->user()->hasPermission("admin-maintenance-update")) abort(401);
|
||||||
|
|
||||||
|
//Check if .env file exists. If not, abort the operation
|
||||||
|
if(!file_exists(base_path('.env'))) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'WARNING!! Environment file not found'
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
Artisan::call('optimize:clear');
|
Artisan::call('optimize:clear');
|
||||||
|
|
||||||
|
@ -205,6 +212,66 @@ class AdminController extends Controller
|
||||||
'message' => 'Cache cleared successfully'
|
'message' => 'Cache cleared successfully'
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function encryptEnvironment(Request $request) {
|
||||||
|
if(!request()->user()->hasPermission("admin-maintenance-update")) abort(401);
|
||||||
|
$request->validate([
|
||||||
|
'key' => 'required|string|min:6'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$key = "base64:".base64_encode(hash('sha256', $request->input('key'), true));
|
||||||
|
|
||||||
|
Artisan::call('env:encrypt', ['--force' => true, '--no-interaction' => true, '--key' => $key]);
|
||||||
|
//Check if "ERROR" is in the output
|
||||||
|
$output = Artisan::output();
|
||||||
|
if(str_contains($output, 'ERROR')) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => str_replace('ERROR ', '', $output)
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Environment encrypted successfully'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function decryptEnvironment(Request $request) {
|
||||||
|
if(!request()->user()->hasPermission("admin-maintenance-update")) abort(401);
|
||||||
|
$request->validate([
|
||||||
|
'key' => 'required|string|min:6'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$key = "base64:".base64_encode(hash('sha256', $request->input('key'), true));
|
||||||
|
|
||||||
|
Artisan::call('env:decrypt', ['--force' => true, '--no-interaction' => true, '--key' => $key]);
|
||||||
|
//Check if "ERROR" is in the output
|
||||||
|
$output = Artisan::output();
|
||||||
|
if(str_contains($output, 'ERROR')) {
|
||||||
|
return response()->json([
|
||||||
|
'message' => str_replace('ERROR ', '', $output)
|
||||||
|
], 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Delete .env.encrypted file if exists
|
||||||
|
if(file_exists(base_path('.env.encrypted'))) unlink(base_path('.env.encrypted'));
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Environment decrypted successfully'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteEnvironment() {
|
||||||
|
if(!request()->user()->hasPermission("admin-maintenance-update")) abort(401);
|
||||||
|
|
||||||
|
if(!file_exists(base_path('bootstrap/cache/config.php'))) Artisan::call('config:cache');
|
||||||
|
|
||||||
|
//Delete .env file if exists
|
||||||
|
if(file_exists(base_path('.env'))) unlink(base_path('.env'));
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'message' => 'Environment file deleted successfully'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
public function getTelegramBotDebugInfo() {
|
public function getTelegramBotDebugInfo() {
|
||||||
if(!request()->user()->hasPermission("admin-maintenance-update")) abort(401);
|
if(!request()->user()->hasPermission("admin-maintenance-update")) abort(401);
|
||||||
|
|
|
@ -109,6 +109,10 @@ Route::middleware('auth:sanctum')->group( function () {
|
||||||
Route::post('/admin/clearOptimization', [AdminController::class, 'clearOptimization']);
|
Route::post('/admin/clearOptimization', [AdminController::class, 'clearOptimization']);
|
||||||
Route::post('/admin/clearCache', [AdminController::class, 'clearCache']);
|
Route::post('/admin/clearCache', [AdminController::class, 'clearCache']);
|
||||||
|
|
||||||
|
Route::post('/admin/envEncrypt', [AdminController::class, 'encryptEnvironment']);
|
||||||
|
Route::post('/admin/envDecrypt', [AdminController::class, 'decryptEnvironment']);
|
||||||
|
Route::post('/admin/envDelete', [AdminController::class, 'deleteEnvironment']);
|
||||||
|
|
||||||
Route::get('/admin/telegramBot/debug', [AdminController::class, 'getTelegramBotDebugInfo']);
|
Route::get('/admin/telegramBot/debug', [AdminController::class, 'getTelegramBotDebugInfo']);
|
||||||
Route::post('/admin/telegramBot/setWebhook', [AdminController::class, 'setTelegramWebhook']);
|
Route::post('/admin/telegramBot/setWebhook', [AdminController::class, 'setTelegramWebhook']);
|
||||||
Route::post('/admin/telegramBot/unsetWebhook', [AdminController::class, 'unsetTelegramWebhook']);
|
Route::post('/admin/telegramBot/unsetWebhook', [AdminController::class, 'unsetTelegramWebhook']);
|
||||||
|
|
|
@ -95,8 +95,8 @@ export class ModalAlertComponent implements OnInit, OnDestroy {
|
||||||
this.translate.get([
|
this.translate.get([
|
||||||
'alert.delete_confirm_title',
|
'alert.delete_confirm_title',
|
||||||
'alert.delete_confirm_text',
|
'alert.delete_confirm_text',
|
||||||
'table.yes_remove',
|
'yes_remove',
|
||||||
'table.cancel',
|
'cancel',
|
||||||
'alert.deleted_successfully',
|
'alert.deleted_successfully',
|
||||||
'alert.delete_failed'
|
'alert.delete_failed'
|
||||||
]).subscribe((res: any) => {
|
]).subscribe((res: any) => {
|
||||||
|
@ -108,8 +108,8 @@ export class ModalAlertComponent implements OnInit, OnDestroy {
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
cancelButtonColor: '#d33',
|
cancelButtonColor: '#d33',
|
||||||
confirmButtonText: res['table.yes_remove'],
|
confirmButtonText: res['yes_remove'],
|
||||||
cancelButtonText: res['table.cancel']
|
cancelButtonText: res['cancel']
|
||||||
}).then((result: any) => {
|
}).then((result: any) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
this.api.patch(`alerts/${this.id}`, {
|
this.api.patch(`alerts/${this.id}`, {
|
||||||
|
|
|
@ -242,7 +242,7 @@ export class TableComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteService(id: number) {
|
deleteService(id: number) {
|
||||||
this.translate.get(['table.yes_remove', 'table.cancel', 'table.remove_service_confirm', 'table.remove_service_text']).subscribe((res: { [key: string]: string; }) => {
|
this.translate.get(['yes_remove', 'cancel', 'table.remove_service_confirm', 'table.remove_service_text']).subscribe((res: { [key: string]: string; }) => {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: res['table.remove_service_confirm'],
|
title: res['table.remove_service_confirm'],
|
||||||
text: res['table.remove_service_confirm_text'],
|
text: res['table.remove_service_confirm_text'],
|
||||||
|
@ -250,8 +250,8 @@ export class TableComponent implements OnInit, OnDestroy {
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
cancelButtonColor: '#d33',
|
cancelButtonColor: '#d33',
|
||||||
confirmButtonText: res['table.yes_remove'],
|
confirmButtonText: res['yes_remove'],
|
||||||
cancelButtonText: res['table.cancel']
|
cancelButtonText: res['cancel']
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
this.api.delete(`services/${id}`).then((response) => {
|
this.api.delete(`services/${id}`).then((response) => {
|
||||||
|
@ -274,7 +274,7 @@ export class TableComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteTraining(id: number) {
|
deleteTraining(id: number) {
|
||||||
this.translate.get(['table.yes_remove', 'table.cancel', 'table.remove_training_confirm', 'table.remove_training_text']).subscribe((res: { [key: string]: string; }) => {
|
this.translate.get(['yes_remove', 'cancel', 'table.remove_training_confirm', 'table.remove_training_text']).subscribe((res: { [key: string]: string; }) => {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
title: res['table.remove_training_confirm'],
|
title: res['table.remove_training_confirm'],
|
||||||
text: res['table.remove_training_confirm_text'],
|
text: res['table.remove_training_confirm_text'],
|
||||||
|
@ -282,8 +282,8 @@ export class TableComponent implements OnInit, OnDestroy {
|
||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonColor: '#3085d6',
|
confirmButtonColor: '#3085d6',
|
||||||
cancelButtonColor: '#d33',
|
cancelButtonColor: '#d33',
|
||||||
confirmButtonText: res['table.yes_remove'],
|
confirmButtonText: res['yes_remove'],
|
||||||
cancelButtonText: res['table.cancel']
|
cancelButtonText: res['cancel']
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
if (result.isConfirmed) {
|
if (result.isConfirmed) {
|
||||||
this.api.delete(`trainings/${id}`).then((response) => {
|
this.api.delete(`trainings/${id}`).then((response) => {
|
||||||
|
|
|
@ -133,6 +133,13 @@
|
||||||
<button type="button" class="btn btn-lg btn-danger" (click)="clearOptimization()">{{ 'admin.clear_optimization'|translate|ftitlecase }}</button>
|
<button type="button" class="btn btn-lg btn-danger" (click)="clearOptimization()">{{ 'admin.clear_optimization'|translate|ftitlecase }}</button>
|
||||||
<button type="button" class="btn btn-lg btn-warning" (click)="clearCache()">{{ 'admin.clear_cache'|translate|ftitlecase }}</button>
|
<button type="button" class="btn btn-lg btn-warning" (click)="clearCache()">{{ 'admin.clear_cache'|translate|ftitlecase }}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group-vertical mt-2 ps-5 pe-5">
|
||||||
|
<p class="btn-group-label">{{ 'admin.env_operations'|translate|ftitlecase }}</p>
|
||||||
|
<button type="button" class="btn btn-lg btn-primary" (click)="envEncrypt()">{{ 'admin.env_encrypt'|translate|ftitlecase }}</button>
|
||||||
|
<button type="button" class="btn btn-lg btn-warning" (click)="envDecrypt()">{{ 'admin.env_decrypt'|translate|ftitlecase }}</button>
|
||||||
|
<button type="button" class="btn btn-lg btn-danger" (click)="envDelete()">{{ 'admin.env_delete'|translate|ftitlecase }}</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -202,7 +202,6 @@ export class AdminMaintenanceComponent implements OnInit {
|
||||||
title: this.translateService.instant('success_title'),
|
title: this.translateService.instant('success_title'),
|
||||||
text: this.translateService.instant('admin.run_optimization_success')
|
text: this.translateService.instant('admin.run_optimization_success')
|
||||||
});
|
});
|
||||||
this.getDB();
|
|
||||||
}).catch((err: any) => {
|
}).catch((err: any) => {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
|
@ -219,7 +218,6 @@ export class AdminMaintenanceComponent implements OnInit {
|
||||||
title: this.translateService.instant('success_title'),
|
title: this.translateService.instant('success_title'),
|
||||||
text: this.translateService.instant('admin.clear_optimization_success')
|
text: this.translateService.instant('admin.clear_optimization_success')
|
||||||
});
|
});
|
||||||
this.getDB();
|
|
||||||
}).catch((err: any) => {
|
}).catch((err: any) => {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
|
@ -236,7 +234,6 @@ export class AdminMaintenanceComponent implements OnInit {
|
||||||
title: this.translateService.instant('success_title'),
|
title: this.translateService.instant('success_title'),
|
||||||
text: this.translateService.instant('admin.clear_cache_success')
|
text: this.translateService.instant('admin.clear_cache_success')
|
||||||
});
|
});
|
||||||
this.getDB();
|
|
||||||
}).catch((err: any) => {
|
}).catch((err: any) => {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
icon: 'error',
|
icon: 'error',
|
||||||
|
@ -246,6 +243,100 @@ export class AdminMaintenanceComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
envEncrypt() {
|
||||||
|
Swal.fire({
|
||||||
|
title: this.translateService.instant('admin.env_encrypt_title'),
|
||||||
|
text: this.translateService.instant('admin.env_encrypt_text'),
|
||||||
|
input: 'password',
|
||||||
|
inputAttributes: {
|
||||||
|
autocapitalize: 'off'
|
||||||
|
},
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: this.translateService.instant('confirm'),
|
||||||
|
cancelButtonText: this.translateService.instant('cancel'),
|
||||||
|
showLoaderOnConfirm: true,
|
||||||
|
preConfirm: (key) => {
|
||||||
|
return this.api.post('admin/envEncrypt', { key }).then((res: any) => {
|
||||||
|
return res;
|
||||||
|
}).catch((err: any) => {
|
||||||
|
Swal.showValidationMessage(
|
||||||
|
err.error.message
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
allowOutsideClick: () => !Swal.isLoading()
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'success',
|
||||||
|
title: this.translateService.instant('success_title'),
|
||||||
|
text: this.translateService.instant('admin.env_encrypt_success')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
envDecrypt() {
|
||||||
|
Swal.fire({
|
||||||
|
title: this.translateService.instant('admin.env_decrypt_title'),
|
||||||
|
text: this.translateService.instant('admin.env_decrypt_text'),
|
||||||
|
input: 'password',
|
||||||
|
inputAttributes: {
|
||||||
|
autocapitalize: 'off'
|
||||||
|
},
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: this.translateService.instant('confirm'),
|
||||||
|
cancelButtonText: this.translateService.instant('cancel'),
|
||||||
|
showLoaderOnConfirm: true,
|
||||||
|
preConfirm: (key) => {
|
||||||
|
return this.api.post('admin/envDecrypt', { key }).then((res: any) => {
|
||||||
|
return res;
|
||||||
|
}).catch((err: any) => {
|
||||||
|
Swal.showValidationMessage(
|
||||||
|
err.error.message
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
allowOutsideClick: () => !Swal.isLoading()
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'success',
|
||||||
|
title: this.translateService.instant('success_title'),
|
||||||
|
text: this.translateService.instant('admin.env_decrypt_success')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
envDelete() {
|
||||||
|
//Require confirmation before proceeding
|
||||||
|
Swal.fire({
|
||||||
|
title: this.translateService.instant('admin.env_delete_title'),
|
||||||
|
text: this.translateService.instant('admin.env_delete_text'),
|
||||||
|
icon: 'warning',
|
||||||
|
showCancelButton: true,
|
||||||
|
confirmButtonText: this.translateService.instant('yes'),
|
||||||
|
cancelButtonText: this.translateService.instant('no')
|
||||||
|
}).then((result) => {
|
||||||
|
if (result.isConfirmed) {
|
||||||
|
this.api.post('admin/envDelete').then((res: any) => {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'success',
|
||||||
|
title: this.translateService.instant('success_title'),
|
||||||
|
text: this.translateService.instant('admin.env_delete_success')
|
||||||
|
});
|
||||||
|
}).catch((err: any) => {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: this.translateService.instant('error_title'),
|
||||||
|
text: err.message
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
setTelegramBotWebhook() {
|
setTelegramBotWebhook() {
|
||||||
this.api.post('admin/telegramBot/setWebhook').then((res: any) => {
|
this.api.post('admin/telegramBot/setWebhook').then((res: any) => {
|
||||||
Swal.fire({
|
Swal.fire({
|
||||||
|
|
|
@ -52,11 +52,22 @@
|
||||||
"run": "run",
|
"run": "run",
|
||||||
"run_confirm_title": "Are you sure you want to run this command?",
|
"run_confirm_title": "Are you sure you want to run this command?",
|
||||||
"run_confirm_text": "This action cannot be undone.",
|
"run_confirm_text": "This action cannot be undone.",
|
||||||
"run_success": "Command executed successfully"
|
"run_success": "Command executed successfully",
|
||||||
|
"env_operations": "environment variables operations",
|
||||||
|
"env_encrypt": "encrypt .env",
|
||||||
|
"env_encrypt_title": "Encrypt .env file",
|
||||||
|
"env_encrypt_confirm": "Insert the password to encrypt the .env file",
|
||||||
|
"env_encrypt_success": ".env encrypted successfully",
|
||||||
|
"env_decrypt": "decrypt .env",
|
||||||
|
"env_decrypt_title": "Decrypt .env file",
|
||||||
|
"env_decrypt_confirm": "Insert the password to decrypt the .env file",
|
||||||
|
"env_decrypt_success": ".env decrypted successfully",
|
||||||
|
"env_delete": "delete .env",
|
||||||
|
"env_delete_title": "Delete .env file",
|
||||||
|
"env_delete_confirm": "Are you sure you want to delete the .env file?",
|
||||||
|
"env_delete_success": ".env deleted successfully"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"yes_remove": "Yes, remove",
|
|
||||||
"cancel": "Cancel",
|
|
||||||
"remove_service_confirm": "Are you sure you want to remove this service?",
|
"remove_service_confirm": "Are you sure you want to remove this service?",
|
||||||
"remove_service_confirm_text": "This action cannot be undone.",
|
"remove_service_confirm_text": "This action cannot be undone.",
|
||||||
"service_deleted_successfully": "Service deleted successfully",
|
"service_deleted_successfully": "Service deleted successfully",
|
||||||
|
@ -174,6 +185,9 @@
|
||||||
"file_too_big": "File too big",
|
"file_too_big": "File too big",
|
||||||
"password_min_length": "Password must be at least 6 characters long"
|
"password_min_length": "Password must be at least 6 characters long"
|
||||||
},
|
},
|
||||||
|
"yes_remove": "Yes, remove",
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"cancel": "Cancel",
|
||||||
"enable": "enable",
|
"enable": "enable",
|
||||||
"disable": "disable",
|
"disable": "disable",
|
||||||
"maintenance_mode": "maintenance mode",
|
"maintenance_mode": "maintenance mode",
|
||||||
|
|
|
@ -52,11 +52,22 @@
|
||||||
"run": "esegui",
|
"run": "esegui",
|
||||||
"run_confirm_title": "Sei sicuro di voler eseguire questo comando?",
|
"run_confirm_title": "Sei sicuro di voler eseguire questo comando?",
|
||||||
"run_confirm_text": "Questa operazione non potrà essere annullata.",
|
"run_confirm_text": "Questa operazione non potrà essere annullata.",
|
||||||
"run_success": "Comando eseguito con successo"
|
"run_success": "Comando eseguito con successo",
|
||||||
|
"env_operations": "operazioni alle variabili d'ambiente",
|
||||||
|
"env_encrypt": "cripta .env",
|
||||||
|
"env_encrypt_title": "Cripta il file .env",
|
||||||
|
"env_encrypt_text": "Inserisci la password per criptare il file .env",
|
||||||
|
"env_encrypt_success": ".env criptato con successo",
|
||||||
|
"env_decrypt": "decripta .env",
|
||||||
|
"env_decrypt_title": "Decripta il file .env",
|
||||||
|
"env_decrypt_text": "Inserisci la password per decriptare il file .env",
|
||||||
|
"env_decrypt_success": ".env decriptato con successo",
|
||||||
|
"env_delete": "rimuovi .env",
|
||||||
|
"env_delete_title": "Rimuovi il file .env",
|
||||||
|
"env_delete_text": "Sei sicuro di voler rimuovere il file .env?",
|
||||||
|
"env_delete_success": ".env rimosso con successo"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"yes_remove": "Si, rimuovi",
|
|
||||||
"cancel": "Annulla",
|
|
||||||
"remove_service_confirm": "Sei sicuro di voler rimuovere questo intervento?",
|
"remove_service_confirm": "Sei sicuro di voler rimuovere questo intervento?",
|
||||||
"remove_service_confirm_text": "Questa operazione non può essere annullata.",
|
"remove_service_confirm_text": "Questa operazione non può essere annullata.",
|
||||||
"service_deleted_successfully": "Intervento rimosso con successo",
|
"service_deleted_successfully": "Intervento rimosso con successo",
|
||||||
|
@ -174,6 +185,9 @@
|
||||||
"file_too_big": "File troppo grande",
|
"file_too_big": "File troppo grande",
|
||||||
"password_min_length": "La password deve essere di almeno 6 caratteri"
|
"password_min_length": "La password deve essere di almeno 6 caratteri"
|
||||||
},
|
},
|
||||||
|
"yes_remove": "Si, rimuovi",
|
||||||
|
"confirm": "Conferma",
|
||||||
|
"cancel": "Annulla",
|
||||||
"enable": "attiva",
|
"enable": "attiva",
|
||||||
"disable": "disattiva",
|
"disable": "disattiva",
|
||||||
"maintenance_mode": "modalità manutenzione",
|
"maintenance_mode": "modalità manutenzione",
|
||||||
|
|
Loading…
Reference in New Issue