Files
raven/server/AyaNova/Controllers/ApiRootController.cs
2020-01-28 00:28:52 +00:00

478 lines
21 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using AyaNova.Util;
using AyaNova.Biz;
using AyaNova.Api.ControllerHelpers;
using Microsoft.AspNetCore.Authorization;
using System.Threading.Tasks;
namespace AyaNova.Api.Controllers
{
/// <summary>
/// Meta controller class
/// </summary>
[ApiVersion("8.0")]
[Route("api/v{version:apiVersion}/")]
[AllowAnonymous]
[ApiController]
public class ApiMetaController : ControllerBase
{
private readonly ApiServerState serverState;
private readonly ILogger<ApiMetaController> _log;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="apiServerState"></param>
public ApiMetaController(ILogger<ApiMetaController> logger, ApiServerState apiServerState)
{
_log = logger;
serverState = apiServerState;
}
/// <summary>
/// AyaNova API documentation and manual
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<ContentResult> Index()
{
var errorBlock = string.Empty;
if (serverState.IsSystemLocked)
{
errorBlock = $@"<div style=""color: #D8000C;background-color: #FFD2D2""><h2>SERVER ERROR</h2><p>{serverState.Reason}</p></div>";
}
var resp = $@"<html lang=""en"">
<head>
<meta charset=""utf-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1, shrink-to-fit=no"">
<title>AyaNova server</title>
<script src=/jquery-1.9.1.js></script>
</head>
<body >
<div style=""text-align: center;"">
{errorBlock}
<div style=""display: inline-block;text-align:left;"">
<h1>{AyaNovaVersion.FullNameAndVersion}</h1>
<a href=""/"" target=""_blank"">AyaNova App</a><br/><br/>
<a href=""/docs"" target=""_blank"">AyaNova manual</a><br/><br/>
<a href=""/api-docs"" target=""_blank"">API explorer</a><br/><br/>
<a href=""mailto:support@ayanova.com"">Email AyaNova support</a><br/><br/>
<h4>{await LocaleBiz.GetDefaultLocalizedTextAsync("HelpLicense")}</h4>
<pre>{AyaNova.Core.License.LicenseInfo}</pre>
<h4>Schema version</h4>
<pre>{AySchema.currentSchema.ToString()}</pre>
<h4>Active techs</h4>
<pre>{await UserBiz.ActiveCountAsync()}</pre>
<h4>Server time</h4>
<pre>{DateUtil.ServerDateTimeString(System.DateTime.UtcNow)}</pre>
<pre>{TimeZoneInfo.Local.Id}</pre>
<h4>Server logs</h4>
<pre>{ServerBootConfig.AYANOVA_LOG_PATH}</pre>
</div>
</div>
</body>
</html>";
return new ContentResult
{
ContentType = "text/html",
StatusCode = 200,
Content = resp
};
}
#region sigtest script
/*
<div style=""text-align: center;"">
<hr/>
<h2>SIGTEST - 1</h2>
<h4>This is the signature header</h4>
<canvas id=""sigpad"" width=""600"" height=""200"" style=""border: 1px dotted;touch-action: none;"">
<p>
Your browser does not support signing <br/>
The following browsers are supported:<br/>
IE 9.0 +, FIREFOX 3.0 +, SAFARI 3.0 +, CHROME 3.0 +, OPERA 10.0 +, IPAD 1.0 +, IPHONE
1.0 +, ANDROID 1.0 +</p>
</canvas>
</div>
{SigScript()}
private string SigScript(){
return @"<script type=""text/javascript"">
$(document).ready(function () {
var canvas = document.getElementById(""sigpad"");
///////////////////////////////////////////////
// Prevent scrolling when touching the canvas
//addEventListener('touchstart', FUNCTION, {passive: false});
document.body.addEventListener(""touchstart"", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, {passive: false});
document.body.addEventListener(""touchend"", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, {passive: false});
document.body.addEventListener(""touchmove"", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, {passive: false});
///////////////////////////////////////////////
$('#sigpad').sigpad();
});
(function ($) {
$.fn.extend(
{
sigpad: function (options) {
// Default options
var defaults = {
lineWidth: 3.0,
lineCap: 'round',
lineJoin: 'round',
miterLimit: 10,
strokeStyle: 'black',
fillStyle: 'none',
showClear: false,
clearLabel: 'Clear',
clearStyle: 'button'
};
options = $.extend(defaults, options);
return this.each(function () {
if (this.nodeName === 'CANVAS') {
$(this).css('cursor', 'pointer');
//$(this).attr('onclick', 'function onclick(event) { void 1; }');
$(this).click('function onclick(event) { void 1; }');
if (this.getContext) {
var canvas = this;
var context = this.getContext('2d');
var id = $(this).attr('id');
$(this).after('<div id=""' + id + '-controls"" style=""width:' + $(this).width() + 'px""></div>');
context.underInteractionEnabled = true;
// Overrides with passed options
context.lineWidth = options.lineWidth;
context.lineCap = options.lineCap;
context.lineJoin = options.lineJoin;
context.miterLimit = options.miterLimit;
context.strokeStyle = options.strokeStyle;
context.fillStyle = options.fillStyle;
var data_input = id + '-data';
$(this).after('<input type=""hidden"" id=""' + data_input + '"" name=""' + data_input + '"" />');
//case 1975
//add hidden to form dirty tracking
$('form').trigger('rescan.areYouSure');
// Defines all our tracking variables
var drawing = false;
var height = $('#' + id).height();
var width = $('#' + id).width();
var svg_path = '';
var scrollLeft = 0;
var scrollTop = 0;
// var offsetX = $(this).attr('offsetLeft');
// var offsetY = $(this).attr('offsetTop');
var offsetX = 0;
var offsetY = 0;
var inside = false;
var prevX = false;
var prevY = false;
var x = false;
var y = false;
// Mouse events
$(document).mousedown(function (e) { drawingStart(e); });
$(document).mousemove(function (e) { drawingMove(e); });
$(document).mouseup(function () { drawingStop(); });
// Touch events
$(document).bind('touchstart', function (e) { drawingStart(e); });
$(document).bind('touchmove', function (e) { drawingMove(e); });
$(document).bind('touchend', function () { drawingStop(); });
$(document).bind('touchcancel', function () { drawingStop(); });
// Adds the clear button / link
if (options.showClear === true) {
// var clear_tag = (options.clearStyle == 'link' ? 'div' : 'button');
// $('#' + id + '-controls').append('<' + clear_tag + ' id=""' + id + '-clear"" style=""float:left"">' + options.clearLabel + '</' + clear_tag + '><br style=""clear:both"" />');
$('#' + id + '-controls').append('<div ' + ' id=""' + id + '-clear"" >' +
'<span class=""btn btn-sm btn-danger icon-Delete ay-icon-large""></span></div>');
clear = true;
}
// Clearing the canvas
$('#' + id + '-clear').click(function (e) {
context.save();
context.beginPath();
context.closePath();
context.restore();
context.clearRect(0, 0, $(canvas).width(), $(canvas).height());
$('#' + data_input).val('');
});
function getTouch(e) {
//console.log(e);//3566
// iPhone/iPad/iPod uses event.touches and not the passed event
if (typeof (event) != ""undefined"" && typeof (event.touches) != ""undefined"") {
e = event.touches.item(0);
scrollLeft = document.body.scrollLeft;
scrollTop = document.body.scrollTop;
}
else {
scrollLeft = $(document).scrollLeft();
scrollTop = $(document).scrollTop();
}
//console.log(""scrollLeft:"" + scrollLeft.toString());
//console.log(""scrollTop:"" + scrollTop.toString());
// Tracks last position to handle dots (as opposed to lines)
if (x != false) {
prevX = x;
prevY = y;
}
// Calculates the X and Y values
x = e.clientX - (offsetX - scrollLeft);
y = e.clientY - (offsetY - scrollTop);
return e;
}
function draw(type) {
if (type != 'stop') {
if (type == 'start') {
inside = false;
prevX = false;
prevY = false;
context.beginPath();
context.moveTo(x, y);
if (svg_path == '') {
//timestamp and dimentions
var currentDate = new Date();
var captured = currentDate.getFullYear() + ':' + (currentDate.getMonth() + 1) + ':' + currentDate.getDate() + ':' + currentDate.getHours() + ':' + currentDate.getMinutes() + ':' + currentDate.getSeconds();
svg_path = '{version=1 width=' + width + ' height=' + height + ' captured=' + captured + '}';
}
if (svg_path != '') {
svg_path += 'X';
}
//svg_path = '{polyline points=""';
}
else {
// If there's no previous increment since it's a .
if (prevX == false) {
x = x + 1;
y = y + 1;
}
context.lineTo(x, y);
}
context.stroke();
if (svg_path.length > 0 && svg_path.substring(svg_path.length - 1) != '""') {
svg_path = svg_path + ' ';
}
svg_path = svg_path + x + ',' + y;
if ((x > 0 && x <= width) && (y > 0 && y <= height)) {
inside = true;
//console.log(""INSIDE"");
} else {
//console.log(""OUTSIDE X="" + x.toString() + "", Y="" + y.toString() + "", WIDTH="" + width.toString() + "", HEIGHT="" + height.toString());
}
}
else {
draw('move');
if (inside == true) {
// Closes the polyline (with style info) and adds the closing svg tag
//svg_path = svg_path + '"" style=""fill:' + options.fillStyle + ';stroke:' + context.strokeStyle + ';stroke-width:' + context.lineWidth + '"" /}{/svg}';
var element = $('#' + data_input);
var svg_data = element.val();
// Adds the opening and closing SVG tags
// if (svg_data == '')
// {
// svg_data = '{?xml version=""1.0"" standalone=""no""?}{!DOCTYPE svg PUBLIC ""-//W3C//DTD SVG 1.1//EN"" ""http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd""}{svg width=""' + width + '"" height=""' + height + '"" version=""1.1"" xmlns=""http://www.w3.org/2000/svg""}{/svg}';
// }
// Appends the recorded path
//element.val(svg_data.substring(0, svg_data.length - 6) + svg_path);
element.val(svg_path);
//rescan hidden field form changed
//case 1975
$('form').trigger('checkform.areYouSure');
}
}
}
function drawingStart(e) {
// console.log(""drawing start"");//3566
setCanvasOffset();
// Prevent the default action (scrolling) from occurring
if (inside == true) {
e.preventDefault();
}
drawing = true;
e = getTouch(e);
context.strokeStyle = $('#' + id + '-colors div.selected').css('backgroundColor');
draw('start');
}
function drawingMove(e) {
//console.log(""drawing move"");
// Prevent the default action (scrolling) from occurring
if (inside == true) {
e.preventDefault();
}
if (drawing == true) {
e = getTouch(e);
draw('move');
}
return false;
}
function drawingStop() {
//console.log(""drawing STOP"");
drawing = false;
// Draws one last line so we can draw dots (e.g. i)
draw('stop');
}
//===========================
function setCanvasOffset() {
canvasOffset = Offset(document.getElementById(id));
offsetX = canvasOffset.left;
offsetY = canvasOffset.top;
}
function Offset(element) {
if (element === undefined) return null;
var obj = element.getBoundingClientRect();
return {
left: obj.left + window.pageXOffset,
top: obj.top + window.pageYOffset
};
}
//===============
}
// else {
// alert('Your browser does not support the CANVAS element required for signing. The following browsers will work: IE 9.0+, FIREFOX 3.0+, SAFARI 3.0+, CHROME 3.0+, OPERA 10.0+, IPAD 1.0+, IPHONE 1.0+, ANDROID 1.0+');
// }
}
else {
alert('Not a CANVAS element');
}
});
}
});
})(jQuery);
</script>";
}
*/
#endregion
/// <summary>
/// Get API server info for general display
/// </summary>
/// <returns>API server info</returns>
[HttpGet("ServerInfo")]
public ActionResult ServerInfo()
{
return Ok(new
{
data = new
{
ServerVersion = AyaNovaVersion.FullNameAndVersion,
DBSchemaVersion = AySchema.currentSchema,
ServerLocalTime = DateUtil.ServerDateTimeString(System.DateTime.UtcNow),
ServerTimeZone = TimeZoneInfo.Local.Id,
License = AyaNova.Core.License.LicenseInfoAsJson
}
});
}
#if (DEBUG)
/// <summary>
/// Get build mode of server, used for automated testing purposes
/// </summary>
/// <returns>"DEBUG" or "RELEASE"</returns>
[HttpGet("BuildMode")]
public ActionResult BuildMode()
{
return Ok(new { data = new { BuildMode = "DEBUG" } });
}
#else
/// <summary>
/// Get build mode of server, used for automated testing purposes
/// </summary>
/// <returns>"DEBUG" or "RELEASE"</returns>
[HttpGet("BuildMode")]
public ActionResult BuildMode()
{
return Ok(new { data = new { BuildMode = "RELEASE" } });
}
#endif
}
}