diff --git a/src/Server/OneTrueError.Api.Client.Tests/OneTrueError.Api.Client.Tests.csproj b/src/Server/OneTrueError.Api.Client.Tests/OneTrueError.Api.Client.Tests.csproj new file mode 100644 index 00000000..2a4a9293 --- /dev/null +++ b/src/Server/OneTrueError.Api.Client.Tests/OneTrueError.Api.Client.Tests.csproj @@ -0,0 +1,97 @@ + + + + + Debug + AnyCPU + {62989500-31BC-44FA-97CA-84F484C6F1AA} + Library + Properties + OneTrueError.Api.Client.Tests + OneTrueError.Api.Client.Tests + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\DotNetCqs.1.0.0\lib\net45\DotNetCqs.dll + True + + + ..\packages\FluentAssertions.4.14.0\lib\net45\FluentAssertions.dll + True + + + ..\packages\FluentAssertions.4.14.0\lib\net45\FluentAssertions.Core.dll + True + + + + + + + + + + + ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll + True + + + ..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll + True + + + ..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll + True + + + ..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll + True + + + + + + + + + Designer + + + + + {017F8863-3DE0-4AD2-9ED3-5ACB87BBBCD0} + OneTrueError.Api.Client + + + {fc331a95-fca4-4764-8004-0884665dd01f} + OneTrueError.Api + + + + + \ No newline at end of file diff --git a/src/Server/OneTrueError.Api.Client.Tests/Properties/AssemblyInfo.cs b/src/Server/OneTrueError.Api.Client.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..513181eb --- /dev/null +++ b/src/Server/OneTrueError.Api.Client.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OneTrueError.Api.Client.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OneTrueError.Api.Client.Tests")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("62989500-31bc-44fa-97ca-84f484c6f1aa")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Server/OneTrueError.Api.Client.Tests/TryTheClient.cs b/src/Server/OneTrueError.Api.Client.Tests/TryTheClient.cs new file mode 100644 index 00000000..2c115b88 --- /dev/null +++ b/src/Server/OneTrueError.Api.Client.Tests/TryTheClient.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +using FluentAssertions; +using OneTrueError.Api.Core.Accounts.Queries; +using Xunit; + +namespace OneTrueError.Api.Client.Tests +{ +#if DEBUG + public class TryTheClient + { + [Fact] + public async Task Test() + { + OneTrueClient client = new OneTrueClient(); + client.Credentials = new NetworkCredential("jonas", "123456"); + client.Open(new Uri("http://localhost/onetrueerror/")); + FindAccountByUserNameResult result = null; + try + { + result = await client.QueryAsync(new FindAccountByUserName("admin")); + } + catch (WebException ex) + { + + } + + + result.Should().NotBeNull(); + } + } +#endif +} diff --git a/src/Server/OneTrueError.Api.Client.Tests/packages.config b/src/Server/OneTrueError.Api.Client.Tests/packages.config new file mode 100644 index 00000000..260548a5 --- /dev/null +++ b/src/Server/OneTrueError.Api.Client.Tests/packages.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/Server/OneTrueError.Api.Client/Json/IncludeNonPublicMembersContractResolver.cs b/src/Server/OneTrueError.Api.Client/Json/IncludeNonPublicMembersContractResolver.cs new file mode 100644 index 00000000..462e0c1d --- /dev/null +++ b/src/Server/OneTrueError.Api.Client/Json/IncludeNonPublicMembersContractResolver.cs @@ -0,0 +1,40 @@ +using System.Reflection; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace OneTrueError.Api.Client.Json +{ + /// + /// Allows us to serialize properties with private setters. + /// + internal class IncludeNonPublicMembersContractResolver : DefaultContractResolver + { + /// + /// Creates a for the given + /// . + /// + /// The member's parent . + /// The member to create a for. + /// + /// A created for the given + /// . + /// + protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) + { + //TODO: Maybe cache + var prop = base.CreateProperty(member, memberSerialization); + + if (!prop.Writable) + { + var property = member as PropertyInfo; + if (property != null) + { + var hasPrivateSetter = property.GetSetMethod(true) != null; + prop.Writable = hasPrivateSetter; + } + } + + return prop; + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api.Client/OneTrueClient.cs b/src/Server/OneTrueError.Api.Client/OneTrueClient.cs new file mode 100644 index 00000000..24a823a9 --- /dev/null +++ b/src/Server/OneTrueError.Api.Client/OneTrueClient.cs @@ -0,0 +1,125 @@ +using System; +using System.Net; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using DotNetCqs; +using Newtonsoft.Json; +using OneTrueError.Api.Client.Json; + +namespace OneTrueError.Api.Client +{ + /// + /// Client for the OneTrueError server API + /// + public class OneTrueApiClient : IQueryBus, ICommandBus, IEventBus + { + private string _apiKey; + + private readonly JsonSerializerSettings _jsonSerializerSettings = new JsonSerializerSettings + { + ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor, + Formatting = Formatting.Indented + }; + + private string _sharedSecret; + private Uri _uri; + + + /// + /// Creates a new instance of . + /// + public OneTrueApiClient() { + + _jsonSerializerSettings.ContractResolver = new IncludeNonPublicMembersContractResolver(); + } + + /// + /// Execute a command + /// + /// type of query (from the OneTrueError.Api class library) + /// command to execute + /// task + public async Task ExecuteAsync(T command) where T : Command + { + var response = await RequestAsync("POST", "command", command); + response.Close(); + } + + /// + /// Publish an event + /// + /// type of event (from the OneTrueError.Api class library) + /// event to publish + /// task + public async Task PublishAsync(TApplicationEvent e) + where TApplicationEvent : ApplicationEvent + { + var response = await RequestAsync("POST", "event", e); + response.Close(); + } + + /// + /// Make a query + /// + /// Result from a query (a class from the OneTrueError.Api library) + /// + /// + public async Task QueryAsync(Query query) + { + //TODO: Unwrap the cqs object to query parameters instead + //to allow caching in the server + var response = await RequestAsync("POST", "query", query); + return await DeserializeResponse(response); + } + + /// + /// Open a channel + /// + /// Root URL to the OneTrueError web + /// Api key from the admin area in OneTrueError web + /// Shared secret from the admin area in OneTrueError web + public void Open(Uri uri, string apiKey, string sharedSecret) + { + if (apiKey == null) throw new ArgumentNullException(nameof(apiKey)); + if (sharedSecret == null) throw new ArgumentNullException(nameof(sharedSecret)); + if (uri == null) throw new ArgumentNullException(nameof(uri)); + + _apiKey = apiKey; + _sharedSecret = sharedSecret; + _uri = uri; + } + + private async Task DeserializeResponse(HttpWebResponse response) + { + var responseStream = response.GetResponseStream(); + var jsonBuf = new byte[response.ContentLength]; + await responseStream.ReadAsync(jsonBuf, 0, jsonBuf.Length); + var jsonStr = Encoding.UTF8.GetString(jsonBuf); + var responseObj = JsonConvert.DeserializeObject(jsonStr, typeof(TResult), _jsonSerializerSettings); + return (TResult) responseObj; + } + + private async Task RequestAsync(string httpMethod, string cqsType, object cqsObject) + { + var request = WebRequest.CreateHttp(_uri + "api/cqs"); + request.Method = httpMethod; + request.Headers.Add("X-Api-Key", _apiKey); + request.Headers.Add("X-Cqs-Name", cqsObject.GetType().Name); + + var stream = await request.GetRequestStreamAsync(); + var json = JsonConvert.SerializeObject(cqsObject, _jsonSerializerSettings); + var buffer = Encoding.UTF8.GetBytes(json); + +var hamc = new HMACSHA256(Encoding.UTF8.GetBytes(_sharedSecret.ToLower())); +var hash = hamc.ComputeHash(buffer); +var signature = Convert.ToBase64String(hash); + + await stream.WriteAsync(buffer, 0, buffer.Length); + + request.Headers.Add("X-Api-Signature", signature); + + return (HttpWebResponse) await request.GetResponseAsync(); + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api.Client/OneTrueError.Api.Client.csproj b/src/Server/OneTrueError.Api.Client/OneTrueError.Api.Client.csproj new file mode 100644 index 00000000..9c6eb078 --- /dev/null +++ b/src/Server/OneTrueError.Api.Client/OneTrueError.Api.Client.csproj @@ -0,0 +1,63 @@ + + + + + Debug + AnyCPU + {017F8863-3DE0-4AD2-9ED3-5ACB87BBBCD0} + Library + Properties + OneTrueError.Api.Client + OneTrueError.Api.Client + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + bin\Release\OneTrueError.Api.Client.XML + + + + ..\packages\DotNetCqs.1.0.0\lib\net45\DotNetCqs.dll + True + + + ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + True + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Server/OneTrueError.Api.Client/Properties/AssemblyInfo.cs b/src/Server/OneTrueError.Api.Client/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..0c3eceba --- /dev/null +++ b/src/Server/OneTrueError.Api.Client/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OneTrueError.Api.Client")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OneTrueError.Api.Client")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("017f8863-3de0-4ad2-9ed3-5acb87bbbcd0")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Server/OneTrueError.Api.Client/StringBuilderExtensions.cs b/src/Server/OneTrueError.Api.Client/StringBuilderExtensions.cs new file mode 100644 index 00000000..dd375dc0 --- /dev/null +++ b/src/Server/OneTrueError.Api.Client/StringBuilderExtensions.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OneTrueError.Api.Client.Tests +{ + static class StringBuilderExtensions + { + public static void AppendUrlEncoded(this StringBuilder sb, string name, string value) + { + if (sb.Length != 0) + sb.Append("&"); + sb.Append(Uri.EscapeDataString(name)); + sb.Append("="); + sb.Append(Uri.EscapeDataString(value)); + } + + } +} diff --git a/src/Server/OneTrueError.Api.Client/packages.config b/src/Server/OneTrueError.Api.Client/packages.config new file mode 100644 index 00000000..77ba143d --- /dev/null +++ b/src/Server/OneTrueError.Api.Client/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/AuthorizeAttribute.cs b/src/Server/OneTrueError.Api/AuthorizeAttribute.cs new file mode 100644 index 00000000..7def7a74 --- /dev/null +++ b/src/Server/OneTrueError.Api/AuthorizeAttribute.cs @@ -0,0 +1,26 @@ +using System; + +namespace OneTrueError.Api +{ + /// + /// Authorize on specific roles. + /// + [AttributeUsage(AttributeTargets.Class)] + public class AuthorizeRolesAttribute : Attribute + { + /// + /// Creates a new instance of . + /// + /// roles granted access + public AuthorizeRolesAttribute(params string[] roles) + { + if (roles == null) throw new ArgumentNullException("roles"); + Roles = roles; + } + + /// + /// Roles granted access + /// + public string[] Roles { get; private set; } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/Core/ApiKeys/Commands/CreateApiKey.cs b/src/Server/OneTrueError.Api/Core/ApiKeys/Commands/CreateApiKey.cs new file mode 100644 index 00000000..fc1962e8 --- /dev/null +++ b/src/Server/OneTrueError.Api/Core/ApiKeys/Commands/CreateApiKey.cs @@ -0,0 +1,58 @@ +using System; +using DotNetCqs; + +namespace OneTrueError.Api.Core.ApiKeys.Commands +{ + /// + /// Create a new api key + /// + [AuthorizeRoles("SysAdmin")] + public class CreateApiKey : Command + { + /// + /// Creates a new instance of . + /// + /// + /// + /// + /// + public CreateApiKey(string applicationName, string apiKey, string sharedSecret, int[] applicationIds) + { + if (applicationName == null) throw new ArgumentNullException("applicationName"); + if (apiKey == null) throw new ArgumentNullException("apiKey"); + if (sharedSecret == null) throw new ArgumentNullException("sharedSecret"); + if (applicationIds == null) throw new ArgumentNullException("applicationIds"); + + ApplicationName = applicationName; + ApiKey = apiKey; + SharedSecret = sharedSecret; + ApplicationIds = applicationIds; + } + + + /// + /// Must always be the one that creates the key (will be assigned by the CommandBus per convention) + /// + public int AccountId { get; set; } + + /// + /// Generated api key + /// + public string ApiKey { get; set; } + + /// + /// applications that this key may modify. Empty = allow for all applications. + /// + public int[] ApplicationIds { get; set; } + + /// + /// Application that uses this api key + /// + public string ApplicationName { get; set; } + + /// + /// Used to sign all requests. + /// + public string SharedSecret { get; set; } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/Core/ApiKeys/Commands/DeleteApiKey.cs b/src/Server/OneTrueError.Api/Core/ApiKeys/Commands/DeleteApiKey.cs new file mode 100644 index 00000000..d34f0e5a --- /dev/null +++ b/src/Server/OneTrueError.Api/Core/ApiKeys/Commands/DeleteApiKey.cs @@ -0,0 +1,52 @@ +using System; +using DotNetCqs; + +namespace OneTrueError.Api.Core.ApiKeys.Commands +{ + /// + /// Delete an API key. + /// + public class DeleteApiKey : Command + { + /// + /// Serialization constructor + /// + protected DeleteApiKey() + { + } + + /// + /// Creates a new instance of . + /// + /// PK + public DeleteApiKey(int id) + { + Id = id; + } + + /// + /// Creates a new instance of . + /// + /// The generated ApiKey + public DeleteApiKey(string apiKey) + { + if (apiKey == null) throw new ArgumentNullException("apiKey"); + Guid guid; + if (!Guid.TryParse(apiKey, out guid)) + throw new ArgumentException("Not a valid api key: " + apiKey, "apiKey"); + + ApiKey = apiKey; + } + + /// + /// generated api key (if specified) + /// + public string ApiKey { get; private set; } + + /// + /// PK (if specified) + /// + public int Id { get; private set; } + } +} + diff --git a/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/GetApiKey.cs b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/GetApiKey.cs new file mode 100644 index 00000000..5c8c0d8d --- /dev/null +++ b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/GetApiKey.cs @@ -0,0 +1,51 @@ +using System; +using DotNetCqs; + +namespace OneTrueError.Api.Core.ApiKeys.Queries +{ + /// + /// Get information about an API key + /// + public class GetApiKey : Query + { + /// + /// Serialization constructor + /// + protected GetApiKey() + { + } + + /// + /// Creates a new instance of . + /// + /// PK + public GetApiKey(int id) + { + Id = id; + } + + /// + /// Creates a new instance of . + /// + /// The generated ApiKey + public GetApiKey(string apiKey) + { + if (apiKey == null) throw new ArgumentNullException("apiKey"); + Guid guid; + if (!Guid.TryParse(apiKey, out guid)) + throw new ArgumentException("Not a valid api key: " + apiKey, "apiKey"); + + ApiKey = apiKey; + } + + /// + /// generated api key (if specified) + /// + public string ApiKey { get; private set; } + + /// + /// PK (if specified) + /// + public int Id { get; private set; } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/GetApiKeyResult.cs b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/GetApiKeyResult.cs new file mode 100644 index 00000000..9bbdd784 --- /dev/null +++ b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/GetApiKeyResult.cs @@ -0,0 +1,48 @@ +using System; + +namespace OneTrueError.Api.Core.ApiKeys.Queries +{ + /// + /// Result for . + /// + public class GetApiKeyResult + { + /// + /// Application ids that we've been granted to work with + /// + public GetApiKeyResultApplication[] AllowedApplications { get; set; } + + /// + /// Application that will be using this key + /// + public string ApplicationName { get; set; } + + + /// + /// When this key was generated + /// + public DateTime CreatedAtUtc { get; set; } + + /// + /// AccountId that generated this key + /// + public int CreatedById { get; set; } + + /// + /// Api key + /// + public string GeneratedKey { get; set; } + + + /// + /// PK + /// + public int Id { get; set; } + + + /// + /// Used when generating signatures. + /// + public string SharedSecret { get; set; } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/GetApiKeyResultApplication.cs b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/GetApiKeyResultApplication.cs new file mode 100644 index 00000000..7528845b --- /dev/null +++ b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/GetApiKeyResultApplication.cs @@ -0,0 +1,19 @@ +namespace OneTrueError.Api.Core.ApiKeys.Queries +{ + /// + /// An allowed application for . + /// + public class GetApiKeyResultApplication + { + /// + /// Application id (PK) + /// + public int ApplicationId { get; set; } + + + /// + /// Name of the application + /// + public string ApplicationName { get; set; } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/ListApiKeys.cs b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/ListApiKeys.cs new file mode 100644 index 00000000..b020e2e2 --- /dev/null +++ b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/ListApiKeys.cs @@ -0,0 +1,11 @@ +using DotNetCqs; + +namespace OneTrueError.Api.Core.ApiKeys.Queries +{ + /// + /// List all created keys + /// + public class ListApiKeys : Query + { + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/ListApiKeysResult.cs b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/ListApiKeysResult.cs new file mode 100644 index 00000000..89c7a9c1 --- /dev/null +++ b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/ListApiKeysResult.cs @@ -0,0 +1,13 @@ +namespace OneTrueError.Api.Core.ApiKeys.Queries +{ + /// + /// Result for . + /// + public class ListApiKeysResult + { + /// + /// All created keys + /// + public ListApiKeysResultItem[] Keys { get; set; } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/ListApiKeysResultItem.cs b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/ListApiKeysResultItem.cs new file mode 100644 index 00000000..95bc86ce --- /dev/null +++ b/src/Server/OneTrueError.Api/Core/ApiKeys/Queries/ListApiKeysResultItem.cs @@ -0,0 +1,23 @@ +namespace OneTrueError.Api.Core.ApiKeys.Queries +{ + /// + /// Item for . + /// + public class ListApiKeysResultItem + { + /// + /// Identity + /// + public int Id { get; set; } + + /// + /// Key to use + /// + public string ApiKey { get; set; } + + /// + /// Application name, i.e. name of the application that uses this key. + /// + public string ApplicationName { get; set; } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/Core/ApiKeys/ReadMe.md b/src/Server/OneTrueError.Api/Core/ApiKeys/ReadMe.md new file mode 100644 index 00000000..9135a120 --- /dev/null +++ b/src/Server/OneTrueError.Api/Core/ApiKeys/ReadMe.md @@ -0,0 +1,32 @@ +ApiKeys +======== + +Used to allow external applications to talk with OneTrueError. + + +## Example usage + +The following example calls a local OneTrueError server to retreive applications. + +```csharp +var client = new OneTrueApiClient(); +var uri = new Uri("http://yourServer/onetrueerror/"); +client.Open(uri, "theApiKey", "sharedSecret"); +var apps = await client.QueryAsync(new GetApplicationList()); +``` + +Result (serialized as JSON): + +```javascript +[{ + "Id" : 1, + "Name" : "PublicWeb" + }, { + "Id" : 9, + "Name" : "Time reporting system" + }, { + "Id" : 10, + "Name" : "Coffee monitor" + } +] +``` diff --git a/src/Server/OneTrueError.Api/Core/Applications/Queries/GetApplicationList.cs b/src/Server/OneTrueError.Api/Core/Applications/Queries/GetApplicationList.cs index 505d8599..101b28c7 100644 --- a/src/Server/OneTrueError.Api/Core/Applications/Queries/GetApplicationList.cs +++ b/src/Server/OneTrueError.Api/Core/Applications/Queries/GetApplicationList.cs @@ -16,5 +16,10 @@ public class GetApplicationList : Query /// /// public int AccountId { get; set; } + + /// + /// Only list applications that the given account is administrator for. + /// + public bool FilterAsAdmin { get; set; } } } \ No newline at end of file diff --git a/src/Server/OneTrueError.Api/OneTrueError.Api.csproj b/src/Server/OneTrueError.Api/OneTrueError.Api.csproj index 37052552..1d0929cc 100644 --- a/src/Server/OneTrueError.Api/OneTrueError.Api.csproj +++ b/src/Server/OneTrueError.Api/OneTrueError.Api.csproj @@ -40,8 +40,8 @@ ..\packages\Griffin.Container.1.1.2\lib\net40\Griffin.Container.dll True - - ..\packages\Griffin.Framework.1.0.37\lib\net45\Griffin.Core.dll + + ..\packages\Griffin.Framework.1.0.39\lib\net45\Griffin.Core.dll True @@ -55,6 +55,7 @@ + @@ -84,6 +85,14 @@ + + + + + + + + @@ -204,6 +213,7 @@ + diff --git a/src/Server/OneTrueError.Api/packages.config b/src/Server/OneTrueError.Api/packages.config index 1fba5e44..0b6b5939 100644 --- a/src/Server/OneTrueError.Api/packages.config +++ b/src/Server/OneTrueError.Api/packages.config @@ -2,5 +2,5 @@ - + \ No newline at end of file diff --git a/src/Server/OneTrueError.App.Tests/OneTrueError.App.Tests.csproj b/src/Server/OneTrueError.App.Tests/OneTrueError.App.Tests.csproj index 2e9092b6..fc957e33 100644 --- a/src/Server/OneTrueError.App.Tests/OneTrueError.App.Tests.csproj +++ b/src/Server/OneTrueError.App.Tests/OneTrueError.App.Tests.csproj @@ -40,20 +40,20 @@ ..\packages\DotNetCqs.1.0.0\lib\net45\DotNetCqs.dll True - - ..\packages\FluentAssertions.4.12.0\lib\net45\FluentAssertions.dll + + ..\packages\FluentAssertions.4.14.0\lib\net45\FluentAssertions.dll True - - ..\packages\FluentAssertions.4.12.0\lib\net45\FluentAssertions.Core.dll + + ..\packages\FluentAssertions.4.14.0\lib\net45\FluentAssertions.Core.dll True ..\packages\Griffin.Container.1.1.2\lib\net40\Griffin.Container.dll True - - ..\packages\Griffin.Framework.1.0.37\lib\net45\Griffin.Core.dll + + ..\packages\Griffin.Framework.1.0.39\lib\net45\Griffin.Core.dll True diff --git a/src/Server/OneTrueError.App.Tests/packages.config b/src/Server/OneTrueError.App.Tests/packages.config index deda04e1..88019ec9 100644 --- a/src/Server/OneTrueError.App.Tests/packages.config +++ b/src/Server/OneTrueError.App.Tests/packages.config @@ -3,7 +3,7 @@ - + diff --git a/src/Server/OneTrueError.App/Core/Accounts/Requests/ActivateAccountHandler.cs b/src/Server/OneTrueError.App/Core/Accounts/Requests/ActivateAccountHandler.cs index 8ece403b..dc930a9d 100644 --- a/src/Server/OneTrueError.App/Core/Accounts/Requests/ActivateAccountHandler.cs +++ b/src/Server/OneTrueError.App/Core/Accounts/Requests/ActivateAccountHandler.cs @@ -1,10 +1,12 @@ using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using DotNetCqs; using Griffin.Container; using OneTrueError.Api.Core.Accounts.Events; using OneTrueError.Api.Core.Accounts.Requests; +using OneTrueError.Api.Core.Applications.Queries; namespace OneTrueError.App.Core.Accounts.Requests { @@ -16,16 +18,17 @@ public class ActivateAccountHandler : IRequestHandler /// Creates a new instance of . /// /// repos /// used to publish . - public ActivateAccountHandler(IAccountRepository repository, IEventBus eventBus) + public ActivateAccountHandler(IAccountRepository repository, IEventBus eventBus, IQueryBus queryBus) { _repository = repository; _eventBus = eventBus; + _queryBus = queryBus; } /// @@ -45,7 +48,11 @@ public async Task ExecuteAsync(ActivateAccount request) account.Activate(); await _repository.UpdateAsync(account); - Thread.CurrentPrincipal = new OneTruePrincipal(account.UserName); + var query = new GetApplicationList(); + var apps = await _queryBus.QueryAsync(query); + var roles = apps.Select(x => "Member_" + x.Id).ToArray(); + + Thread.CurrentPrincipal = new OneTruePrincipal(account.Id, account.UserName, roles); var evt = new AccountActivated(account.Id, account.UserName) { EmailAddress = account.Email diff --git a/src/Server/OneTrueError.App/Core/ApiKeys/ApiKey.cs b/src/Server/OneTrueError.App/Core/ApiKeys/ApiKey.cs new file mode 100644 index 00000000..c6a5b1dd --- /dev/null +++ b/src/Server/OneTrueError.App/Core/ApiKeys/ApiKey.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; + +namespace OneTrueError.App.Core.ApiKeys +{ + /// + /// A generated API key which can be used to call OneTrueError´s HTTP api. + /// + public class ApiKey + { + private List _applications = new List(); + + /// + /// Application ids that we've been granted to work with + /// + public IEnumerable AllowedApplications + { + get { return _applications; } + private set { _applications = new List(value); } + } + + /// + /// Application that will be using this key + /// + public string ApplicationName { get; set; } + + + /// + /// When this key was generated + /// + public DateTime CreatedAtUtc { get; set; } + + /// + /// AccountId that generated this key + /// + public int CreatedById { get; set; } + + /// + /// Api key + /// + public string GeneratedKey { get; set; } + + + /// + /// PK + /// + public int Id { get; set; } + + + /// + /// Used when generating signatures. + /// + public string SharedSecret { get; set; } + + /// + /// Add an application that this ApiKey can be used for. + /// + /// application id + public void Add(int applicationId) + { + if (applicationId <= 0) throw new ArgumentOutOfRangeException(nameof(applicationId)); + + _applications.Add(applicationId); + } + + /// + /// Validate a given signature using the HTTP body. + /// + /// Signature passed from the client + /// HTTP body (i.e. the data that the signature was generated on) + /// true if the signature was generated using the shared secret; otherwise false. + public bool ValidateSignature(string specifiedSignature, byte[] body) + { + var hashAlgo = new HMACSHA256(Encoding.UTF8.GetBytes(SharedSecret.ToLower())); + var hash = hashAlgo.ComputeHash(body); + var signature = Convert.ToBase64String(hash); + + var hashAlgo1 = new HMACSHA256(Encoding.UTF8.GetBytes(SharedSecret.ToUpper())); + var hash1 = hashAlgo1.ComputeHash(body); + var signature1 = Convert.ToBase64String(hash1); + + return specifiedSignature.Equals(signature) || specifiedSignature.Equals(signature1); + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.App/Core/ApiKeys/IApiKeyRepository.cs b/src/Server/OneTrueError.App/Core/ApiKeys/IApiKeyRepository.cs new file mode 100644 index 00000000..eff945cd --- /dev/null +++ b/src/Server/OneTrueError.App/Core/ApiKeys/IApiKeyRepository.cs @@ -0,0 +1,19 @@ +using System.Threading.Tasks; +using Griffin.Data; + +namespace OneTrueError.App.Core.ApiKeys +{ + /// + /// Repository for . + /// + public interface IApiKeyRepository + { + /// + /// Get an key by using the generated string. + /// + /// key + /// key + /// Given key was not found. + Task GetByKeyAsync(string apiKey); + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.App/Core/ApiKeys/ReadMe.md b/src/Server/OneTrueError.App/Core/ApiKeys/ReadMe.md new file mode 100644 index 00000000..72b68d79 --- /dev/null +++ b/src/Server/OneTrueError.App/Core/ApiKeys/ReadMe.md @@ -0,0 +1,5 @@ +Api Keys +========= + +Api keys are used to allow other applications to communicate with OneTrueError through the HTTP api. + diff --git a/src/Server/OneTrueError.App/Core/Invitations/CommandHandlers/AcceptInvitationHandler.cs b/src/Server/OneTrueError.App/Core/Invitations/CommandHandlers/AcceptInvitationHandler.cs index aed1926a..5ca8eb51 100644 --- a/src/Server/OneTrueError.App/Core/Invitations/CommandHandlers/AcceptInvitationHandler.cs +++ b/src/Server/OneTrueError.App/Core/Invitations/CommandHandlers/AcceptInvitationHandler.cs @@ -39,10 +39,11 @@ public async Task ExecuteAsync(AcceptInvitation request) account.Activate(); account.Login(request.Password); + var roles= invitation.Invitations.Select(x => "Member_" + x.ApplicationId).ToArray(); await _accountRepository.CreateAsync(account); - Thread.CurrentPrincipal = new OneTruePrincipal(account.UserName); + Thread.CurrentPrincipal = new OneTruePrincipal(account.Id, account.UserName, roles); await _eventBus.PublishAsync(new AccountActivated(account.Id, account.UserName) { EmailAddress = account.Email diff --git a/src/Server/OneTrueError.App/OneTrueError.App.csproj b/src/Server/OneTrueError.App/OneTrueError.App.csproj index ef952926..46de13e8 100644 --- a/src/Server/OneTrueError.App/OneTrueError.App.csproj +++ b/src/Server/OneTrueError.App/OneTrueError.App.csproj @@ -44,8 +44,8 @@ ..\packages\Griffin.Container.1.1.2\lib\net40\Griffin.Container.dll True - - ..\packages\Griffin.Framework.1.0.37\lib\net45\Griffin.Core.dll + + ..\packages\Griffin.Framework.1.0.39\lib\net45\Griffin.Core.dll True @@ -80,6 +80,8 @@ + + @@ -145,6 +147,7 @@ + @@ -247,6 +250,7 @@ + diff --git a/src/Server/OneTrueError.App/OneTrueIdentity.cs b/src/Server/OneTrueError.App/OneTrueIdentity.cs new file mode 100644 index 00000000..759fcde8 --- /dev/null +++ b/src/Server/OneTrueError.App/OneTrueIdentity.cs @@ -0,0 +1,48 @@ +using System; +using System.Security.Principal; + +namespace OneTrueError.App +{ + /// + /// Identity for . + /// + public class OneTrueIdentity : IIdentity + { + /// + /// Creates a new instance of . + /// + /// 0 = system or api key; otherwise an user account id + /// User name + public OneTrueIdentity(int accountId, string userName) + { + if (userName == null) throw new ArgumentNullException("userName"); + if (accountId < 0) throw new ArgumentOutOfRangeException("accountId"); + + AccountId = accountId; + Name = userName; + } + + /// + /// 0 = system or api key; otherwise an user account id + /// + public int AccountId { get; private set; } + + /// + /// Account name (username) + /// + public string Name { get; private set; } + + /// + /// "apiKey", "cookie", "openauth" + /// + public string AuthenticationType { get; set; } + + /// + /// Always true when OneTrueIdentity is used. + /// + public bool IsAuthenticated + { + get { return true; } + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.App/OneTruePrincipal.cs b/src/Server/OneTrueError.App/OneTruePrincipal.cs index 40450b9b..2998e7aa 100644 --- a/src/Server/OneTrueError.App/OneTruePrincipal.cs +++ b/src/Server/OneTrueError.App/OneTruePrincipal.cs @@ -1,48 +1,63 @@ using System; +using System.Linq; using System.Security.Principal; using System.Threading; namespace OneTrueError.App { /// - /// Our security principal + /// Our security principal /// public class OneTruePrincipal : IPrincipal { + private readonly string[] _roles; + /// - /// Creates a new instance of . + /// Creates a new instance of . /// + /// 0 = system or api key; otherwise an user account id /// Logged in user or "system" + /// /// userName - public OneTruePrincipal(string userName) + public OneTruePrincipal(int accountId, string userName, string[] roles) { if (userName == null) throw new ArgumentNullException("userName"); - Identity = new GenericIdentity(userName); + if (roles == null) throw new ArgumentNullException("roles"); + if (accountId < 0) throw new ArgumentOutOfRangeException("accountId"); + + Identity = new OneTrueIdentity(accountId, userName); + _roles = roles; } /// - /// Current thread principal + /// Current thread principal /// public static OneTruePrincipal Current { - get { return ((OneTruePrincipal) Thread.CurrentPrincipal); } + get { return (OneTruePrincipal) Thread.CurrentPrincipal; } } - /// - /// Not supported (what a lovely LSP violation) + /// Currently logged in user + /// + public OneTrueIdentity Identity { get; private set; } + + + /// + /// Not supported (what a lovely LSP violation) /// - /// none + /// "sysadmin", "admin-x" where X = application id /// /// not supported public bool IsInRole(string role) { - throw new NotSupportedException(); + if (role == null) throw new ArgumentNullException("role"); + return _roles.Any(x => x.Equals(role, StringComparison.OrdinalIgnoreCase)); } - /// - /// Currently logged in user - /// - public IIdentity Identity { get; private set; } + IIdentity IPrincipal.Identity + { + get { return Identity; } + } } } \ No newline at end of file diff --git a/src/Server/OneTrueError.App/packages.config b/src/Server/OneTrueError.App/packages.config index b997523d..156e098a 100644 --- a/src/Server/OneTrueError.App/packages.config +++ b/src/Server/OneTrueError.App/packages.config @@ -3,7 +3,7 @@ - + diff --git a/src/Server/OneTrueError.Data.Common/OneTrueError.Infrastructure.csproj b/src/Server/OneTrueError.Data.Common/OneTrueError.Infrastructure.csproj index b330d665..3ea32e42 100644 --- a/src/Server/OneTrueError.Data.Common/OneTrueError.Infrastructure.csproj +++ b/src/Server/OneTrueError.Data.Common/OneTrueError.Infrastructure.csproj @@ -34,8 +34,8 @@ ..\packages\Griffin.Container.1.1.2\lib\net40\Griffin.Container.dll True - - ..\packages\Griffin.Framework.1.0.37\lib\net45\Griffin.Core.dll + + ..\packages\Griffin.Framework.1.0.39\lib\net45\Griffin.Core.dll True diff --git a/src/Server/OneTrueError.Data.Common/packages.config b/src/Server/OneTrueError.Data.Common/packages.config index 35c33822..3b4f5e00 100644 --- a/src/Server/OneTrueError.Data.Common/packages.config +++ b/src/Server/OneTrueError.Data.Common/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/Server/OneTrueError.ReportAnalyzer/OneTrueError.ReportAnalyzer.csproj b/src/Server/OneTrueError.ReportAnalyzer/OneTrueError.ReportAnalyzer.csproj index 84c7c2e7..690ff66e 100644 --- a/src/Server/OneTrueError.ReportAnalyzer/OneTrueError.ReportAnalyzer.csproj +++ b/src/Server/OneTrueError.ReportAnalyzer/OneTrueError.ReportAnalyzer.csproj @@ -39,8 +39,8 @@ ..\packages\Griffin.Container.1.1.2\lib\net40\Griffin.Container.dll True - - ..\packages\Griffin.Framework.1.0.37\lib\net45\Griffin.Core.dll + + ..\packages\Griffin.Framework.1.0.39\lib\net45\Griffin.Core.dll True diff --git a/src/Server/OneTrueError.ReportAnalyzer/packages.config b/src/Server/OneTrueError.ReportAnalyzer/packages.config index 2ef00d2a..230fc0e5 100644 --- a/src/Server/OneTrueError.ReportAnalyzer/packages.config +++ b/src/Server/OneTrueError.ReportAnalyzer/packages.config @@ -2,7 +2,7 @@ - + diff --git a/src/Server/OneTrueError.SqlServer.Tests/ConnectionFactory.cs b/src/Server/OneTrueError.SqlServer.Tests/ConnectionFactory.cs index 9b15fce4..fc7c7d55 100644 --- a/src/Server/OneTrueError.SqlServer.Tests/ConnectionFactory.cs +++ b/src/Server/OneTrueError.SqlServer.Tests/ConnectionFactory.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using System.Configuration; +using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -11,7 +13,10 @@ class ConnectionFactory { public static IAdoNetUnitOfWork Create() { - throw new NotImplementedException(); + var connection = new SqlConnection(); + connection.ConnectionString = ConfigurationManager.ConnectionStrings["Db"].ConnectionString; + connection.Open(); + return new AdoNetUnitOfWork(connection, true); } } } diff --git a/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Commands/CreateApiKeyHandlerTests.cs b/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Commands/CreateApiKeyHandlerTests.cs new file mode 100644 index 00000000..1a3859d3 --- /dev/null +++ b/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Commands/CreateApiKeyHandlerTests.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FluentAssertions; +using Griffin.Data; +using OneTrueError.Api.Core.ApiKeys.Commands; +using OneTrueError.App.Core.Applications; +using OneTrueError.SqlServer.Core.ApiKeys; +using OneTrueError.SqlServer.Core.ApiKeys.Commands; +using OneTrueError.SqlServer.Core.Applications; +using Xunit; + +namespace OneTrueError.SqlServer.Tests.Core.ApiKeys.Commands +{ + public class CreateApiKeyHandlerTests : IDisposable + { + private IAdoNetUnitOfWork _uow; + private int _applicationId; + + public CreateApiKeyHandlerTests() + { + _uow = ConnectionFactory.Create(); + GetApplicationId(); + } + + private void GetApplicationId() + { + var repos = new ApplicationRepository(_uow); + var id = _uow.ExecuteScalar("SELECT TOP 1 Id FROM Applications"); + if (id is DBNull) + { + repos.CreateAsync(new Application(10, "AppTen")).Wait(); + _applicationId = (int) _uow.ExecuteScalar("SELECT TOP 1 Id FROM Applications"); + } + else + _applicationId = (int) id; + } + + [Fact] + public async Task should_be_able_to_Create_key() + { + var cmd = new CreateApiKey("Mofo", Guid.NewGuid().ToString("N"), Guid.NewGuid().ToString("N"), new[] { _applicationId}); + + var sut = new CreateApiKeyHandler(_uow); + await sut.ExecuteAsync(cmd); + + var repos = new ApiKeyRepository(_uow); + var generated = await repos.GetByKeyAsync(cmd.ApiKey); + generated.Should().NotBeNull(); + generated.AllowedApplications.Should().BeEquivalentTo(new[] {_applicationId}); + } + + public void Dispose() + { + _uow.Dispose(); + } + } +} diff --git a/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Commands/DeleteApiKeyHandlerTests.cs b/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Commands/DeleteApiKeyHandlerTests.cs new file mode 100644 index 00000000..ecd2473d --- /dev/null +++ b/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Commands/DeleteApiKeyHandlerTests.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FluentAssertions; +using Griffin.Data; +using OneTrueError.Api.Core.ApiKeys.Commands; +using OneTrueError.App.Core.ApiKeys; +using OneTrueError.App.Core.Applications; +using OneTrueError.SqlServer.Core.ApiKeys; +using OneTrueError.SqlServer.Core.ApiKeys.Commands; +using OneTrueError.SqlServer.Core.Applications; +using Xunit; + +namespace OneTrueError.SqlServer.Tests.Core.ApiKeys.Commands +{ + public class DeleteApiKeyHandlerTests : IDisposable + { + private IAdoNetUnitOfWork _uow; + private int _applicationId; + private ApiKey _existingEntity; + + public DeleteApiKeyHandlerTests() + { + _uow = ConnectionFactory.Create(); + GetApplicationId(); + + _existingEntity = new ApiKey + { + ApplicationName = "Arne", + GeneratedKey = Guid.NewGuid().ToString("N"), + SharedSecret = Guid.NewGuid().ToString("N"), + CreatedById = 20, + CreatedAtUtc = DateTime.UtcNow, + }; + + _existingEntity.Add(_applicationId); + var repos = new ApiKeyRepository(_uow); + repos.CreateAsync(_existingEntity).Wait(); + } + + private void GetApplicationId() + { + var repos = new ApplicationRepository(_uow); + var id = _uow.ExecuteScalar("SELECT TOP 1 Id FROM Applications"); + if (id is DBNull) + { + repos.CreateAsync(new Application(10, "AppTen")).Wait(); + _applicationId = (int)_uow.ExecuteScalar("SELECT TOP 1 Id FROM Applications"); + } + else + _applicationId = (int)id; + + + } + + [Fact] + public async Task should_be_able_to_delete_key_by_id() + { + var cmd = new DeleteApiKey(_existingEntity.Id); + + var sut = new DeleteApiKeyHandler(_uow); + await sut.ExecuteAsync(cmd); + + var count = _uow.ExecuteScalar("SELECT cast(count(*) as int) FROM ApiKeys WHERE Id = @id", new { id = _existingEntity.Id }); + count.Should().Be(0); + } + + [Fact] + public async Task should_be_able_to_delete_key_by_ApiKey() + { + var cmd = new DeleteApiKey(_existingEntity.GeneratedKey); + + var sut = new DeleteApiKeyHandler(_uow); + await sut.ExecuteAsync(cmd); + + var count = _uow.ExecuteScalar("SELECT cast(count(*) as int) FROM ApiKeys WHERE Id = @id", new { id = _existingEntity.Id }); + count.Should().Be(0); + } + + public void Dispose() + { + _uow.Dispose(); + } + } +} diff --git a/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Queries/GetApiKeyHandlerTests.cs b/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Queries/GetApiKeyHandlerTests.cs new file mode 100644 index 00000000..d4959a0e --- /dev/null +++ b/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Queries/GetApiKeyHandlerTests.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FluentAssertions; +using Griffin.Data; +using Griffin.Data.Mapper; +using OneTrueError.Api.Core.ApiKeys.Queries; +using OneTrueError.App.Core.ApiKeys; +using OneTrueError.App.Core.Applications; +using OneTrueError.SqlServer.Core.ApiKeys; +using OneTrueError.SqlServer.Core.ApiKeys.Queries; +using OneTrueError.SqlServer.Core.Applications; +using Xunit; + +namespace OneTrueError.SqlServer.Tests.Core.ApiKeys.Queries +{ + public class GetApiKeyHandlerTests + { + private IAdoNetUnitOfWork _uow; + private ApiKey _existingEntity; + private Application _application; + + public GetApiKeyHandlerTests() + { + _uow = ConnectionFactory.Create(); + GetApplication(); + + _existingEntity = new ApiKey + { + ApplicationName = "Arne", + GeneratedKey = Guid.NewGuid().ToString("N"), + SharedSecret = Guid.NewGuid().ToString("N"), + CreatedById = 20, + CreatedAtUtc = DateTime.UtcNow, + }; + + _existingEntity.Add(_application.Id); + var repos = new ApiKeyRepository(_uow); + repos.CreateAsync(_existingEntity).Wait(); + } + + private void GetApplication() + { + var repos = new ApplicationRepository(_uow); + var id = _uow.ExecuteScalar("SELECT TOP 1 Id FROM Applications"); + if (id is DBNull) + { + _application = new Application(10, "AppTen"); + repos.CreateAsync(_application).Wait(); + } + else + { + _application = repos.GetByIdAsync((int) id).Result; + } + } + + + [Fact] + public async void should_Be_able_to_fetch_existing_key_by_id() + { + var query = new GetApiKey(_existingEntity.Id); + + var sut = new GetApiKeyHandler(_uow); + var result = await sut.ExecuteAsync(query); + + result.Should().NotBeNull(); + result.GeneratedKey.Should().Be(_existingEntity.GeneratedKey); + result.ApplicationName.Should().Be(_existingEntity.ApplicationName); + result.AllowedApplications[0].ApplicationId.Should().Be(_application.Id); + result.AllowedApplications[0].ApplicationName.Should().Be(_application.Name); + } + + public void Dispose() + { + _uow.Dispose(); + } + } +} diff --git a/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Queries/ListApiKeysHandlerTests.cs b/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Queries/ListApiKeysHandlerTests.cs new file mode 100644 index 00000000..6be09845 --- /dev/null +++ b/src/Server/OneTrueError.SqlServer.Tests/Core/ApiKeys/Queries/ListApiKeysHandlerTests.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using FluentAssertions; +using Griffin.Data; +using Griffin.Data.Mapper; +using OneTrueError.Api.Core.ApiKeys.Queries; +using OneTrueError.App.Core.ApiKeys; +using OneTrueError.SqlServer.Core.ApiKeys; +using OneTrueError.SqlServer.Core.ApiKeys.Queries; +using Xunit; + +namespace OneTrueError.SqlServer.Tests.Core.ApiKeys.Queries +{ + public class ListApiKeysHandlerTests : IDisposable + { + private IAdoNetUnitOfWork _uow; + private ApiKey _existingEntity; + + public ListApiKeysHandlerTests() + { + _existingEntity = new ApiKey + { + ApplicationName = "Arne", + GeneratedKey = Guid.NewGuid().ToString("N"), + SharedSecret = Guid.NewGuid().ToString("N"), + CreatedById = 20, + CreatedAtUtc = DateTime.UtcNow, + }; + _existingEntity.Add(22); + _uow = ConnectionFactory.Create(); + _uow.Insert(_existingEntity); + } + [Fact] + public async void should_be_able_to_load_a_key() + { + var query = new ListApiKeys(); + + var sut = new ListApiKeysHandler(_uow); + var result = await sut.ExecuteAsync(query); + + result.Keys.Should().NotBeEmpty(); + result.Keys[0].ApiKey.Should().Be(_existingEntity.GeneratedKey); + result.Keys[0].ApplicationName.Should().Be(_existingEntity.ApplicationName); + } + + public void Dispose() + { + _uow.Dispose(); + } + } +} diff --git a/src/Server/OneTrueError.SqlServer.Tests/OneTrueError.SqlServer.Tests.csproj b/src/Server/OneTrueError.SqlServer.Tests/OneTrueError.SqlServer.Tests.csproj index 701b71bf..2d2254c1 100644 --- a/src/Server/OneTrueError.SqlServer.Tests/OneTrueError.SqlServer.Tests.csproj +++ b/src/Server/OneTrueError.SqlServer.Tests/OneTrueError.SqlServer.Tests.csproj @@ -35,12 +35,20 @@ ..\packages\DotNetCqs.1.0.0\lib\net45\DotNetCqs.dll True + + ..\packages\FluentAssertions.4.14.0\lib\net45\FluentAssertions.dll + True + + + ..\packages\FluentAssertions.4.14.0\lib\net45\FluentAssertions.Core.dll + True + ..\packages\Griffin.Container.1.1.2\lib\net40\Griffin.Container.dll True - - ..\packages\Griffin.Framework.1.0.37\lib\net45\Griffin.Core.dll + + ..\packages\Griffin.Framework.1.0.39\lib\net45\Griffin.Core.dll True @@ -48,6 +56,7 @@ True + @@ -74,6 +83,10 @@ + + + + @@ -82,6 +95,10 @@ + + {FC331A95-FCA4-4764-8004-0884665DD01F} + OneTrueError.Api + {5EF42A74-9323-49FA-A1F6-974D6DE77202} OneTrueError.App diff --git a/src/Server/OneTrueError.SqlServer.Tests/app.config b/src/Server/OneTrueError.SqlServer.Tests/app.config index 44ccc4b7..ff8fbd69 100644 --- a/src/Server/OneTrueError.SqlServer.Tests/app.config +++ b/src/Server/OneTrueError.SqlServer.Tests/app.config @@ -1,5 +1,8 @@  + + + diff --git a/src/Server/OneTrueError.SqlServer.Tests/packages.config b/src/Server/OneTrueError.SqlServer.Tests/packages.config index 3e22b8f8..892d1bcd 100644 --- a/src/Server/OneTrueError.SqlServer.Tests/packages.config +++ b/src/Server/OneTrueError.SqlServer.Tests/packages.config @@ -1,8 +1,9 @@  + - + diff --git a/src/Server/OneTrueError.SqlServer/Core/ApiKeys/ApiKeyRepository.cs b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/ApiKeyRepository.cs new file mode 100644 index 00000000..cdaa4e5b --- /dev/null +++ b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/ApiKeyRepository.cs @@ -0,0 +1,105 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Griffin.Container; +using Griffin.Data; +using Griffin.Data.Mapper; +using OneTrueError.App.Core.ApiKeys; +using OneTrueError.SqlServer.Core.ApiKeys.Mappings; + +namespace OneTrueError.SqlServer.Core.ApiKeys +{ + /// + /// SQL Server implementation of . + /// + [Component] + public class ApiKeyRepository : IApiKeyRepository + { + private readonly IAdoNetUnitOfWork _uow; + + /// + /// Creates a new instance of . + /// + /// Active unit of work + public ApiKeyRepository(IAdoNetUnitOfWork uow) + { + if (uow == null) throw new ArgumentNullException(nameof(uow)); + + _uow = uow; + } + + /// + /// Get an key by using the generated string. + /// + /// key + /// key + /// Given key was not found. + public async Task GetByKeyAsync(string apiKey) + { + if (apiKey == null) throw new ArgumentNullException(nameof(apiKey)); + var key = await _uow.FirstAsync("GeneratedKey=@1", apiKey); + var sql = "SELECT [ApplicationId] FROM [ApiKeyApplications] WHERE [ApiKeyId] = @1"; + var apps = await _uow.ToListAsync(new IntMapper(), sql, key.Id); + foreach (var app in apps) + { + key.Add(app); + } + return key; + } + + /// + /// Create a new key + /// + /// key to create + /// task + public async Task CreateAsync(ApiKey key) + { + if (key == null) throw new ArgumentNullException(nameof(key)); + + await _uow.InsertAsync(key); + foreach (var applicationId in key.AllowedApplications) + { + AddApplication(key.Id, applicationId); + } + } + + /// + /// Update an existing key + /// + /// key + /// task + public async Task UpdateAsync(ApiKey key) + { + if (key == null) throw new ArgumentNullException(nameof(key)); + + await _uow.InsertAsync(key); + + var existingMappings = + await _uow.ToListAsync("SELECT ApplicationId FROM ApiKeyApplications WHERE ApiKeyId=@1", + key); + + var removed = existingMappings.Except(key.AllowedApplications); + foreach (var applicationId in removed) + { + _uow.Execute("DELETE FROM ApiKeyApplications WHERE ApiKeyId = @1 AND ApplicationId = @2", + new[] { key.Id, applicationId }); + } + + var added = key.AllowedApplications.Except(existingMappings); + foreach (var id in added) + { + AddApplication(key.Id, id); + } + } + + private void AddApplication(int apiKeyId, int applicationId) + { + _uow.Execute("INSERT INTO [ApiKeyApplications] (ApiKeyId, ApplicationId) VALUES(@api, @app)", new + { + api = apiKeyId, + app = applicationId + }); + } + + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Commands/CreateApiKeyHandler.cs b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Commands/CreateApiKeyHandler.cs new file mode 100644 index 00000000..16e3a530 --- /dev/null +++ b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Commands/CreateApiKeyHandler.cs @@ -0,0 +1,49 @@ +using System; +using System.Threading.Tasks; +using DotNetCqs; +using Griffin.Container; +using Griffin.Data; +using OneTrueError.Api.Core.ApiKeys.Commands; +using OneTrueError.App; + +namespace OneTrueError.SqlServer.Core.ApiKeys.Commands +{ + [Component(RegisterAsSelf = true)] + public class CreateApiKeyHandler : ICommandHandler + { + private readonly IAdoNetUnitOfWork _unitOfWork; + + public CreateApiKeyHandler(IAdoNetUnitOfWork unitOfWork) + { + _unitOfWork = unitOfWork; + } + + public async Task ExecuteAsync(CreateApiKey command) + { + int id; + using (var cmd = _unitOfWork.CreateDbCommand()) + { + cmd.CommandText = + "INSERT INTO ApiKeys (ApplicationName, GeneratedKey, SharedSecret, CreatedById, CreatedAtUtc) VALUES(@appName, @key, @secret, @by, @when); select cast(scope_identity() as int);"; + cmd.AddParameter("appName", command.ApplicationName); + cmd.AddParameter("key", command.ApiKey); + cmd.AddParameter("secret", command.SharedSecret); + cmd.AddParameter("by", command.AccountId); + cmd.AddParameter("when", DateTime.UtcNow); + id = (int) await cmd.ExecuteScalarAsync(); + } + + foreach (var applicationId in command.ApplicationIds) + { + using (var cmd = _unitOfWork.CreateDbCommand()) + { + cmd.CommandText = + "INSERT INTO ApiKeyApplications (ApiKeyId, ApplicationId) VALUES(@key, @app)"; + cmd.AddParameter("app", applicationId); + cmd.AddParameter("key", id); + await cmd.ExecuteNonQueryAsync(); + } + } + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Commands/DeleteApiKeyHandler.cs b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Commands/DeleteApiKeyHandler.cs new file mode 100644 index 00000000..64ba7cb5 --- /dev/null +++ b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Commands/DeleteApiKeyHandler.cs @@ -0,0 +1,40 @@ +using System; +using System.Threading.Tasks; +using DotNetCqs; +using Griffin.Container; +using Griffin.Data; +using Griffin.Data.Mapper; +using OneTrueError.Api.Core.ApiKeys.Commands; +using OneTrueError.App.Core.ApiKeys; + +namespace OneTrueError.SqlServer.Core.ApiKeys.Commands +{ + [Component(RegisterAsSelf = true)] + public class DeleteApiKeyHandler : ICommandHandler + { + private readonly IAdoNetUnitOfWork _unitOfWork; + + public DeleteApiKeyHandler(IAdoNetUnitOfWork unitOfWork) + { + if (unitOfWork == null) throw new ArgumentNullException(nameof(unitOfWork)); + _unitOfWork = unitOfWork; + } + + public Task ExecuteAsync(DeleteApiKey command) + { + int id; + if (!string.IsNullOrEmpty(command.ApiKey)) + { + id = (int) _unitOfWork.ExecuteScalar("SELECT Id FROM ApiKeys WHERE GeneratedKey = @key", new { key=command.ApiKey}); + } + else + { + id = command.Id; + } + + _unitOfWork.ExecuteNonQuery("DELETE FROM [ApiKeyApplications] WHERE ApiKeyId = @id", new {id}); + _unitOfWork.ExecuteNonQuery("DELETE FROM [ApiKeys] WHERE Id = @id", new { id }); + return Task.FromResult(null); + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Mappings/ApiKeyMapper.cs b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Mappings/ApiKeyMapper.cs new file mode 100644 index 00000000..504232fb --- /dev/null +++ b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Mappings/ApiKeyMapper.cs @@ -0,0 +1,16 @@ +using Griffin.Data.Mapper; +using OneTrueError.App.Core.ApiKeys; + +namespace OneTrueError.SqlServer.Core.ApiKeys.Mappings +{ + public class ApiKeyMapper : CrudEntityMapper + { + public ApiKeyMapper() : base("ApiKeys") + { + Property(x => x.Id) + .PrimaryKey(true); + Property(x => x.AllowedApplications) + .Ignore(); + } + } +} diff --git a/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Mappings/IntMapper.cs b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Mappings/IntMapper.cs new file mode 100644 index 00000000..551a503e --- /dev/null +++ b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Mappings/IntMapper.cs @@ -0,0 +1,23 @@ +using System.Data; +using Griffin.Data.Mapper; + +namespace OneTrueError.SqlServer.Core.ApiKeys.Mappings +{ + public class IntMapper : IEntityMapper + { + public object Create(IDataRecord record) + { + return record[0]; + } + + public void Map(IDataRecord source, object destination) + { + + } + + public void Map(IDataRecord source, int destination) + { + + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Mappings/MirrorMapper.cs b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Mappings/MirrorMapper.cs new file mode 100644 index 00000000..c17148ef --- /dev/null +++ b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Mappings/MirrorMapper.cs @@ -0,0 +1,48 @@ +using System; +using System.Data; +using System.Reflection; +using Griffin.Data.Mapper; + +namespace OneTrueError.SqlServer.Core.ApiKeys.Mappings +{ + public class MirrorMapper : IEntityMapper where T : new() + { + private MethodInfo[] _setters; + + public void Map(IDataRecord source, T destination) + { + Map(source, (object) destination); + } + + public object Create(IDataRecord record) + { + return new T(); + } + + public void Map(IDataRecord source, object destination) + { + if (_setters == null) + _setters = MapPropertySetters(source, typeof(T)); + + for (var i = 0; i < _setters.Length; i++) + { + var value = source[i]; + if (value is DBNull) + continue; + + _setters[i].Invoke(destination, new[] {value}); + } + } + + private MethodInfo[] MapPropertySetters(IDataRecord source, Type type) + { + var fields = new MethodInfo[source.FieldCount]; + for (var i = 0; i < source.FieldCount; i++) + { + var name = source.GetName(i); + fields[i] = type.GetProperty(name, BindingFlags.IgnoreCase|BindingFlags.Public|BindingFlags.Instance).SetMethod; + } + return fields; + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Queries/GetApiKeyHandler.cs b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Queries/GetApiKeyHandler.cs new file mode 100644 index 00000000..cf60a988 --- /dev/null +++ b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Queries/GetApiKeyHandler.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DotNetCqs; +using Griffin.Container; +using Griffin.Data; +using Griffin.Data.Mapper; +using OneTrueError.Api.Core.ApiKeys.Queries; +using OneTrueError.App.Core.ApiKeys; +using OneTrueError.SqlServer.Core.ApiKeys.Mappings; + +namespace OneTrueError.SqlServer.Core.ApiKeys.Queries +{ + /// + /// Handler for . + /// + [Component(RegisterAsSelf = true)] + public class GetApiKeyHandler : IQueryHandler + { + private IAdoNetUnitOfWork _uow; + private static MirrorMapper _appMapping = new MirrorMapper(); + + /// + /// Creates a new instance of . + /// + /// valid uow + public GetApiKeyHandler(IAdoNetUnitOfWork uow) + { + if (uow == null) throw new ArgumentNullException(nameof(uow)); + + _uow = uow; + } + + /// Method used to execute the query + /// Query to execute. + /// Task which will contain the result once completed. + public async Task ExecuteAsync(GetApiKey query) + { + if (query == null) throw new ArgumentNullException(nameof(query)); + + ApiKey key; + if (!string.IsNullOrEmpty(query.ApiKey)) + key = await _uow.FirstAsync("GeneratedKey=@1", query.ApiKey); + else + key = await _uow.FirstAsync("Id=@1", query.Id); + + var result = new GetApiKeyResult + { + ApplicationName = key.ApplicationName, + CreatedAtUtc = key.CreatedAtUtc, + CreatedById = key.CreatedById, + GeneratedKey = key.GeneratedKey, + Id = key.Id, + SharedSecret = key.SharedSecret + }; + + var sql = @"SELECT Id as ApplicationId, Name as ApplicationName +FROM Applications +JOIN ApiKeyApplications ON (Id = ApplicationId) +WHERE ApiKeyId = @1"; + var apps = await _uow.ToListAsync(_appMapping, sql, key.Id); + result.AllowedApplications = apps.ToArray(); + return result; + } + } +} diff --git a/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Queries/ListApiKeysHandler.cs b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Queries/ListApiKeysHandler.cs new file mode 100644 index 00000000..85edfab9 --- /dev/null +++ b/src/Server/OneTrueError.SqlServer/Core/ApiKeys/Queries/ListApiKeysHandler.cs @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using DotNetCqs; +using Griffin.Container; +using Griffin.Data; +using Griffin.Data.Mapper; +using OneTrueError.Api.Core.ApiKeys.Queries; +using OneTrueError.SqlServer.Core.ApiKeys.Mappings; + +namespace OneTrueError.SqlServer.Core.ApiKeys.Queries +{ + [Component(RegisterAsSelf = true)] + public class ListApiKeysHandler : IQueryHandler + { + private IAdoNetUnitOfWork _unitOfWork; + private MirrorMapper _mapper = new MirrorMapper(); + + public ListApiKeysHandler(IAdoNetUnitOfWork unitOfWork) + { + _unitOfWork = unitOfWork; + } + + public async Task ExecuteAsync(ListApiKeys query) + { + var keys = + await + _unitOfWork.ToListAsync(_mapper, + "SELECT ID, GeneratedKey ApiKey, ApplicationName FROM ApiKeys ORDER BY ApplicationName"); + return new ListApiKeysResult {Keys = keys.ToArray()}; + } + } +} diff --git a/src/Server/OneTrueError.SqlServer/Database.sql b/src/Server/OneTrueError.SqlServer/Database.sql index 2efbe85e..65a5ab08 100644 --- a/src/Server/OneTrueError.SqlServer/Database.sql +++ b/src/Server/OneTrueError.SqlServer/Database.sql @@ -279,7 +279,7 @@ CREATE TABLE dbo.Users IF OBJECT_ID(N'dbo.[ApplicationMembers]', N'U') IS NULL BEGIN - CREATE TABLE [dbo].[ApplicationMembers] ( + CREATE TABLE [dbo].[ApplicationMembers] ( [AccountId] INT NULL foreign key references Accounts (Id), [ApplicationId] INT NOT NULL foreign key references Applications (Id), [EmailAddress] nvarchar(255) not null, @@ -292,7 +292,7 @@ END IF OBJECT_ID(N'dbo.[QueueEvents]', N'U') IS NULL BEGIN - CREATE TABLE [dbo].[QueueEvents] ( + CREATE TABLE [dbo].[QueueEvents] ( [Id] INT identity not NULL primary key, [ApplicationId] INT NOT NULL, [CreatedAtUtc] DATETIME NOT NULL, @@ -303,7 +303,7 @@ END IF OBJECT_ID(N'dbo.[QueueReports]', N'U') IS NULL BEGIN - CREATE TABLE [dbo].[QueueReports] ( + CREATE TABLE [dbo].[QueueReports] ( [Id] INT identity not NULL primary key, [ApplicationId] INT NOT NULL, [CreatedAtUtc] DATETIME NOT NULL, @@ -316,7 +316,7 @@ END IF OBJECT_ID(N'dbo.[QueueFeedback]', N'U') IS NULL BEGIN - CREATE TABLE [dbo].[QueueFeedback] ( + CREATE TABLE [dbo].[QueueFeedback] ( [Id] INT identity not NULL primary key, [ApplicationId] INT NOT NULL, [CreatedAtUtc] DATETIME NOT NULL, @@ -327,3 +327,31 @@ BEGIN END insert into Applications (Name, AppKey, CreatedById, CreatedAtUtc, ApplicationType, SharedSecret) VALUES('test', '13d82df603a845c7a27164c4fec19dd6', 1, GetUtcDate(), 'DesktopApplication', '6f0a0a7fac6d42caa7cc47bb34a6520b'); + +IF OBJECT_ID(N'dbo.[DatabaseSchema]', N'U') IS NULL +BEGIN + CREATE TABLE [dbo].[DatabaseSchema] ( + [Version] int not null default 1 + ); + +END + +IF OBJECT_ID(N'dbo.[ApiKeys]', N'U') IS NULL +BEGIN + CREATE TABLE [dbo].[ApiKeys] ( + [Id] INT identity not NULL primary key, + [ApplicationName] varchar(40) NOT NULL, + [CreatedAtUtc] DATETIME NOT NULL, + [CreatedById] int NOT NULL, + [GeneratedKey] varchar(36) NOT NULL, + [SharedSecret] varchar(36) NOT NULL + ); + CREATE TABLE [dbo].[ApiKeyApplications] ( + [ApiKeyId] INT not NULL, + [ApplicationId] INT NOT NULL, + Primary key (ApiKeyId, ApplicationId), + FOREIGN KEY (ApiKeyId) REFERENCES ApiKeys(Id), + FOREIGN KEY (ApplicationId) REFERENCES Applications(Id) + ); + update DatabaseSchema SET Version = 2; +END diff --git a/src/Server/OneTrueError.SqlServer/OneTrueError.SqlServer.csproj b/src/Server/OneTrueError.SqlServer/OneTrueError.SqlServer.csproj index 643da36c..6d138333 100644 --- a/src/Server/OneTrueError.SqlServer/OneTrueError.SqlServer.csproj +++ b/src/Server/OneTrueError.SqlServer/OneTrueError.SqlServer.csproj @@ -40,8 +40,8 @@ ..\packages\Griffin.Container.1.1.2\lib\net40\Griffin.Container.dll True - - ..\packages\Griffin.Framework.1.0.37\lib\net45\Griffin.Core.dll + + ..\packages\Griffin.Framework.1.0.39\lib\net45\Griffin.Core.dll True @@ -71,6 +71,14 @@ + + + + + + + + diff --git a/src/Server/OneTrueError.SqlServer/packages.config b/src/Server/OneTrueError.SqlServer/packages.config index dbc24209..d78f7c43 100644 --- a/src/Server/OneTrueError.SqlServer/packages.config +++ b/src/Server/OneTrueError.SqlServer/packages.config @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/App_Start/FilterConfig.cs b/src/Server/OneTrueError.Web/App_Start/FilterConfig.cs index ecc3f1c7..036ae2a0 100644 --- a/src/Server/OneTrueError.Web/App_Start/FilterConfig.cs +++ b/src/Server/OneTrueError.Web/App_Start/FilterConfig.cs @@ -1,6 +1,7 @@ using System.Web; using System.Web.Mvc; using OneTrueError.Web.Infrastructure; +using OneTrueError.Web.Infrastructure.Auth; namespace OneTrueError.Web { diff --git a/src/Server/OneTrueError.Web/App_Start/WebApiConfig.cs b/src/Server/OneTrueError.Web/App_Start/WebApiConfig.cs index ae8f9ceb..af8c4f04 100644 --- a/src/Server/OneTrueError.Web/App_Start/WebApiConfig.cs +++ b/src/Server/OneTrueError.Web/App_Start/WebApiConfig.cs @@ -1,5 +1,6 @@ using System.Web.Http; using OneTrueError.Web.Infrastructure; +using OneTrueError.Web.Infrastructure.Auth; namespace OneTrueError.Web { @@ -18,6 +19,7 @@ public static string UrlPrefixRelative public static void Register(HttpConfiguration config) { config.SuppressDefaultHostAuthentication(); + config.Filters.Add(new ApiKeyAuthenticator()); config.Filters.Add(new WebApiAuthenticationFilter()); config.MapHttpAttributeRoutes(); diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Controllers/ApiKeysController.cs b/src/Server/OneTrueError.Web/Areas/Admin/Controllers/ApiKeysController.cs new file mode 100644 index 00000000..f360c948 --- /dev/null +++ b/src/Server/OneTrueError.Web/Areas/Admin/Controllers/ApiKeysController.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Web; +using System.Web.Mvc; +using DotNetCqs; +using OneTrueError.Api.Core.ApiKeys.Commands; +using OneTrueError.Api.Core.ApiKeys.Queries; +using OneTrueError.Api.Core.Applications.Queries; +using OneTrueError.App.Core.Applications; +using OneTrueError.Web.Areas.Admin.Models.ApiKeys; +using OneTrueError.Web.Models; + +namespace OneTrueError.Web.Areas.Admin.Controllers +{ + public class ApiKeysController : Controller + { + private IQueryBus _queryBus; + private ICommandBus _commandBus; + public ApiKeysController(IQueryBus queryBus, ICommandBus commandBus) + { + _queryBus = queryBus; + _commandBus = commandBus; + } + + public async Task Index() + { + var query= new ListApiKeys(); + var result = await _queryBus.QueryAsync(query); + var vms = result.Keys.Select(x => new ListViewModelItem {Id = x.Id, Name = x.ApplicationName}).ToArray(); + var model = new ListViewModel {Keys = vms}; + return View(model); + } + + public async Task Delete(int id) + { + var cmd = new DeleteApiKey(id); + await _commandBus.ExecuteAsync(cmd); + return RedirectToAction("Deleted"); + } + + public ActionResult Deleted() + { + return View(); + } + + public async Task Create() + { + var applications = await GetMyApplications(); + + var model = new CreateViewModel { Applications = applications }; + return View(model); + } + + private async Task> GetMyApplications() + { + var query = new GetApplicationList + { + AccountId = SessionUser.Current.AccountId, + FilterAsAdmin = true + }; + var items = await _queryBus.QueryAsync(query); + var applications = items.ToDictionary(x => x.Id.ToString(), x => x.Name); + return applications; + } + + + public async Task Details(int id) + { + var key = await _queryBus.QueryAsync(new GetApiKey(id)); + return View(key); + } + + [HttpPost] + public async Task Create(CreateViewModel model) + { + model.Applications = await GetMyApplications(); + if (!ModelState.IsValid) + return View(model); + + var apiKey = Guid.NewGuid().ToString("N"); + var sharedSecret = Guid.NewGuid().ToString("N"); + var apps = model.SelectedApplications.Select(int.Parse).ToArray(); + var cmd = new CreateApiKey(model.ApplicationName, apiKey, sharedSecret, apps); + await _commandBus.ExecuteAsync(cmd); + + return RedirectToAction("Created", new {apiKey, sharedSecret}); + } + + public ActionResult Created(string apiKey, string sharedSecret) + { + ViewBag.ApiKey = apiKey; + ViewBag.SharedSecret = sharedSecret; + return View(); + } + + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Models/ApiKeys/CreateViewModel.cs b/src/Server/OneTrueError.Web/Areas/Admin/Models/ApiKeys/CreateViewModel.cs new file mode 100644 index 00000000..a3abc51b --- /dev/null +++ b/src/Server/OneTrueError.Web/Areas/Admin/Models/ApiKeys/CreateViewModel.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Web; + +namespace OneTrueError.Web.Areas.Admin.Models.ApiKeys +{ + public class CreateViewModel + { + public Dictionary Applications { get; set; } + + + [Required, Display(Name = "Application name")] + public string ApplicationName { get; set; } + + public bool ReadOnly { get; set; } + + [Display(Name = "Selected applications")] + public string[] SelectedApplications { get; set; } + } +} + +/*function S4() { + return (((1+Math.random())*0x10000)|0).toString(16).substring(1); +} + +// then to call it, plus stitch in '4' in the third group +guid = (S4() + S4() + "-" + S4() + "-4" + S4().substr(0,3) + "-" + S4() + "-" + S4() + S4() + S4()).toLowerCase(); +*/ \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Models/ApiKeys/ListViewModel.cs b/src/Server/OneTrueError.Web/Areas/Admin/Models/ApiKeys/ListViewModel.cs new file mode 100644 index 00000000..050b8488 --- /dev/null +++ b/src/Server/OneTrueError.Web/Areas/Admin/Models/ApiKeys/ListViewModel.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace OneTrueError.Web.Areas.Admin.Models.ApiKeys +{ + public class ListViewModel + { + public ListViewModelItem[] Keys { get; set; } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Models/ApiKeys/ListViewModelItem.cs b/src/Server/OneTrueError.Web/Areas/Admin/Models/ApiKeys/ListViewModelItem.cs new file mode 100644 index 00000000..79c69a10 --- /dev/null +++ b/src/Server/OneTrueError.Web/Areas/Admin/Models/ApiKeys/ListViewModelItem.cs @@ -0,0 +1,8 @@ +namespace OneTrueError.Web.Areas.Admin.Models.ApiKeys +{ + public class ListViewModelItem + { + public int Id { get; set; } + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Create.cshtml b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Create.cshtml new file mode 100644 index 00000000..ec6e3abe --- /dev/null +++ b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Create.cshtml @@ -0,0 +1,39 @@ +@model OneTrueError.Web.Areas.Admin.Models.ApiKeys.CreateViewModel +@{ + ViewBag.Title = "Create"; +} +
+
+

Create a new API key

+

+ +

+
+ @Html.ValidationSummary(false) +
+ @Html.LabelFor(x => x.ApplicationName, new {@class = "control-label"}) + @Html.TextBoxFor(x => x.ApplicationName, new {@class = "form-control", placeholder = "Application name"}) + +
+ @*
+ +
*@ +
+ @Html.LabelFor(x => x.SelectedApplications, new {@class = "control-label"}) +
+ Select the applications that this ApiKey can access. (none selected = can access all) +
+ @foreach (var app in Model.Applications) + { + + @app.Value
+ } +
+
+ +
+
+
\ No newline at end of file diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Created.cshtml b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Created.cshtml new file mode 100644 index 00000000..59d93180 --- /dev/null +++ b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Created.cshtml @@ -0,0 +1,26 @@ +@{ + ViewBag.Title = "ApiKey was created"; +} + + +
+
+
+

Api key

+
The API key have been created.
+

To invoke the server API pass the API key in a HttpHeader called X-Api-Key. Use the shared secret to calculate a HMAC signature on the HTTP Request body and include it in the http header X-Api-Signature.

+
+
Api key
+
@ViewBag.ApiKey
+
Shared secret
+
@ViewBag.SharedSecret
+
+ +

Example

+
var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_sharedSecret));
+var hash = hmac.ComputeHash(httpBodyAsByteArray);
+var signature = Convert.ToBase64String(hash);
+
+
+
+
diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Deleted.cshtml b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Deleted.cshtml new file mode 100644 index 00000000..a6ee1554 --- /dev/null +++ b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Deleted.cshtml @@ -0,0 +1,13 @@ +@{ + ViewBag.Title = "ApiKey is deleted"; +} + + +
+
+
+

Api key

+
The ApiKey has been deleted.
+
+
+
diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Details.cshtml b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Details.cshtml new file mode 100644 index 00000000..59f65a97 --- /dev/null +++ b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Details.cshtml @@ -0,0 +1,67 @@ +@model OneTrueError.Api.Core.ApiKeys.Queries.GetApiKeyResult +@{ + ViewBag.Title = "Api key"; +} + + +
+
+
+

Api key

+
+

+ To invoke the server API pass the API key in a HttpHeader called X-Api-Key. Use the shared secret to calculate a HMAC signature on the HTTP Request body and include it in the http header X-Api-Signature. +

+
+
+
Api key
+
@Model.GeneratedKey
+
Shared secret
+
@Model.SharedSecret
+
Created by
+
+ +
+
+
+
+

Authorized applications

+

The key is authorized to modify the following applications:

+
    + @foreach (var app in Model.AllowedApplications) + { +
  • @app.ApplicationName
  • + } +
+
+ +

Signing example

+
var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_sharedSecret));
+var hash = hmac.ComputeHash(httpBodyAsByteArray);
+var signature = Convert.ToBase64String(hash);
+
+
+
+
+ + +
+
+
+
+
+@section scripts +{ + +} diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Index.cshtml b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Index.cshtml new file mode 100644 index 00000000..7fb2ae4c --- /dev/null +++ b/src/Server/OneTrueError.Web/Areas/Admin/Views/ApiKeys/Index.cshtml @@ -0,0 +1,22 @@ +@model OneTrueError.Web.Areas.Admin.Models.ApiKeys.ListViewModel +@{ + ViewBag.Title = "Admin - Api keys"; +} +
+
+

Api keys

+

+ Api keys are used when communicating with OneTrueError through the API. +

+ Create a new key +

Existing keys

+
    + @foreach (var item in Model.Keys) + { +
  • + @item.Name +
  • + } +
+
+
diff --git a/src/Server/OneTrueError.Web/Areas/Admin/Views/Messaging/Email.cshtml b/src/Server/OneTrueError.Web/Areas/Admin/Views/Messaging/Email.cshtml index f144f452..e62ad486 100644 --- a/src/Server/OneTrueError.Web/Areas/Admin/Views/Messaging/Email.cshtml +++ b/src/Server/OneTrueError.Web/Areas/Admin/Views/Messaging/Email.cshtml @@ -7,7 +7,7 @@

Email configuration

- OneTrueError can send email notifcations upon different types of events (and password resets etc). To do this, we need + OneTrueError can send email notifications upon different types of events (and password resets etc). To do this, we need to have a SMTP account for mailing.

diff --git a/src/Server/OneTrueError.Web/Areas/Admin/WizardSteps.cs b/src/Server/OneTrueError.Web/Areas/Admin/WizardSteps.cs index 3a66f171..fe043c52 100644 --- a/src/Server/OneTrueError.Web/Areas/Admin/WizardSteps.cs +++ b/src/Server/OneTrueError.Web/Areas/Admin/WizardSteps.cs @@ -9,6 +9,7 @@ public static class WizardSteps new WizardStepInfo("Start page", "~/admin"), new WizardStepInfo("Base configuration", "~/admin/home/basics/"), new WizardStepInfo("Error tracking", "~/admin/home/errors/"), + new WizardStepInfo("Api keys", "~/admin/apikeys/"), new WizardStepInfo("Mail settings", "~/admin/messaging/email/"), new WizardStepInfo("Message queues", "~/admin/queues/"), }; diff --git a/src/Server/OneTrueError.Web/Areas/Receiver/Helpers/SaveReportHandler.cs b/src/Server/OneTrueError.Web/Areas/Receiver/Helpers/SaveReportHandler.cs index bfc6ca53..8c7228f3 100644 --- a/src/Server/OneTrueError.Web/Areas/Receiver/Helpers/SaveReportHandler.cs +++ b/src/Server/OneTrueError.Web/Areas/Receiver/Helpers/SaveReportHandler.cs @@ -17,17 +17,25 @@ namespace OneTrueError.Web.Areas.Receiver.Helpers { + /// + /// Validates inbound report and store it in our internal queue for analysis. + /// public class SaveReportHandler { private readonly ILog _logger = LogManager.GetLogger(typeof (SaveReportHandler)); private IMessageQueue _queue; + /// + /// Creates a new instance of . + /// + /// provider public SaveReportHandler(IMessageQueueProvider queueProvider) { + if (queueProvider == null) throw new ArgumentNullException("queueProvider"); _queue = queueProvider.Open("ReportQueue"); } - public async Task BuildReportAsync(string appKey, string sig, string remoteAddress, byte[] reportBody) + public async Task BuildReportAsync(string appKey, string signatureProvidedByTheClient, string remoteAddress, byte[] reportBody) { Guid tempKey; if (!Guid.TryParse(appKey, out tempKey)) @@ -43,9 +51,9 @@ public async Task BuildReportAsync(string appKey, string sig, string remoteAddre throw new HttpException(400, "AppKey was not found in the database. Key '" + appKey + "'."); } - if (!ReportValidator.ValidateBody(application.SharedSecret, sig, reportBody)) + if (!ReportValidator.ValidateBody(application.SharedSecret, signatureProvidedByTheClient, reportBody)) { - await StoreInvalidReportAsync(appKey, sig, remoteAddress, reportBody); + await StoreInvalidReportAsync(appKey, signatureProvidedByTheClient, remoteAddress, reportBody); throw new HttpException(403, "You either specified the wrong SharedSecret, or someone tampered with the data."); } diff --git a/src/Server/OneTrueError.Web/Areas/Receiver/Models/ReportValidator.cs b/src/Server/OneTrueError.Web/Areas/Receiver/Models/ReportValidator.cs index 20e082b1..8a916c5a 100644 --- a/src/Server/OneTrueError.Web/Areas/Receiver/Models/ReportValidator.cs +++ b/src/Server/OneTrueError.Web/Areas/Receiver/Models/ReportValidator.cs @@ -4,10 +4,24 @@ namespace OneTrueError.Web.Areas.Receiver.Models { + /// + /// Used to make sure that the uploaded report was signed with the correct shared secret. + /// public class ReportValidator { + /// + /// Validate HTTP body + /// + /// Shared secret associated with the AppKey. + /// Signature that the client have generated. + /// HTTP body + /// true if the specifiedSignature was generated with the shared secret; otherwise false. public static bool ValidateBody(string sharedSecret, string specifiedSignature, byte[] body) { + if (sharedSecret == null) throw new ArgumentNullException("sharedSecret"); + if (specifiedSignature == null) throw new ArgumentNullException("specifiedSignature"); + if (body == null) throw new ArgumentNullException("body"); + var hashAlgo = new HMACSHA256(Encoding.UTF8.GetBytes(sharedSecret.ToLower())); var hash = hashAlgo.ComputeHash(body); var signature = Convert.ToBase64String(hash); diff --git a/src/Server/OneTrueError.Web/Controllers/CqsController.cs b/src/Server/OneTrueError.Web/Controllers/CqsController.cs index 4ea4b743..ad8546b4 100644 --- a/src/Server/OneTrueError.Web/Controllers/CqsController.cs +++ b/src/Server/OneTrueError.Web/Controllers/CqsController.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Web; @@ -12,6 +13,7 @@ using Griffin.Cqs.Authorization; using Griffin.Cqs.Net; using OneTrueError.Api.Core.Applications.Commands; +using OneTrueError.App; using OneTrueError.Web.Infrastructure.Cqs; using OneTrueError.Web.Models; @@ -89,17 +91,22 @@ public async Task Cqs() var prop = cqsObject.GetType().GetProperty("UserId"); if (prop != null && prop.CanWrite) - prop.SetValue(cqsObject, SessionUser.Current.AccountId); + prop.SetValue(cqsObject, OneTruePrincipal.Current.Identity.AccountId); prop = cqsObject.GetType().GetProperty("AccountId"); if (prop != null && prop.CanWrite) - prop.SetValue(cqsObject, SessionUser.Current.AccountId); + prop.SetValue(cqsObject, OneTruePrincipal.Current.Identity.AccountId); + + + + RestrictOnApplicationId(cqsObject); ClientResponse cqsReplyObject = null; Exception ex = null; try { cqsReplyObject = await _cqsProcessor.ProcessAsync(cqsObject); + RestrictOnApplicationId(cqsReplyObject); } catch (AggregateException e1) { @@ -149,6 +156,22 @@ public async Task Cqs() return reply; } + private static void RestrictOnApplicationId(object cqsObject) + { + PropertyInfo prop; + if (OneTruePrincipal.Current.Identity.AuthenticationType == "ApiKey") + { + prop = cqsObject.GetType().GetProperty("ApplicationId"); + if (prop != null && prop.CanRead) + { + var value = (int) prop.GetValue(cqsObject); + if (!OneTruePrincipal.Current.IsInRole("Application_" + value) && + !OneTruePrincipal.Current.IsInRole("AllApplications")) + throw new HttpException(403, "The given application key is not allowed for application " + value); + } + } + } + private string FirstLine(string msg) { var pos = msg.IndexOfAny(new[] {'\r', '\n'}); diff --git a/src/Server/OneTrueError.Web/Controllers/HomeController.cs b/src/Server/OneTrueError.Web/Controllers/HomeController.cs index e91c8716..84da6487 100644 --- a/src/Server/OneTrueError.Web/Controllers/HomeController.cs +++ b/src/Server/OneTrueError.Web/Controllers/HomeController.cs @@ -1,4 +1,8 @@ -using System.Web.Mvc; +using System; +using System.Threading.Tasks; +using System.Web.Mvc; +using OneTrueError.Api.Client; +using OneTrueError.Api.Core.Applications.Queries; namespace OneTrueError.Web.Controllers { diff --git a/src/Server/OneTrueError.Web/Global.asax.cs b/src/Server/OneTrueError.Web/Global.asax.cs index 2bffdd1a..12f0d285 100644 --- a/src/Server/OneTrueError.Web/Global.asax.cs +++ b/src/Server/OneTrueError.Web/Global.asax.cs @@ -103,7 +103,6 @@ private void ConfigureStandardSetup() provider.Scan(typeof(UserMapper).Assembly); EntityMappingProvider.Provider = provider; - OneTrueErrorPrincipal.Assigned += OnAssignedPrincipal; GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); @@ -117,9 +116,5 @@ private static bool IsWebApiRequest() WebApiConfig.UrlPrefixRelative); } - private void OnAssignedPrincipal(object sender, EventArgs e) - { - HttpContext.Current.User = (IPrincipal)sender; - } } } \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/Infrastructure/Auth/ApiKeyAuthenticator.cs b/src/Server/OneTrueError.Web/Infrastructure/Auth/ApiKeyAuthenticator.cs new file mode 100644 index 00000000..024394da --- /dev/null +++ b/src/Server/OneTrueError.Web/Infrastructure/Auth/ApiKeyAuthenticator.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Http; +using System.Web.Http.Filters; +using OneTrueError.App; +using OneTrueError.App.Core.ApiKeys; + +namespace OneTrueError.Web.Infrastructure.Auth +{ + public class ApiKeyAuthenticator : IAuthenticationFilter + { + public bool AllowMultiple { get { return true; } } + +#pragma warning disable 1998 + public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken) +#pragma warning restore 1998 + { + IEnumerable apiKeys; + IEnumerable tokens; + if (!context.Request.Headers.TryGetValues("X-Api-Key", out apiKeys) || + !context.Request.Headers.TryGetValues("X-Api-Signature", out tokens)) + { + return; + } + + using (var scope = GlobalConfiguration.Configuration.DependencyResolver.BeginScope()) + { + var repos = (IApiKeyRepository) scope.GetService(typeof(IApiKeyRepository)); + var key = await repos.GetByKeyAsync(apiKeys.First()); + var content = await context.Request.Content.ReadAsByteArrayAsync(); + if (!key.ValidateSignature(tokens.First(), content)) + { + context.ErrorResult = + new AuthenticationFailureResult( + "Body could not be signed by the shared secret. Verify your client configuration.", + context.Request); + return; + } + + var roles = key.AllowedApplications.Select(x => "Application_" + x).ToArray(); + var principal = new OneTruePrincipal(0, key.GeneratedKey, roles); + principal.Identity.AuthenticationType = "ApiKey"; + context.Principal = principal; + Thread.CurrentPrincipal = principal; + } + } + +#pragma warning disable 1998 + public async Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken) +#pragma warning restore 1998 + { + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/Infrastructure/AuthenticationFailureResult.cs b/src/Server/OneTrueError.Web/Infrastructure/Auth/AuthenticationFailureResult.cs similarity index 92% rename from src/Server/OneTrueError.Web/Infrastructure/AuthenticationFailureResult.cs rename to src/Server/OneTrueError.Web/Infrastructure/Auth/AuthenticationFailureResult.cs index ca58aa4f..2b1d6087 100644 --- a/src/Server/OneTrueError.Web/Infrastructure/AuthenticationFailureResult.cs +++ b/src/Server/OneTrueError.Web/Infrastructure/Auth/AuthenticationFailureResult.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; using System.Web.Http; -namespace OneTrueError.Web.Infrastructure +namespace OneTrueError.Web.Infrastructure.Auth { public class AuthenticationFailureResult : IHttpActionResult { diff --git a/src/Server/OneTrueError.Web/Infrastructure/CustomMvcAuthorizeFilter.cs b/src/Server/OneTrueError.Web/Infrastructure/Auth/CustomMvcAuthorizeFilter.cs similarity index 86% rename from src/Server/OneTrueError.Web/Infrastructure/CustomMvcAuthorizeFilter.cs rename to src/Server/OneTrueError.Web/Infrastructure/Auth/CustomMvcAuthorizeFilter.cs index 3b98eb2e..d0781f16 100644 --- a/src/Server/OneTrueError.Web/Infrastructure/CustomMvcAuthorizeFilter.cs +++ b/src/Server/OneTrueError.Web/Infrastructure/Auth/CustomMvcAuthorizeFilter.cs @@ -1,13 +1,13 @@ using System; using System.Security.Cryptography; -using System.Security.Principal; using System.Threading; using System.Web; using System.Web.Mvc; using System.Web.Security; +using OneTrueError.App; using OneTrueError.Web.Models; -namespace OneTrueError.Web.Infrastructure +namespace OneTrueError.Web.Infrastructure.Auth { [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class CustomMvcAuthorizeFilter : AuthorizeAttribute @@ -50,12 +50,8 @@ protected override bool AuthorizeCore(HttpContextBase httpContext) if (SessionUser.IsAuthenticated) { - Thread.CurrentPrincipal = new OneTrueErrorPrincipal - { - AccountId = SessionUser.Current.AccountId, - ApplicationId = SessionUser.Current.ApplicationId, - Identity = new GenericIdentity(SessionUser.Current.UserName), - }; + Thread.CurrentPrincipal = new OneTruePrincipal(SessionUser.Current.AccountId, + SessionUser.Current.UserName, SessionUser.Current.GetRoles()); httpContext.User = Thread.CurrentPrincipal; } diff --git a/src/Server/OneTrueError.Web/Infrastructure/SignalRAuthenticateAttribute.cs b/src/Server/OneTrueError.Web/Infrastructure/Auth/SignalRAuthenticateAttribute.cs similarity index 100% rename from src/Server/OneTrueError.Web/Infrastructure/SignalRAuthenticateAttribute.cs rename to src/Server/OneTrueError.Web/Infrastructure/Auth/SignalRAuthenticateAttribute.cs diff --git a/src/Server/OneTrueError.Web/Infrastructure/Auth/WebApiAuthenticationFilter.cs b/src/Server/OneTrueError.Web/Infrastructure/Auth/WebApiAuthenticationFilter.cs new file mode 100644 index 00000000..a61991e9 --- /dev/null +++ b/src/Server/OneTrueError.Web/Infrastructure/Auth/WebApiAuthenticationFilter.cs @@ -0,0 +1,46 @@ +using System.Linq; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using System.Web.Http; +using System.Web.Http.Filters; +using OneTrueError.App; +using OneTrueError.Web.Models; + +namespace OneTrueError.Web.Infrastructure.Auth +{ + public class WebApiAuthenticationFilter : IAuthenticationFilter + { + public bool AllowMultiple { get { return true; } } + +#pragma warning disable 1998 + public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken) +#pragma warning restore 1998 + { + //loaded by api key or any other mechanism (but cookies) + if (context.Principal is OneTruePrincipal) + return; + + if (!SessionUser.IsAuthenticated) + { + var attr = context.ActionContext.ControllerContext.Controller.GetType().GetCustomAttribute() + ?? context.ActionContext.ActionDescriptor.GetCustomAttributes().FirstOrDefault(); + if (attr == null) + context.ErrorResult = new AuthenticationFailureResult("Authenticate", context.Request); + + return; + } + + var roles = SessionUser.Current.GetRoles(); + Thread.CurrentPrincipal = new OneTruePrincipal(SessionUser.Current.AccountId, SessionUser.Current.UserName, + roles); + context.Principal = Thread.CurrentPrincipal; + } + +#pragma warning disable 1998 + public async Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken) +#pragma warning restore 1998 + { + } + } +} \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/Infrastructure/OneTrueErrorPrincipal.cs b/src/Server/OneTrueError.Web/Infrastructure/OneTrueErrorPrincipal.cs deleted file mode 100644 index 533b1c57..00000000 --- a/src/Server/OneTrueError.Web/Infrastructure/OneTrueErrorPrincipal.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Security.Principal; - -namespace OneTrueError.Web.Infrastructure -{ - public class OneTrueErrorPrincipal : IPrincipal - { - public OneTrueErrorPrincipal() - { - if (Assigned != null) - Assigned(this, EventArgs.Empty); - } - public int AccountId { get; set; } - public int ApplicationId { get; set; } - - public bool IsInRole(string role) - { - return false; - } - - public IIdentity Identity { get; set; } - - public static event EventHandler Assigned; - } -} \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/Infrastructure/WebApiAuthenticationFilter.cs b/src/Server/OneTrueError.Web/Infrastructure/WebApiAuthenticationFilter.cs index 801bce98..67f32336 100644 --- a/src/Server/OneTrueError.Web/Infrastructure/WebApiAuthenticationFilter.cs +++ b/src/Server/OneTrueError.Web/Infrastructure/WebApiAuthenticationFilter.cs @@ -1,10 +1,16 @@ -using System.Security.Principal; +using System; +using System.Security.Principal; using System.Threading; using System.Threading.Tasks; using System.Web.Http; using System.Web.Http.Filters; using System.Reflection; using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using DotNetCqs; +using OneTrueError.Api.Core.Accounts.Requests; using OneTrueError.Web.Models; namespace OneTrueError.Web.Infrastructure @@ -21,7 +27,17 @@ public async Task AuthenticateAsync(HttpAuthenticationContext context, Cancellat { var attr = context.ActionContext.ControllerContext.Controller.GetType().GetCustomAttribute() ?? context.ActionContext.ActionDescriptor.GetCustomAttributes().FirstOrDefault(); - if (attr == null) + if (attr != null) + { + return; + } + + + //if (TryBasicAuthentication(context)) + //{ + // return; + //} + context.ErrorResult = new AuthenticationFailureResult("Authenticate", context.Request); return; @@ -36,6 +52,49 @@ public async Task AuthenticateAsync(HttpAuthenticationContext context, Cancellat context.Principal = Thread.CurrentPrincipal; } + //private async Task TryBasicAuthentication(HttpAuthenticationContext context) + //{ + // HttpRequestMessage request = context.Request; + // AuthenticationHeaderValue authorization = request.Headers.Authorization; + + // if (authorization == null || authorization.Scheme != "Basic") + // { + // return false; + // } + + // if (string.IsNullOrEmpty(authorization.Parameter)) + // { + // context.ErrorResult = new AuthenticationFailureResult("Missing credentials", request); + // return false; + // } + + // var encoding = Encoding.GetEncoding("iso-8859-1"); + // var credentials = encoding.GetString(Convert.FromBase64String(authorization.Parameter)); + + // int separator = credentials.IndexOf(':'); + // string userName = credentials.Substring(0, separator); + // string password = credentials.Substring(separator + 1); + + // var principal = await AuthenticateUserAsync(userName, password); + // if (principal == null) + // { + // context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request); + // return false; + // } + + // context.Principal = principal; + // return true; + //} + + //private Task AuthenticateUserAsync(string userName, string password) + //{ + // using (var scope = GlobalConfiguration.Configuration.DependencyResolver.BeginScope()) + // { + // var bus = (IRequestReplyBus) scope.GetService(typeof(IRequestReplyBus)); + // await Results = bus.ExecuteAsync(new Login(userName, password)); + // } + //} + #pragma warning disable 1998 public async Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken) #pragma warning restore 1998 diff --git a/src/Server/OneTrueError.Web/Models/SessionUser.cs b/src/Server/OneTrueError.Web/Models/SessionUser.cs index 1fcb87bd..0fd6d14c 100644 --- a/src/Server/OneTrueError.Web/Models/SessionUser.cs +++ b/src/Server/OneTrueError.Web/Models/SessionUser.cs @@ -1,10 +1,13 @@ using System.Collections.Generic; +using System.Linq; using System.Web; namespace OneTrueError.Web.Models { public class SessionUser { + private string[] _roles; + public SessionUser(int accountId, string userName) { AccountId = accountId; @@ -17,8 +20,20 @@ public SessionUser(int accountId, string userName) public string UserName { get; set; } + public string[] GetRoles() + { + if (_roles != null) + return _roles; + + var roles = Applications.Select(x => "Application_" + x.Key).ToList(); + if (AccountId == 1) + roles.Add("Sysadmin"); + _roles = roles.ToArray(); + return _roles; + } #region "Static accessors" + public static bool IsAuthenticated { get { return Current != null; } @@ -35,7 +50,7 @@ public static SessionUser Current set { HttpContext.Current.Session["SessionUser"] = value; } } - public IDictionary Applications { get; set; } + public IDictionary Applications { get; set; } #endregion } diff --git a/src/Server/OneTrueError.Web/OneTrueError.Web.csproj b/src/Server/OneTrueError.Web/OneTrueError.Web.csproj index 447f2b3d..63693b6d 100644 --- a/src/Server/OneTrueError.Web/OneTrueError.Web.csproj +++ b/src/Server/OneTrueError.Web/OneTrueError.Web.csproj @@ -63,8 +63,8 @@ ..\packages\Griffin.Container.Mvc5.1.0.2\lib\net40\Griffin.Container.Mvc5.dll True - - ..\packages\Griffin.Framework.1.0.37\lib\net45\Griffin.Core.dll + + ..\packages\Griffin.Framework.1.0.39\lib\net45\Griffin.Core.dll True @@ -216,6 +216,10 @@ + + + + @@ -255,7 +259,8 @@ - + + @@ -266,15 +271,14 @@ - + - - - + + @@ -381,6 +385,11 @@ + + + + + compilerconfig.json @@ -601,6 +610,10 @@ + + {017F8863-3DE0-4AD2-9ED3-5ACB87BBBCD0} + OneTrueError.Api.Client + {FC331A95-FCA4-4764-8004-0884665DD01F} OneTrueError.Api diff --git a/src/Server/OneTrueError.Web/Scripts/CqsClient.js b/src/Server/OneTrueError.Web/Scripts/CqsClient.js deleted file mode 100644 index 84c750c9..00000000 --- a/src/Server/OneTrueError.Web/Scripts/CqsClient.js +++ /dev/null @@ -1,58 +0,0 @@ -/// -/// -var Griffin; -(function (Griffin) { - var Cqs; - (function (Cqs) { - var CqsClient = (function () { - function CqsClient() { - } - CqsClient.query = function (query) { - var d = P.defer(); - var client = new Griffin.Net.HttpClient(); - client.post(window["API_URL"] + "/api/cqs/?query=" + query.constructor.TYPE_NAME, query, "application/json", null, { 'X-Cqs-Name': query.constructor.TYPE_NAME }) - .done(function (response) { - d.resolve(response.body); - }).fail(function (rejection) { - d.reject(rejection); - }); - return d.promise(); - }; - CqsClient.request = function (query) { - var d = P.defer(); - var client = new Griffin.Net.HttpClient(); - client.post(window["API_URL"] + "/api/cqs/?query=" + query.constructor.TYPE_NAME, query, "application/json", null, { 'X-Cqs-Name': query.constructor.TYPE_NAME }) - .done(function (response) { - d.resolve(response.body); - }).fail(function (rejection) { - d.reject(rejection); - }); - return d.promise(); - }; - CqsClient.event = function (query) { - var d = P.defer(); - var client = new Griffin.Net.HttpClient(); - client.post(window["API_URL"] + "/api/cqs/", query) - .done(function (response) { - d.resolve(response.body); - }).fail(function (rejection) { - d.reject(rejection); - }); - return d.promise(); - }; - CqsClient.command = function (cmd) { - var d = P.defer(); - var client = new Griffin.Net.HttpClient(); - client.post(window["API_URL"] + "/api/cqs/", cmd, "application/json", null, { 'X-Cqs-Name': cmd.constructor.TYPE_NAME }) - .done(function (response) { - d.resolve(response.body); - }).fail(function (rejection) { - d.reject(rejection); - }); - return d.promise(); - }; - return CqsClient; - }()); - Cqs.CqsClient = CqsClient; - })(Cqs = Griffin.Cqs || (Griffin.Cqs = {})); -})(Griffin || (Griffin = {})); diff --git a/src/Server/OneTrueError.Web/Scripts/Griffin.Editor.js b/src/Server/OneTrueError.Web/Scripts/Griffin.Editor.js deleted file mode 100644 index 28d72ea0..00000000 --- a/src/Server/OneTrueError.Web/Scripts/Griffin.Editor.js +++ /dev/null @@ -1,647 +0,0 @@ -var Griffin; -(function (Griffin) { - /** - * The main mother of all editors. - */ - var Editor = (function () { - /** - * Create a new editor - * @param elementOrId either an HTML id (without hash) or a HTMLTextAreaElement. - * @param parser Used to transform markdown to HTML (or another language). - */ - function Editor(elementOrId, parser) { - this.keyMap = {}; - if (typeof elementOrId === "string") { - this.containerElement = document.getElementById(elementOrId); - } - else { - this.containerElement = elementOrId; - } - this.id = this.containerElement.id; - var id = this.containerElement.id; - this.element = (this.containerElement.getElementsByTagName("textarea")[0]); - this.previewElement = document.getElementById(id + "-preview"); - this.toolbarElement = this.containerElement.getElementsByClassName("toolbar")[0]; - this.textSelector = new TextSelector(this.element); - this.toolbarHandler = new MarkdownToolbar(parser); - this.assignAccessKeys(); - if (typeof $().modal == "function") { - this.dialogProvider = new BoostrapDialogs(); - } - else { - this.dialogProvider = new ConfirmDialogs(); - document.getElementById(id + "-imageDialog").style.display = "none"; - document.getElementById(id + "-linkDialog").style.display = "none"; - } - this.bindEvents(); - } - Editor.prototype.trimSpaceInSelection = function () { - var selectedText = this.textSelector.text(); - var pos = this.textSelector.get(); - if (selectedText.substr(selectedText.length - 1, 1) === " ") { - this.textSelector.select(pos.start, pos.end - 1); - } - }; - Editor.prototype.getActionNameFromClass = function (classString) { - var classNames = classString.split(/\s+/); - for (var i = 0; i < classNames.length; i++) { - if (classNames[i].substr(0, 7) === "button-") { - return classNames[i].substr(7); - } - } - return null; - }; - Editor.prototype.assignAccessKeys = function () { - var self = this; - var spans = this.toolbarElement.getElementsByTagName("span"); - var len = spans.length; - for (var i = 0; i < len; i++) { - if (!spans[i].getAttribute("accesskey")) - continue; - var button = spans[i]; - var title = button.getAttribute("title"); - var key = button.getAttribute("accesskey").toUpperCase(); - var actionName = self.getActionNameFromClass(button.className); - button.setAttribute("title", title + " [CTRL+" + key + "]"); - this.keyMap[key] = actionName; - } - }; - Editor.prototype.invokeAutoSize = function () { - if (!this.autoSize) { - return; - } - var twin = $(this).data("twin-area"); - if (typeof twin === "undefined") { - twin = $(''); - twin.appendTo("body"); - //div.appendTo('body'); - $(this).data("twin-area", twin); - $(this).data("originalSize", { - width: this.element.clientWidth, - height: this.element.clientHeight, - //position: data.editor.css('position'), - top: this.getTopPos(this.element), - left: this.getLeftPos(this.element) - }); - } - twin.css("height", this.element.clientHeight); - twin.css("width", this.element.clientWidth); - twin.html(this.element.getAttribute("value") + "some\r\nmore\r\n"); - if (twin[0].clientHeight < twin[0].scrollHeight) { - var style = { - height: (this.element.clientHeight + 100) + "px", - width: this.element.clientWidth, - //position: 'absolute', - top: this.getTopPos(this.element), - left: this.getLeftPos(this.element) - }; - $(this.element).css(style); - $(this).data("expandedSize", style); - } - }; - Editor.prototype.bindEvents = function () { - this.bindToolbarEvents(); - this.bindAccessors(); - this.bindEditorEvents(); - }; - Editor.prototype.bindEditorEvents = function () { - var self = this; - this.element.addEventListener("focus", function (e) { - //grow editor - }); - this.element.addEventListener("blur", function (e) { - //shrink editor - }); - this.element.addEventListener("keyup", function (e) { - self.preview(); - //self.invokeAutoSize(); - }); - this.element.addEventListener("paste", function (e) { - setTimeout(function () { - self.preview(); - }, 100); - }); - }; - Editor.prototype.bindToolbarEvents = function () { - var _this = this; - var spans = this.toolbarElement.getElementsByTagName("span"); - var len = spans.length; - var self = this; - for (var i = 0; i < len; i++) { - if (spans[i].className.indexOf("button") === -1) - continue; - var button = spans[i]; - button.addEventListener("click", function (e) { - var btn = e.target; - if (btn.tagName != "span") { - btn = e.target.parentElement; - } - var actionName = self.getActionNameFromClass(btn.className); - self.invokeAction(actionName); - self.preview(); - return _this; - }); - } - }; - Editor.prototype.bindAccessors = function () { - var _this = this; - var self = this; - //required to override browser keys - document.addEventListener("keydown", function (e) { - if (!e.ctrlKey) - return; - var key = String.fromCharCode(e.which); - if (!key || key.length === 0) - return; - if (e.target !== self.element) - return; - var actionName = _this.keyMap[key]; - if (actionName) { - e.cancelBubble = true; - e.stopPropagation(); - e.preventDefault(); - } - }); - this.element.addEventListener("keyup", function (e) { - if (!e.ctrlKey) - return; - var key = String.fromCharCode(e.which); - if (!key || key.length === 0) - return; - var actionName = _this.keyMap[key]; - if (actionName) { - _this.invokeAction(actionName); - self.preview(); - } - }); - }; - /** - * Invoke a toolbar action - * @param actionName "H1", "B" or similar - */ - Editor.prototype.invokeAction = function (actionName) { - if (!actionName || actionName.length === 0) - throw new Error("ActionName cannot be empty"); - this.trimSpaceInSelection(); - this.toolbarHandler.invokeAction({ - editorElement: this.element, - editor: this, - actionName: actionName, - selection: this.textSelector - }); - }; - Editor.prototype.getTopPos = function (element) { - return element.getBoundingClientRect().top + window.pageYOffset - element.ownerDocument.documentElement.clientTop; - }; - Editor.prototype.getLeftPos = function (element) { - return element.getBoundingClientRect().left + window.pageXOffset - element.ownerDocument.documentElement.clientLeft; - }; - /** - * Update the preview window - */ - Editor.prototype.preview = function () { - var _this = this; - if (this.previewElement == null) { - return; - } - this.toolbarHandler.preview(this, this.previewElement, this.element.value); - if (this.editorTimer) { - clearTimeout(this.editorTimer); - } - if (this.syntaxHighlighter) { - this.editorTimer = setTimeout(function () { - var tags = _this.previewElement.getElementsByTagName("code"); - var inlineBlocks = []; - var codeBlocks = []; - for (var i = 0; i < tags.length; i++) { - var elem = tags[i]; - if (elem.parentElement.tagName === "PRE") { - codeBlocks.push(elem); - } - else { - inlineBlocks.push(elem); - } - } - _this.syntaxHighlighter.highlight(inlineBlocks, codeBlocks); - }, 1000); - } - }; - return Editor; - }()); - Griffin.Editor = Editor; - var ConfirmDialogs = (function () { - function ConfirmDialogs() { - } - ConfirmDialogs.prototype.image = function (context, callback) { - var url = prompt("Enter image URL", context.selection.text()); - setTimeout(function () { - callback({ - href: url, - title: "Enter title here" - }); - }); - }; - ConfirmDialogs.prototype.link = function (context, callback) { - var url = prompt("Enter URL", context.selection.text()); - setTimeout(function () { - callback({ - url: url, - text: "Enter title here" - }); - }); - }; - return ConfirmDialogs; - }()); - Griffin.ConfirmDialogs = ConfirmDialogs; - var BoostrapDialogs = (function () { - function BoostrapDialogs() { - } - BoostrapDialogs.prototype.image = function (context, callback) { - var dialog = $("#" + context.editor.id + "-imageDialog"); - if (!dialog.data("griffin-imageDialog-inited")) { - dialog.data("griffin-imageDialog-inited", true); - $("[data-success]", dialog).click(function () { - dialog.modal("hide"); - callback({ - href: $('[name="imageUrl"]', dialog).val(), - title: $('[name="imageCaption"]', dialog).val() - }); - context.editorElement.focus(); - }); - } - if (context.selection.isSelected()) { - $('[name="imageCaption"]', dialog).val(context.selection.text()); - } - dialog.on("shown.bs.modal", function () { - $('[name="imageUrl"]', dialog).focus(); - }); - dialog.modal({ - show: true - }); - }; - BoostrapDialogs.prototype.link = function (context, callback) { - var dialog = $("#" + context.editor.id + "-linkDialog"); - if (!dialog.data("griffin-linkDialog-inited")) { - dialog.data("griffin-linkDialog-inited", true); - $("[data-success]", dialog).click(function () { - dialog.modal("hide"); - callback({ - url: $('[name="linkUrl"]', dialog).val(), - text: $('[name="linkText"]', dialog).val() - }); - context.editorElement.focus(); - }); - dialog.on("shown.bs.modal", function () { - $('[name="linkUrl"]', dialog).focus(); - }); - dialog.on("hidden.bs.modal", function () { - context.editorElement.focus(); - }); - } - if (context.selection.isSelected()) { - $('[name="linkText"]', dialog).val(context.selection.text()); - } - dialog.modal({ - show: true - }); - }; - return BoostrapDialogs; - }()); - Griffin.BoostrapDialogs = BoostrapDialogs; - var MarkdownToolbar = (function () { - function MarkdownToolbar(parser) { - this.parser = parser; - } - MarkdownToolbar.prototype.invokeAction = function (context) { - // console.log(griffinEditor); - var method = "action" + context.actionName.substr(0, 1).toUpperCase() + context.actionName.substr(1); - if (this[method]) { - var args = []; - args[0] = context.selection; - args[1] = context; - return this[method].apply(this, args); - } - else { - if (typeof alert !== "undefined") { - alert("Missing " + method + " in the active textHandler (griffinEditorExtension)"); - } - } - return this; - }; - MarkdownToolbar.prototype.preview = function (editor, preview, contents) { - if (contents === null || typeof contents === "undefined") { - throw new Error("May not be called without actual content."); - } - preview.innerHTML = this.parser.parse(contents); - }; - MarkdownToolbar.prototype.removeWrapping = function (selection, wrapperString) { - var wrapperLength = wrapperString.length; - var editor = selection.element; - var pos = selection.get(); - // expand double click - if (pos.start !== 0 && editor.value.substr(pos.start - wrapperLength, wrapperLength) === wrapperString) { - selection.select(pos.start - wrapperLength, pos.end + wrapperLength); - pos = selection.get(); - } - // remove - if (selection.text().substr(0, wrapperLength) === wrapperString) { - var text = selection.text().substr(wrapperLength, selection.text().length - (wrapperLength * 2)); - selection.replace(text); - selection.select(pos.start, pos.end - (wrapperLength * 2)); - return true; - } - return false; - }; - MarkdownToolbar.prototype.actionBold = function (selection) { - var isSelected = selection.isSelected(); - var pos = selection.get(); - if (this.removeWrapping(selection, "**")) { - return this; - } - selection.replace("**" + selection.text() + "**"); - if (isSelected) { - selection.select(pos.start, pos.end + 4); - } - else { - selection.select(pos.start + 2, pos.start + 2); - } - return this; - }; - MarkdownToolbar.prototype.actionItalic = function (selection) { - var isSelected = selection.isSelected(); - var pos = selection.get(); - if (this.removeWrapping(selection, "_")) { - return this; - } - selection.replace("_" + selection.text() + "_"); - if (isSelected) { - selection.select(pos.start, pos.end + 2); - } - else { - selection.select(pos.start + 1, pos.start + 1); - } - return this; - }; - MarkdownToolbar.prototype.addTextToBeginningOfLine = function (selection, textToAdd) { - var isSelected = selection.isSelected(); - if (!isSelected) { - var text = selection.element.value; - var orgPos = selection.get().start; - ; - var xStart = selection.get().start; - var found = false; - //find beginning of line so that we can check - //if the text already exists. - while (xStart > 0) { - var ch = text.substr(xStart, 1); - if (ch === "\r" || ch === "\n") { - if (text.substr(xStart + 1, textToAdd.length) === textToAdd) { - selection.select(xStart + 1, textToAdd.length); - selection.replace(""); - } - else { - selection.replace(textToAdd); - } - found = true; - break; - } - xStart = xStart - 1; - } - if (!found) { - if (text.substr(0, textToAdd.length) === textToAdd) { - selection.select(0, textToAdd.length); - selection.replace(""); - } - else { - selection.select(0, 0); - selection.replace(textToAdd); - } - } - selection.moveCursor(orgPos + textToAdd.length); - //selection.select(orgPos, 1); - return; - } - var pos = selection.get(); - selection.replace(textToAdd + selection.text()); - selection.select(pos.end + textToAdd.length, pos.end + textToAdd.length); - }; - MarkdownToolbar.prototype.actionH1 = function (selection) { - this.addTextToBeginningOfLine(selection, "# "); - }; - MarkdownToolbar.prototype.actionH2 = function (selection) { - this.addTextToBeginningOfLine(selection, "## "); - }; - MarkdownToolbar.prototype.actionH3 = function (selection) { - this.addTextToBeginningOfLine(selection, "### "); - }; - MarkdownToolbar.prototype.actionBullets = function (selection) { - var pos = selection.get(); - selection.replace("* " + selection.text()); - selection.select(pos.end + 2, pos.end + 2); - }; - MarkdownToolbar.prototype.actionNumbers = function (selection) { - this.addTextToBeginningOfLine(selection, "1. "); - }; - MarkdownToolbar.prototype.actionSourcecode = function (selection) { - var pos = selection.get(); - if (!selection.isSelected()) { - selection.replace("> "); - selection.select(pos.start + 2, pos.start + 2); - return; - } - if (selection.text().indexOf("\n") === -1) { - selection.replace("`" + selection.text() + "`"); - selection.select(pos.end + 2, pos.end + 2); - return; - } - var text = " " + selection.text().replace(/\n/g, "\n "); - if (text.substr(text.length - 3, 1) === " " && text.substr(text.length - 1, 1) === " ") { - text = text.substr(0, text.length - 4); - } - selection.replace(text); - selection.select(pos.start + text.length, pos.start + text.length); - }; - MarkdownToolbar.prototype.actionQuote = function (selection) { - var pos = selection.get(); - if (!selection.isSelected()) { - selection.replace("> "); - selection.select(pos.start + 2, pos.start + 2); - return; - } - var text = "> " + selection.text().replace(/\n/g, "\n> "); - if (text.substr(text.length - 3, 1) === " ") { - text = text.substr(0, text.length - 4); - } - selection.replace(text); - selection.select(pos.start + text.length, pos.start + text.length); - }; - //context: { url: 'urlToImage' } - MarkdownToolbar.prototype.actionImage = function (selection, context) { - var pos = selection.get(); - var text = selection.text(); - selection.store(); - var options = { - editor: context.editor, - editorElement: context.editorElement, - selection: selection, - href: "", - title: "" - }; - if (!selection.isSelected()) { - options.href = ""; - options.title = ""; - } - else if (text.substr(-4, 4) === ".png" || text.substr(-4, 4) === ".gif" || text.substr(-4, 4) === ".jpg") { - options.href = text; - } - else { - options.title = text; - } - context.editor.dialogProvider.image(options, function (result) { - var newText = "![" + result.title + "](" + result.href + ")"; - selection.load(); - selection.replace(newText); - selection.select(pos.start + newText.length, pos.start + newText.length); - context.editor.preview(); - }); - }; - MarkdownToolbar.prototype.actionLink = function (selection, context) { - var pos = selection.get(); - var text = selection.text(); - selection.store(); - var options = { - editor: context.editor, - editorElement: context.editorElement, - selection: selection, - url: "", - text: "" - }; - if (selection.isSelected()) { - if (text.substr(0, 4) === "http" || text.substr(0, 3) === "www") { - options.url = text; - } - else { - options.text = text; - } - } - context.editor.dialogProvider.link(options, function (result) { - selection.load(); - var newText = "[" + result.text + "](" + result.url + ")"; - selection.replace(newText); - selection.select(pos.start + newText.length, pos.start + newText.length); - context.editor.preview(); - }); - }; - return MarkdownToolbar; - }()); - Griffin.MarkdownToolbar = MarkdownToolbar; - var TextSelector = (function () { - function TextSelector(elementOrId) { - if (typeof elementOrId === "string") { - this.element = document.getElementById(elementOrId); - } - else { - this.element = elementOrId; - } - } - /** @returns object {start: X, end: Y, length: Z} - * x = start character - * y = end character - * length: number of selected characters - */ - TextSelector.prototype.get = function () { - if (typeof this.element.selectionStart !== "undefined") { - return { - start: this.element.selectionStart, - end: this.element.selectionEnd, - length: this.element.selectionEnd - this.element.selectionStart - }; - } - var doc = document; - var range = doc.selection.createRange(); - var storedRange = range.duplicate(); - storedRange.moveToElementText(this.element); - storedRange.setEndPoint("EndToEnd", range); - var start = storedRange.text.length - range.text.length; - var end = start + range.text.length; - return { start: start, end: end, length: range.text.length }; - }; - /** Replace selected text with the specified one */ - TextSelector.prototype.replace = function (newText) { - if (typeof this.element.selectionStart !== "undefined") { - this.element.value = this.element.value.substr(0, this.element.selectionStart) - + newText - + this.element.value.substr(this.element.selectionEnd); - return this; - } - this.element.focus(); - document["selection"].createRange().text = newText; - return this; - }; - /** Store current selection */ - TextSelector.prototype.store = function () { - this.stored = this.get(); - }; - /** load last selection */ - TextSelector.prototype.load = function () { - this.select(this.stored); - }; - /** Selected the specified range - * @param start Start character - * @param end End character - */ - TextSelector.prototype.select = function (startOrSelection, end) { - var start = startOrSelection; - if (typeof startOrSelection.start !== "undefined") { - end = startOrSelection.end; - start = startOrSelection.start; - } - if (typeof this.element.selectionStart == "number") { - this.element.selectionStart = start; - this.element.selectionEnd = end; - } - else if (typeof this.element.setSelectionRange !== "undefined") { - this.element.focus(); - this.element.setSelectionRange(start, end); - } - else if (typeof this.element.createTextRange !== "undefined") { - var range = this.element.createTextRange(); - range.collapse(true); - range.moveEnd("character", end); - range.moveStart("character", start); - range.select(); - } - return this; - }; - /** @returns if anything is selected */ - TextSelector.prototype.isSelected = function () { - return this.get().length !== 0; - }; - /** @returns selected text */ - TextSelector.prototype.text = function () { - if (typeof document["selection"] !== "undefined") { - //elem.focus(); - //console.log(document.selection.createRange().text); - return document["selection"].createRange().text; - } - return this.element.value.substr(this.element.selectionStart, this.element.selectionEnd - this.element.selectionStart); - }; - TextSelector.prototype.moveCursor = function (position) { - if (typeof this.element.selectionStart == "number") { - this.element.selectionStart = position; - } - else if (typeof this.element.setSelectionRange !== "undefined") { - this.element.focus(); - this.element.setSelectionRange(position, 0); - } - else if (typeof this.element.createTextRange !== "undefined") { - var range = this.element.createTextRange(); - range.collapse(true); - range.moveStart("character", position); - range.select(); - } - }; - return TextSelector; - }()); - Griffin.TextSelector = TextSelector; -})(Griffin || (Griffin = {})); diff --git a/src/Server/OneTrueError.Web/Scripts/Griffin.Net.js b/src/Server/OneTrueError.Web/Scripts/Griffin.Net.js deleted file mode 100644 index ffe47973..00000000 --- a/src/Server/OneTrueError.Web/Scripts/Griffin.Net.js +++ /dev/null @@ -1,226 +0,0 @@ -/// -var Griffin; -(function (Griffin) { - var Net; - (function (Net) { - ; - var HttpRequest = (function () { - function HttpRequest(httpMethod, url) { - this.url = url; - this.httpMethod = httpMethod; - this.isAsync = true; - } - return HttpRequest; - }()); - Net.HttpRequest = HttpRequest; - ; - var CorsRequest = (function () { - function CorsRequest() { - } - return CorsRequest; - }()); - Net.CorsRequest = CorsRequest; - var HttpResponse = (function () { - function HttpResponse() { - } - return HttpResponse; - }()); - Net.HttpResponse = HttpResponse; - ; - var HttpRejection = (function () { - function HttpRejection(response) { - this.message = response.statusReason; - this.Reponse = response; - } - return HttpRejection; - }()); - Net.HttpRejection = HttpRejection; - var QueryString = (function () { - function QueryString() { - } - QueryString.parse = function (str) { - str = str.trim().replace(/^(\?|#)/, ''); - if (!str) { - return null; - } - var data = str.trim().split('&').reduce(function (ret, param) { - var parts = param.replace(/\+/g, ' ').split('='); - var key = parts[0]; - var val = parts[1]; - key = decodeURIComponent(key); - val = val === undefined ? null : decodeURIComponent(val); - if (!ret.hasOwnProperty(key)) { - ret[key] = val; - } - else if (Array.isArray(ret[key])) { - ret[key].push(val); - } - else { - ret[key] = [ret[key], val]; - } - return ret; - }, {}); - return data; - }; - QueryString.stringify = function (data) { - return data ? Object.keys(data).map(function (key) { - var val = data[key]; - if (Array.isArray(val)) { - return val.map(function (val2) { return (encodeURIComponent(key) + '=' + encodeURIComponent(val2)); }).join('&'); - } - return encodeURIComponent(key) + '=' + encodeURIComponent(val); - }).join('&') : ''; - }; - return QueryString; - }()); - Net.QueryString = QueryString; - var HttpClient = (function () { - function HttpClient() { - } - HttpClient.prototype.get = function (url, queryString, headers) { - if (queryString === void 0) { queryString = null; } - if (headers === void 0) { headers = null; } - var request = new HttpRequest('GET', url); - if (queryString != null) - request.queryString = queryString; - if (headers != null) { - request.headers = headers; - } - return this.invokeRequest(request); - }; - HttpClient.prototype.post = function (url, body, contentType, queryString, headers) { - if (body === void 0) { body = null; } - if (contentType === void 0) { contentType = 'application/x-www-form-urlencoded'; } - if (queryString === void 0) { queryString = null; } - if (headers === void 0) { headers = null; } - var request = new HttpRequest('POST', url); - if (queryString != null) - request.queryString = queryString; - if (body != null) { - request.body = body; - request.contentType = contentType; - } - if (headers != null) { - request.headers = headers; - } - return this.invokeRequest(request); - }; - HttpClient.prototype.invokeRequest = function (request) { - var _this = this; - var d = P.defer(); - var uri; - if (request.queryString) - if (request.url.indexOf('?') > -1) { - uri = request.url + "&" + QueryString.stringify(request.queryString); - } - else { - uri = request.url + "?" + QueryString.stringify(request.queryString); - } - else - uri = request.url; - var xhr = new XMLHttpRequest(); - xhr.open(request.httpMethod, uri, request.isAsync); - if (request.credentials != null) { - var credentials = Base64.encode(request.credentials.username + ":" + request.credentials.password); - xhr.setRequestHeader("Authorization", "Basic " + credentials); - } - if (request.headers) { - for (var header in request.headers) { - if (header === "Content-Type") - throw "You may not specify 'Content-Type' as a header, use the specific property."; - //if (request.hasOwnProperty(header)) { - xhr.setRequestHeader(header, request.headers[header]); - } - } - if (!request.contentType || request.contentType === '') - request.contentType = "application/x-www-form-urlencoded"; - if (request.body) { - if (request.contentType === 'application/x-www-form-urlencoded') { - if (typeof request.body !== "string") { - request.body = this.urlEncodeObject(request.body); - } - } - else if (request.contentType === 'application/json') { - if (typeof request.body !== "string") { - request.body = JSON.stringify(request.body); - } - } - xhr.setRequestHeader("Content-Type", request.contentType); - } - //xhr.onload = () => { - // var response = this.buildResponse(xhr); - // if (xhr.status >= 200 && xhr.status < 300) { - // d.resolve(response); - // } else { - // d.reject(new HttpRejection(response)); - // } - //}; - xhr.onreadystatechange = function () { - if (xhr.readyState === XMLHttpRequest.DONE) { - var response = _this.buildResponse(xhr); - if (xhr.status >= 200 && xhr.status < 300) { - d.resolve(response); - } - else { - if (xhr.status === 401 && HttpClient.REDIRECT_401_TO) { - window.location.assign(HttpClient.REDIRECT_401_TO + "?ReturnTo=" + encodeURIComponent(window.location.href.replace('#', '&hash='))); - } - d.reject(new HttpRejection(response)); - } - } - }; - xhr.send(request.body); - return d.promise(); - }; - HttpClient.prototype.urlEncodeObject = function (obj, prefix) { - if (prefix === void 0) { prefix = null; } - var str = []; - for (var p in obj) { - if (obj.hasOwnProperty(p)) { - var k = prefix ? prefix + "." + p : p, v = obj[p]; - if (v instanceof Array) { - } - str.push(typeof v == "object" ? - this.urlEncodeObject(v, k) : - encodeURIComponent(k) + "=" + encodeURIComponent(v)); - } - } - return str.join("&"); - }; - HttpClient.prototype.buildResponse = function (xhr) { - var response = new HttpResponse(); - response.statusCode = xhr.status; - response.statusReason = xhr.statusText; - if (xhr.responseBody) { - response.body = xhr.responseBody; - } - else if (xhr.responseXML) { - response.body = xhr.responseXML; - } - else { - response.body = xhr.responseText; - } - response.contentType = xhr.getResponseHeader('content-type'); - if (response.contentType !== null && response.body !== null) { - var pos = response.contentType.indexOf(';'); - if (pos > -1) { - response.charset = response.contentType.substr(pos + 1); - response.contentType = response.contentType.substr(0, pos); - } - if (response.contentType === 'application/json') { - try { - response.body = JSON.parse(response.body); - } - catch (error) { - throw "Failed to parse '" + response.body + '. got: ' + error; - } - } - } - return response; - }; - HttpClient.REDIRECT_401_TO = "/account/login"; - return HttpClient; - }()); - Net.HttpClient = HttpClient; - })(Net = Griffin.Net || (Griffin.Net = {})); -})(Griffin || (Griffin = {})); // ReSharper restore InconsistentNaming diff --git a/src/Server/OneTrueError.Web/Scripts/Griffin.WebApp.js b/src/Server/OneTrueError.Web/Scripts/Griffin.WebApp.js deleted file mode 100644 index abc6d23b..00000000 --- a/src/Server/OneTrueError.Web/Scripts/Griffin.WebApp.js +++ /dev/null @@ -1,366 +0,0 @@ -/// -/// -var Griffin; -(function (Griffin) { - var WebApp; - (function (WebApp) { - var ChangedEventArgs = (function () { - function ChangedEventArgs(model, field, newValue) { - this.model = model; - this.field = field; - this.newValue = newValue; - this.isHandled = true; - } - return ChangedEventArgs; - }()); - WebApp.ChangedEventArgs = ChangedEventArgs; - var ClickEventArgs = (function () { - function ClickEventArgs(model, field, newValue) { - this.model = model; - this.field = field; - this.newValue = newValue; - this.isHandled = true; - } - return ClickEventArgs; - }()); - WebApp.ClickEventArgs = ClickEventArgs; - var FieldModel = (function () { - function FieldModel(propertyName) { - this.propertyName = propertyName; - } - FieldModel.prototype.equalsName = function (name) { - return this.propertyName.toLocaleLowerCase() === name.toLocaleLowerCase(); - }; - FieldModel.prototype.setContent = function (value) { - var elm = this.elem; - if (elm.value === "undefined") { - elm.value = value; - } - else { - this.elem.innerHTML = value; - } - }; - return FieldModel; - }()); - var ViewModel = (function () { - function ViewModel(modelId, viewModel) { - this.jqueryMappings = new Array(); - this.instance = null; - this.id = modelId; - this.instance = viewModel; - for (var fieldName in viewModel) { - var underscorePos = fieldName.indexOf("_"); - if (underscorePos > 0 && typeof viewModel[fieldName] === "function") { - var propertyName = fieldName.substr(0, underscorePos); - var eventName = fieldName.substr(underscorePos + 1); - if (typeof this.jqueryMappings[propertyName] == "undefined") { - this.jqueryMappings[propertyName] = new FieldModel(propertyName); - var elem = this.elem(propertyName, this.id); - if (elem.length === 0) { - if (ViewModel.ENFORCE_MAPPINGS) { - throw "Failed to find child element \"" + propertyName + "\" in model \"" + this.id + "\""; - } - } - else { - this.jqueryMappings[propertyName].elem = elem[0]; - } - } - this.jqueryMappings[propertyName][eventName] = viewModel[fieldName]; - this.mapEvent(propertyName, eventName, fieldName); - } - else if (typeof viewModel[fieldName] !== "function") { - if (fieldName[0] === "_") { - continue; - } - var elem = this.elem(fieldName, this.id); - if (elem.length === 0) { - if (ViewModel.ENFORCE_MAPPINGS) { - throw "Failed to find child element \"" + fieldName + "\" in model \"" + this.id + "\""; - } - continue; - } - if (typeof this.jqueryMappings[fieldName] == "undefined") - this.jqueryMappings[fieldName] = new FieldModel(fieldName); - this.jqueryMappings[fieldName].elem = elem[0]; - } - } - } - ViewModel.prototype.mapChanged = function (elementNameOrId) { - var p = P.defer(); - var elem = elem(elementNameOrId, this.id); - if (elem.length === 0) - throw "Failed to find child element \"" + elementNameOrId + "\" in model \"" + this.id + "\""; - var model = this; - elem.on("changed", function () { - p.resolve(new ChangedEventArgs(model, this, $(this).val())); - }); - return p.promise(); - }; - ViewModel.prototype.bind = function () { - }; - ViewModel.prototype.getField = function (name) { - for (var fieldName in this.jqueryMappings) { - var field = this.jqueryMappings[fieldName]; - if (field.equalsName(name)) - return field; - } - return null; - }; - ViewModel.prototype.update = function (json) { - var model = this; - for (var fieldName in json) { - var field = this.getField(fieldName); - if (field !== null) { - field.setContent(json[fieldName]); - } - } - }; - ViewModel.prototype.elem = function (name, parent) { - if (parent === void 0) { parent = null; } - var searchString = "#" + name + ",[data-name=\"" + name + "\"],[name=\"" + name + "\"]"; - if (parent == null) - return $(searchString); - if (typeof parent === "string") { - return $(searchString, $("#" + parent)); - } - return $(searchString, parent); - }; - ViewModel.prototype.mapEvent = function (propertyName, eventName, fieldName) { - var elem = this.elem(propertyName, this.id); - if (elem.length === 0) - throw "Failed to find child element \"" + propertyName + "\" in model \"" + this.id + "\" for event \"" + eventName + "'."; - var binder = this; - if (eventName === "change" || eventName === "changed") { - elem.on("change", function (e) { - var args = new ChangedEventArgs(binder.instance, this, $(this).val()); - binder.jqueryMappings[propertyName][eventName].apply(binder.instance, [args]); - if (args.isHandled) { - e.preventDefault(); - } - }); - } - else if (eventName === "click" || eventName === "clicked") { - elem.on("click", function (e) { - var value = ""; - if (this.tagName == "A") { - value = this.getAttribute("href"); - } - else { - value = $(this).val(); - } - var args = new ClickEventArgs(binder.instance, this, value); - binder.jqueryMappings[propertyName][eventName].apply(binder.instance, [args]); - if (args.isHandled) { - e.preventDefault(); - } - }); - } - }; - ViewModel.ENFORCE_MAPPINGS = false; - return ViewModel; - }()); - WebApp.ViewModel = ViewModel; - var Carburator = (function () { - function Carburator() { - } - Carburator.mapRoute = function (elementNameOrId, viewModel) { - return new ViewModel(elementNameOrId, viewModel); - }; - return Carburator; - }()); - WebApp.Carburator = Carburator; - var PagerPage = (function () { - function PagerPage(pageNumber, selected) { - this.pageNumber = pageNumber; - this.selected = selected; - } - PagerPage.prototype.select = function () { - this.listItem.firstElementChild.setAttribute("class", "number " + Pager.BTN_ACTIVE_CLASS); - this.selected = true; - }; - PagerPage.prototype.deselect = function () { - this.listItem.firstElementChild.setAttribute("class", "number " + Pager.BTN_CLASS); - this.selected = true; - }; - return PagerPage; - }()); - WebApp.PagerPage = PagerPage; - var Pager = (function () { - function Pager(currentPage, pageSize, totalNumberOfItems) { - this.currentPage = currentPage; - this.pageSize = pageSize; - this.totalNumberOfItems = totalNumberOfItems; - this.pageCount = 0; - this.pages = new Array(); - this._subscribers = new Array(); - this.update(currentPage, pageSize, totalNumberOfItems); - } - Pager.prototype.update = function (currentPage, pageSize, totalNumberOfItems) { - console.log(currentPage, pageSize, totalNumberOfItems); - if (totalNumberOfItems < pageSize || pageSize === 0 || totalNumberOfItems === 0) { - this.pageCount = 0; - this.pages = []; - if (this.parent) { - this.draw(this.parent); - } - return; - } - var isFirstUpdate = this.totalNumberOfItems === 0; - this.pageCount = Math.ceil(totalNumberOfItems / pageSize); - this.currentPage = currentPage; - this.totalNumberOfItems = totalNumberOfItems; - this.pageSize = pageSize; - var i = 1; - this.pages = new Array(); - for (i = 1; i <= this.pageCount; i++) - this.pages.push(new PagerPage(i, i === currentPage)); - if (this.parent) { - this.draw(this.parent); - } - if (!isFirstUpdate) { - this.notify(); - } - }; - Pager.prototype.subscribe = function (subscriber) { - this._subscribers.push(subscriber); - }; - Pager.prototype.moveNext = function () { - if (this.currentPage < this.pageCount) { - this.pages[this.currentPage - 1].deselect(); - this.currentPage += 1; - this.pages[this.currentPage - 1].select(); - if (this.currentPage === this.pageCount) { - this.nextItem.style.display = "none"; - } - this.prevItem.style.display = ""; - this.notify(); - } - }; - Pager.prototype.movePrevious = function () { - if (this.currentPage > 1) { - this.pages[this.currentPage - 1].deselect(); - this.currentPage -= 1; - this.pages[this.currentPage - 1].select(); - if (this.currentPage === 1) { - this.prevItem.style.display = "none"; - } - else { - } - this.nextItem.style.display = ""; - this.notify(); - } - }; - Pager.prototype.goto = function (pageNumber) { - this.pages[this.currentPage - 1].deselect(); - this.currentPage = pageNumber; - this.pages[this.currentPage - 1].select(); - if (this.currentPage === 1 || this.pageCount === 1) { - this.prevItem.style.display = "none"; - } - else { - this.prevItem.style.display = ""; - } - if (this.currentPage === this.pageCount || this.pageCount === 1) { - this.nextItem.style.display = "none"; - } - else { - this.nextItem.style.display = ""; - } - this.notify(); - }; - Pager.prototype.createListItem = function (title, callback) { - var btn = document.createElement("button"); - btn.innerHTML = title; - btn.className = Pager.BTN_CLASS; - btn.addEventListener("click", function (e) { - e.preventDefault(); - callback(); - }); - var li = document.createElement("li"); - li.appendChild(btn); - return li; - }; - Pager.prototype.deactivateAll = function () { - this.prevItem.firstElementChild.setAttribute("class", Pager.BTN_CLASS); - this.nextItem.firstElementChild.setAttribute("class", Pager.BTN_CLASS); - this.pages.forEach(function (item) { - item.selected = false; - item.listItem.firstElementChild.setAttribute("class", Pager.BTN_CLASS); - }); - }; - Pager.prototype.draw = function (containerIdOrElement) { - var _this = this; - if (typeof containerIdOrElement === "string") { - this.parent = document.getElementById(containerIdOrElement); - if (!this.parent) - throw new Error("Failed to find '" + containerIdOrElement + "'"); - } - else { - if (!containerIdOrElement) - throw new Error("No element was specified"); - this.parent = containerIdOrElement; - } - var self = this; - var ul = document.createElement("ul"); - //prev - var li = this.createListItem("<< Previous", function () { - self.movePrevious(); - }); - ul.appendChild(li); - this.prevItem = li; - if (this.currentPage <= 1 || this.pageCount <= 1) { - this.prevItem.style.display = "none"; - } - else { - this.prevItem.style.display = ""; - } - //pages - this.pages.forEach(function (item) { - var li = _this.createListItem(item.pageNumber.toString(), function () { - self.goto(item.pageNumber); - }); - item.listItem = li; - ul.appendChild(li); - if (item.selected) { - li.className = "active"; - li.firstElementChild.setAttribute("class", "number " + Pager.BTN_ACTIVE_CLASS); - } - }); - //next - var li = this.createListItem("Next >>", function () { - self.moveNext(); - }); - ul.appendChild(li); - this.nextItem = li; - if (this.currentPage >= this.pageCount || this.pageCount <= 1) { - this.nextItem.style.display = "none"; - } - else { - this.nextItem.style.display = ""; - } - ul.className = "pager"; - while (this.parent.firstChild) { - this.parent.removeChild(this.parent.firstChild); - } - this.parent.appendChild(ul); - }; - Pager.prototype.notify = function () { - var self = this; - this._subscribers.forEach(function (item) { - item.onPager.apply(item, [self]); - }); - }; - Pager.prototype.reset = function () { - this.pageCount = 0; - this.pages = []; - if (this.parent) { - this.draw(this.parent); - } - }; - Pager.BTN_ACTIVE_CLASS = "btn btn-success"; - Pager.BTN_CLASS = "btn"; - return Pager; - }()); - WebApp.Pager = Pager; - })(WebApp = Griffin.WebApp || (Griffin.WebApp = {})); -})(Griffin || (Griffin = {})); diff --git a/src/Server/OneTrueError.Web/Scripts/Models/AllModels.js b/src/Server/OneTrueError.Web/Scripts/Models/AllModels.js deleted file mode 100644 index c2da3153..00000000 --- a/src/Server/OneTrueError.Web/Scripts/Models/AllModels.js +++ /dev/null @@ -1,1396 +0,0 @@ -var OneTrueError; -(function (OneTrueError) { - var Web; - (function (Web) { - var Overview; - (function (Overview) { - var Queries; - (function (Queries) { - var GetOverview = (function () { - function GetOverview() { - } - GetOverview.TYPE_NAME = 'GetOverview'; - return GetOverview; - }()); - Queries.GetOverview = GetOverview; - var GetOverviewApplicationResult = (function () { - function GetOverviewApplicationResult(label, startDate, days) { - this.Label = label; - } - GetOverviewApplicationResult.TYPE_NAME = 'GetOverviewApplicationResult'; - return GetOverviewApplicationResult; - }()); - Queries.GetOverviewApplicationResult = GetOverviewApplicationResult; - var GetOverviewResult = (function () { - function GetOverviewResult() { - } - GetOverviewResult.TYPE_NAME = 'GetOverviewResult'; - return GetOverviewResult; - }()); - Queries.GetOverviewResult = GetOverviewResult; - var OverviewStatSummary = (function () { - function OverviewStatSummary() { - } - OverviewStatSummary.TYPE_NAME = 'OverviewStatSummary'; - return OverviewStatSummary; - }()); - Queries.OverviewStatSummary = OverviewStatSummary; - })(Queries = Overview.Queries || (Overview.Queries = {})); - })(Overview = Web.Overview || (Web.Overview = {})); - })(Web = OneTrueError.Web || (OneTrueError.Web = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Web; - (function (Web) { - var Feedback; - (function (Feedback) { - var Queries; - (function (Queries) { - var GetFeedbackForApplicationPage = (function () { - function GetFeedbackForApplicationPage(applicationId) { - this.ApplicationId = applicationId; - } - GetFeedbackForApplicationPage.TYPE_NAME = 'GetFeedbackForApplicationPage'; - return GetFeedbackForApplicationPage; - }()); - Queries.GetFeedbackForApplicationPage = GetFeedbackForApplicationPage; - var GetFeedbackForApplicationPageResult = (function () { - function GetFeedbackForApplicationPageResult() { - } - GetFeedbackForApplicationPageResult.TYPE_NAME = 'GetFeedbackForApplicationPageResult'; - return GetFeedbackForApplicationPageResult; - }()); - Queries.GetFeedbackForApplicationPageResult = GetFeedbackForApplicationPageResult; - var GetFeedbackForApplicationPageResultItem = (function () { - function GetFeedbackForApplicationPageResultItem() { - } - GetFeedbackForApplicationPageResultItem.TYPE_NAME = 'GetFeedbackForApplicationPageResultItem'; - return GetFeedbackForApplicationPageResultItem; - }()); - Queries.GetFeedbackForApplicationPageResultItem = GetFeedbackForApplicationPageResultItem; - var GetIncidentFeedback = (function () { - function GetIncidentFeedback(incidentId) { - this.IncidentId = incidentId; - } - GetIncidentFeedback.TYPE_NAME = 'GetIncidentFeedback'; - return GetIncidentFeedback; - }()); - Queries.GetIncidentFeedback = GetIncidentFeedback; - var GetIncidentFeedbackResult = (function () { - function GetIncidentFeedbackResult(items, emails) { - this.Items = items; - this.Emails = emails; - } - GetIncidentFeedbackResult.TYPE_NAME = 'GetIncidentFeedbackResult'; - return GetIncidentFeedbackResult; - }()); - Queries.GetIncidentFeedbackResult = GetIncidentFeedbackResult; - var GetIncidentFeedbackResultItem = (function () { - function GetIncidentFeedbackResultItem() { - } - GetIncidentFeedbackResultItem.TYPE_NAME = 'GetIncidentFeedbackResultItem'; - return GetIncidentFeedbackResultItem; - }()); - Queries.GetIncidentFeedbackResultItem = GetIncidentFeedbackResultItem; - var GetFeedbackForDashboardPage = (function () { - function GetFeedbackForDashboardPage() { - } - GetFeedbackForDashboardPage.TYPE_NAME = 'GetFeedbackForDashboardPage'; - return GetFeedbackForDashboardPage; - }()); - Queries.GetFeedbackForDashboardPage = GetFeedbackForDashboardPage; - var GetFeedbackForDashboardPageResult = (function () { - function GetFeedbackForDashboardPageResult() { - } - GetFeedbackForDashboardPageResult.TYPE_NAME = 'GetFeedbackForDashboardPageResult'; - return GetFeedbackForDashboardPageResult; - }()); - Queries.GetFeedbackForDashboardPageResult = GetFeedbackForDashboardPageResult; - var GetFeedbackForDashboardPageResultItem = (function () { - function GetFeedbackForDashboardPageResultItem() { - } - GetFeedbackForDashboardPageResultItem.TYPE_NAME = 'GetFeedbackForDashboardPageResultItem'; - return GetFeedbackForDashboardPageResultItem; - }()); - Queries.GetFeedbackForDashboardPageResultItem = GetFeedbackForDashboardPageResultItem; - })(Queries = Feedback.Queries || (Feedback.Queries = {})); - })(Feedback = Web.Feedback || (Web.Feedback = {})); - })(Web = OneTrueError.Web || (OneTrueError.Web = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Modules; - (function (Modules) { - var Triggers; - (function (Triggers) { - (function (LastTriggerActionDTO) { - LastTriggerActionDTO[LastTriggerActionDTO["ExecuteActions"] = 0] = "ExecuteActions"; - LastTriggerActionDTO[LastTriggerActionDTO["AbortTrigger"] = 1] = "AbortTrigger"; - })(Triggers.LastTriggerActionDTO || (Triggers.LastTriggerActionDTO = {})); - var LastTriggerActionDTO = Triggers.LastTriggerActionDTO; - var TriggerActionDataDTO = (function () { - function TriggerActionDataDTO() { - } - TriggerActionDataDTO.TYPE_NAME = 'TriggerActionDataDTO'; - return TriggerActionDataDTO; - }()); - Triggers.TriggerActionDataDTO = TriggerActionDataDTO; - var TriggerContextRule = (function () { - function TriggerContextRule() { - } - TriggerContextRule.TYPE_NAME = 'TriggerContextRule'; - return TriggerContextRule; - }()); - Triggers.TriggerContextRule = TriggerContextRule; - var TriggerExceptionRule = (function () { - function TriggerExceptionRule() { - } - TriggerExceptionRule.TYPE_NAME = 'TriggerExceptionRule'; - return TriggerExceptionRule; - }()); - Triggers.TriggerExceptionRule = TriggerExceptionRule; - (function (TriggerFilterCondition) { - TriggerFilterCondition[TriggerFilterCondition["StartsWith"] = 0] = "StartsWith"; - TriggerFilterCondition[TriggerFilterCondition["EndsWith"] = 1] = "EndsWith"; - TriggerFilterCondition[TriggerFilterCondition["Contains"] = 2] = "Contains"; - TriggerFilterCondition[TriggerFilterCondition["DoNotContain"] = 3] = "DoNotContain"; - TriggerFilterCondition[TriggerFilterCondition["Equals"] = 4] = "Equals"; - })(Triggers.TriggerFilterCondition || (Triggers.TriggerFilterCondition = {})); - var TriggerFilterCondition = Triggers.TriggerFilterCondition; - var TriggerDTO = (function () { - function TriggerDTO() { - } - TriggerDTO.TYPE_NAME = 'TriggerDTO'; - return TriggerDTO; - }()); - Triggers.TriggerDTO = TriggerDTO; - (function (TriggerRuleAction) { - TriggerRuleAction[TriggerRuleAction["AbortTrigger"] = 0] = "AbortTrigger"; - TriggerRuleAction[TriggerRuleAction["ContinueWithNextRule"] = 1] = "ContinueWithNextRule"; - TriggerRuleAction[TriggerRuleAction["ExecuteActions"] = 2] = "ExecuteActions"; - })(Triggers.TriggerRuleAction || (Triggers.TriggerRuleAction = {})); - var TriggerRuleAction = Triggers.TriggerRuleAction; - var TriggerRuleBase = (function () { - function TriggerRuleBase() { - } - TriggerRuleBase.TYPE_NAME = 'TriggerRuleBase'; - return TriggerRuleBase; - }()); - Triggers.TriggerRuleBase = TriggerRuleBase; - })(Triggers = Modules.Triggers || (Modules.Triggers = {})); - })(Modules = OneTrueError.Modules || (OneTrueError.Modules = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Modules; - (function (Modules) { - var Triggers; - (function (Triggers) { - var Queries; - (function (Queries) { - var GetContextCollectionMetadata = (function () { - function GetContextCollectionMetadata(applicationId) { - this.ApplicationId = applicationId; - } - GetContextCollectionMetadata.TYPE_NAME = 'GetContextCollectionMetadata'; - return GetContextCollectionMetadata; - }()); - Queries.GetContextCollectionMetadata = GetContextCollectionMetadata; - var GetContextCollectionMetadataItem = (function () { - function GetContextCollectionMetadataItem() { - } - GetContextCollectionMetadataItem.TYPE_NAME = 'GetContextCollectionMetadataItem'; - return GetContextCollectionMetadataItem; - }()); - Queries.GetContextCollectionMetadataItem = GetContextCollectionMetadataItem; - var GetTrigger = (function () { - function GetTrigger(id) { - this.Id = id; - } - GetTrigger.TYPE_NAME = 'GetTrigger'; - return GetTrigger; - }()); - Queries.GetTrigger = GetTrigger; - var GetTriggerDTO = (function () { - function GetTriggerDTO() { - } - GetTriggerDTO.TYPE_NAME = 'GetTriggerDTO'; - return GetTriggerDTO; - }()); - Queries.GetTriggerDTO = GetTriggerDTO; - var GetTriggersForApplication = (function () { - function GetTriggersForApplication(applicationId) { - this.ApplicationId = applicationId; - } - GetTriggersForApplication.TYPE_NAME = 'GetTriggersForApplication'; - return GetTriggersForApplication; - }()); - Queries.GetTriggersForApplication = GetTriggersForApplication; - })(Queries = Triggers.Queries || (Triggers.Queries = {})); - })(Triggers = Modules.Triggers || (Modules.Triggers = {})); - })(Modules = OneTrueError.Modules || (OneTrueError.Modules = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Modules; - (function (Modules) { - var Triggers; - (function (Triggers) { - var Commands; - (function (Commands) { - var CreateTrigger = (function () { - function CreateTrigger(applicationId, name) { - this.ApplicationId = applicationId; - this.Name = name; - } - CreateTrigger.TYPE_NAME = 'CreateTrigger'; - return CreateTrigger; - }()); - Commands.CreateTrigger = CreateTrigger; - var DeleteTrigger = (function () { - function DeleteTrigger(id) { - this.Id = id; - } - DeleteTrigger.TYPE_NAME = 'DeleteTrigger'; - return DeleteTrigger; - }()); - Commands.DeleteTrigger = DeleteTrigger; - var UpdateTrigger = (function () { - function UpdateTrigger(id, name) { - this.Id = id; - this.Name = name; - } - UpdateTrigger.TYPE_NAME = 'UpdateTrigger'; - return UpdateTrigger; - }()); - Commands.UpdateTrigger = UpdateTrigger; - })(Commands = Triggers.Commands || (Triggers.Commands = {})); - })(Triggers = Modules.Triggers || (Modules.Triggers = {})); - })(Modules = OneTrueError.Modules || (OneTrueError.Modules = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Modules; - (function (Modules) { - var Tagging; - (function (Tagging) { - var TagDTO = (function () { - function TagDTO() { - } - TagDTO.TYPE_NAME = 'TagDTO'; - return TagDTO; - }()); - Tagging.TagDTO = TagDTO; - })(Tagging = Modules.Tagging || (Modules.Tagging = {})); - })(Modules = OneTrueError.Modules || (OneTrueError.Modules = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Modules; - (function (Modules) { - var Tagging; - (function (Tagging) { - var Queries; - (function (Queries) { - var GetTagsForIncident = (function () { - function GetTagsForIncident(incidentId) { - this.IncidentId = incidentId; - } - GetTagsForIncident.TYPE_NAME = 'GetTagsForIncident'; - return GetTagsForIncident; - }()); - Queries.GetTagsForIncident = GetTagsForIncident; - })(Queries = Tagging.Queries || (Tagging.Queries = {})); - })(Tagging = Modules.Tagging || (Modules.Tagging = {})); - })(Modules = OneTrueError.Modules || (OneTrueError.Modules = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Modules; - (function (Modules) { - var Tagging; - (function (Tagging) { - var Events; - (function (Events) { - var TagAttachedToIncident = (function () { - function TagAttachedToIncident(incidentId, tags) { - this.IncidentId = incidentId; - this.Tags = tags; - } - TagAttachedToIncident.TYPE_NAME = 'TagAttachedToIncident'; - return TagAttachedToIncident; - }()); - Events.TagAttachedToIncident = TagAttachedToIncident; - })(Events = Tagging.Events || (Tagging.Events = {})); - })(Tagging = Modules.Tagging || (Modules.Tagging = {})); - })(Modules = OneTrueError.Modules || (OneTrueError.Modules = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Modules; - (function (Modules) { - var ContextData; - (function (ContextData) { - var Queries; - (function (Queries) { - var GetSimilarities = (function () { - function GetSimilarities(incidentId) { - this.IncidentId = incidentId; - } - GetSimilarities.TYPE_NAME = 'GetSimilarities'; - return GetSimilarities; - }()); - Queries.GetSimilarities = GetSimilarities; - var GetSimilaritiesCollection = (function () { - function GetSimilaritiesCollection() { - } - GetSimilaritiesCollection.TYPE_NAME = 'GetSimilaritiesCollection'; - return GetSimilaritiesCollection; - }()); - Queries.GetSimilaritiesCollection = GetSimilaritiesCollection; - var GetSimilaritiesResult = (function () { - function GetSimilaritiesResult() { - } - GetSimilaritiesResult.TYPE_NAME = 'GetSimilaritiesResult'; - return GetSimilaritiesResult; - }()); - Queries.GetSimilaritiesResult = GetSimilaritiesResult; - var GetSimilaritiesSimilarity = (function () { - function GetSimilaritiesSimilarity(name) { - this.Name = name; - } - GetSimilaritiesSimilarity.TYPE_NAME = 'GetSimilaritiesSimilarity'; - return GetSimilaritiesSimilarity; - }()); - Queries.GetSimilaritiesSimilarity = GetSimilaritiesSimilarity; - var GetSimilaritiesValue = (function () { - function GetSimilaritiesValue(value, percentage, count) { - this.Value = value; - this.Percentage = percentage; - this.Count = count; - } - GetSimilaritiesValue.TYPE_NAME = 'GetSimilaritiesValue'; - return GetSimilaritiesValue; - }()); - Queries.GetSimilaritiesValue = GetSimilaritiesValue; - })(Queries = ContextData.Queries || (ContextData.Queries = {})); - })(ContextData = Modules.ContextData || (Modules.ContextData = {})); - })(Modules = OneTrueError.Modules || (OneTrueError.Modules = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Modules; - (function (Modules) { - var ErrorOrigins; - (function (ErrorOrigins) { - var Queries; - (function (Queries) { - var GetOriginsForIncident = (function () { - function GetOriginsForIncident(incidentId) { - this.IncidentId = incidentId; - } - GetOriginsForIncident.TYPE_NAME = 'GetOriginsForIncident'; - return GetOriginsForIncident; - }()); - Queries.GetOriginsForIncident = GetOriginsForIncident; - var GetOriginsForIncidentResult = (function () { - function GetOriginsForIncidentResult() { - } - GetOriginsForIncidentResult.TYPE_NAME = 'GetOriginsForIncidentResult'; - return GetOriginsForIncidentResult; - }()); - Queries.GetOriginsForIncidentResult = GetOriginsForIncidentResult; - var GetOriginsForIncidentResultItem = (function () { - function GetOriginsForIncidentResultItem() { - } - GetOriginsForIncidentResultItem.TYPE_NAME = 'GetOriginsForIncidentResultItem'; - return GetOriginsForIncidentResultItem; - }()); - Queries.GetOriginsForIncidentResultItem = GetOriginsForIncidentResultItem; - })(Queries = ErrorOrigins.Queries || (ErrorOrigins.Queries = {})); - })(ErrorOrigins = Modules.ErrorOrigins || (Modules.ErrorOrigins = {})); - })(Modules = OneTrueError.Modules || (OneTrueError.Modules = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var IgnoreFieldAttribute = (function () { - function IgnoreFieldAttribute() { - } - IgnoreFieldAttribute.TYPE_NAME = 'IgnoreFieldAttribute'; - return IgnoreFieldAttribute; - }()); - Core.IgnoreFieldAttribute = IgnoreFieldAttribute; - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Users; - (function (Users) { - var NotificationSettings = (function () { - function NotificationSettings() { - } - NotificationSettings.TYPE_NAME = 'NotificationSettings'; - return NotificationSettings; - }()); - Users.NotificationSettings = NotificationSettings; - (function (NotificationState) { - NotificationState[NotificationState["UseGlobalSetting"] = 0] = "UseGlobalSetting"; - NotificationState[NotificationState["Disabled"] = 1] = "Disabled"; - NotificationState[NotificationState["Cellphone"] = 2] = "Cellphone"; - NotificationState[NotificationState["Email"] = 3] = "Email"; - })(Users.NotificationState || (Users.NotificationState = {})); - var NotificationState = Users.NotificationState; - })(Users = Core.Users || (Core.Users = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Users; - (function (Users) { - var Queries; - (function (Queries) { - var GetUserSettings = (function () { - function GetUserSettings() { - } - GetUserSettings.TYPE_NAME = 'GetUserSettings'; - return GetUserSettings; - }()); - Queries.GetUserSettings = GetUserSettings; - var GetUserSettingsResult = (function () { - function GetUserSettingsResult() { - } - GetUserSettingsResult.TYPE_NAME = 'GetUserSettingsResult'; - return GetUserSettingsResult; - }()); - Queries.GetUserSettingsResult = GetUserSettingsResult; - })(Queries = Users.Queries || (Users.Queries = {})); - })(Users = Core.Users || (Core.Users = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Users; - (function (Users) { - var Commands; - (function (Commands) { - var UpdateNotifications = (function () { - function UpdateNotifications() { - } - UpdateNotifications.TYPE_NAME = 'UpdateNotifications'; - return UpdateNotifications; - }()); - Commands.UpdateNotifications = UpdateNotifications; - var UpdatePersonalSettings = (function () { - function UpdatePersonalSettings() { - } - UpdatePersonalSettings.TYPE_NAME = 'UpdatePersonalSettings'; - return UpdatePersonalSettings; - }()); - Commands.UpdatePersonalSettings = UpdatePersonalSettings; - })(Commands = Users.Commands || (Users.Commands = {})); - })(Users = Core.Users || (Core.Users = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Support; - (function (Support) { - var SendSupportRequest = (function () { - function SendSupportRequest() { - } - SendSupportRequest.TYPE_NAME = 'SendSupportRequest'; - return SendSupportRequest; - }()); - Support.SendSupportRequest = SendSupportRequest; - })(Support = Core.Support || (Core.Support = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Reports; - (function (Reports) { - var ContextCollectionDTO = (function () { - function ContextCollectionDTO(name, items) { - this.Name = name; - } - ContextCollectionDTO.TYPE_NAME = 'ContextCollectionDTO'; - return ContextCollectionDTO; - }()); - Reports.ContextCollectionDTO = ContextCollectionDTO; - var ReportDTO = (function () { - function ReportDTO() { - } - ReportDTO.TYPE_NAME = 'ReportDTO'; - return ReportDTO; - }()); - Reports.ReportDTO = ReportDTO; - var ReportExeptionDTO = (function () { - function ReportExeptionDTO() { - } - ReportExeptionDTO.TYPE_NAME = 'ReportExeptionDTO'; - return ReportExeptionDTO; - }()); - Reports.ReportExeptionDTO = ReportExeptionDTO; - })(Reports = Core.Reports || (Core.Reports = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Reports; - (function (Reports) { - var Queries; - (function (Queries) { - var GetReport = (function () { - function GetReport(reportId) { - this.ReportId = reportId; - } - GetReport.TYPE_NAME = 'GetReport'; - return GetReport; - }()); - Queries.GetReport = GetReport; - var GetReportException = (function () { - function GetReportException() { - } - GetReportException.TYPE_NAME = 'GetReportException'; - return GetReportException; - }()); - Queries.GetReportException = GetReportException; - var GetReportList = (function () { - function GetReportList(incidentId) { - this.IncidentId = incidentId; - } - GetReportList.TYPE_NAME = 'GetReportList'; - return GetReportList; - }()); - Queries.GetReportList = GetReportList; - var GetReportListResult = (function () { - function GetReportListResult(items) { - this.Items = items; - } - GetReportListResult.TYPE_NAME = 'GetReportListResult'; - return GetReportListResult; - }()); - Queries.GetReportListResult = GetReportListResult; - var GetReportListResultItem = (function () { - function GetReportListResultItem() { - } - GetReportListResultItem.TYPE_NAME = 'GetReportListResultItem'; - return GetReportListResultItem; - }()); - Queries.GetReportListResultItem = GetReportListResultItem; - var GetReportResult = (function () { - function GetReportResult() { - } - GetReportResult.TYPE_NAME = 'GetReportResult'; - return GetReportResult; - }()); - Queries.GetReportResult = GetReportResult; - var GetReportResultContextCollection = (function () { - function GetReportResultContextCollection(name, properties) { - this.Name = name; - this.Properties = properties; - } - GetReportResultContextCollection.TYPE_NAME = 'GetReportResultContextCollection'; - return GetReportResultContextCollection; - }()); - Queries.GetReportResultContextCollection = GetReportResultContextCollection; - var KeyValuePair = (function () { - function KeyValuePair(key, value) { - this.Key = key; - this.Value = value; - } - KeyValuePair.TYPE_NAME = 'KeyValuePair'; - return KeyValuePair; - }()); - Queries.KeyValuePair = KeyValuePair; - })(Queries = Reports.Queries || (Reports.Queries = {})); - })(Reports = Core.Reports || (Core.Reports = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Messaging; - (function (Messaging) { - var EmailAddress = (function () { - function EmailAddress(address) { - this.Address = address; - } - EmailAddress.TYPE_NAME = 'EmailAddress'; - return EmailAddress; - }()); - Messaging.EmailAddress = EmailAddress; - var EmailMessage = (function () { - function EmailMessage() { - } - EmailMessage.TYPE_NAME = 'EmailMessage'; - return EmailMessage; - }()); - Messaging.EmailMessage = EmailMessage; - var EmailResource = (function () { - function EmailResource(name, content) { - this.Name = name; - this.Content = content; - } - EmailResource.TYPE_NAME = 'EmailResource'; - return EmailResource; - }()); - Messaging.EmailResource = EmailResource; - })(Messaging = Core.Messaging || (Core.Messaging = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Messaging; - (function (Messaging) { - var Commands; - (function (Commands) { - var SendEmail = (function () { - function SendEmail() { - } - SendEmail.TYPE_NAME = 'SendEmail'; - return SendEmail; - }()); - Commands.SendEmail = SendEmail; - var SendTemplateEmail = (function () { - function SendTemplateEmail(mailTitle, templateName) { - this.MailTitle = mailTitle; - this.TemplateName = templateName; - } - SendTemplateEmail.TYPE_NAME = 'SendTemplateEmail'; - return SendTemplateEmail; - }()); - Commands.SendTemplateEmail = SendTemplateEmail; - })(Commands = Messaging.Commands || (Messaging.Commands = {})); - })(Messaging = Core.Messaging || (Core.Messaging = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Invitations; - (function (Invitations) { - var Queries; - (function (Queries) { - var GetInvitationByKey = (function () { - function GetInvitationByKey(invitationKey) { - this.InvitationKey = invitationKey; - } - GetInvitationByKey.TYPE_NAME = 'GetInvitationByKey'; - return GetInvitationByKey; - }()); - Queries.GetInvitationByKey = GetInvitationByKey; - var GetInvitationByKeyResult = (function () { - function GetInvitationByKeyResult() { - } - GetInvitationByKeyResult.TYPE_NAME = 'GetInvitationByKeyResult'; - return GetInvitationByKeyResult; - }()); - Queries.GetInvitationByKeyResult = GetInvitationByKeyResult; - })(Queries = Invitations.Queries || (Invitations.Queries = {})); - })(Invitations = Core.Invitations || (Core.Invitations = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Invitations; - (function (Invitations) { - var Commands; - (function (Commands) { - var InviteUser = (function () { - function InviteUser(applicationId, emailAddress) { - this.ApplicationId = applicationId; - this.EmailAddress = emailAddress; - } - InviteUser.TYPE_NAME = 'InviteUser'; - return InviteUser; - }()); - Commands.InviteUser = InviteUser; - })(Commands = Invitations.Commands || (Invitations.Commands = {})); - })(Invitations = Core.Invitations || (Core.Invitations = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Incidents; - (function (Incidents) { - (function (IncidentOrder) { - IncidentOrder[IncidentOrder["Newest"] = 0] = "Newest"; - IncidentOrder[IncidentOrder["MostReports"] = 1] = "MostReports"; - IncidentOrder[IncidentOrder["MostFeedback"] = 2] = "MostFeedback"; - })(Incidents.IncidentOrder || (Incidents.IncidentOrder = {})); - var IncidentOrder = Incidents.IncidentOrder; - var IncidentSummaryDTO = (function () { - function IncidentSummaryDTO(id, name) { - this.Id = id; - this.Name = name; - } - IncidentSummaryDTO.TYPE_NAME = 'IncidentSummaryDTO'; - return IncidentSummaryDTO; - }()); - Incidents.IncidentSummaryDTO = IncidentSummaryDTO; - })(Incidents = Core.Incidents || (Core.Incidents = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Incidents; - (function (Incidents) { - var Queries; - (function (Queries) { - var FindIncidentResult = (function () { - function FindIncidentResult() { - } - FindIncidentResult.TYPE_NAME = 'FindIncidentResult'; - return FindIncidentResult; - }()); - Queries.FindIncidentResult = FindIncidentResult; - var FindIncidentResultItem = (function () { - function FindIncidentResultItem(id, name) { - this.Id = id; - this.Name = name; - } - FindIncidentResultItem.TYPE_NAME = 'FindIncidentResultItem'; - return FindIncidentResultItem; - }()); - Queries.FindIncidentResultItem = FindIncidentResultItem; - var FindIncidents = (function () { - function FindIncidents() { - } - FindIncidents.TYPE_NAME = 'FindIncidents'; - return FindIncidents; - }()); - Queries.FindIncidents = FindIncidents; - var GetIncident = (function () { - function GetIncident(incidentId) { - this.IncidentId = incidentId; - } - GetIncident.TYPE_NAME = 'GetIncident'; - return GetIncident; - }()); - Queries.GetIncident = GetIncident; - var GetIncidentForClosePage = (function () { - function GetIncidentForClosePage(incidentId) { - this.IncidentId = incidentId; - } - GetIncidentForClosePage.TYPE_NAME = 'GetIncidentForClosePage'; - return GetIncidentForClosePage; - }()); - Queries.GetIncidentForClosePage = GetIncidentForClosePage; - var GetIncidentForClosePageResult = (function () { - function GetIncidentForClosePageResult() { - } - GetIncidentForClosePageResult.TYPE_NAME = 'GetIncidentForClosePageResult'; - return GetIncidentForClosePageResult; - }()); - Queries.GetIncidentForClosePageResult = GetIncidentForClosePageResult; - var GetIncidentResult = (function () { - function GetIncidentResult() { - } - GetIncidentResult.TYPE_NAME = 'GetIncidentResult'; - return GetIncidentResult; - }()); - Queries.GetIncidentResult = GetIncidentResult; - var GetIncidentStatistics = (function () { - function GetIncidentStatistics() { - } - GetIncidentStatistics.TYPE_NAME = 'GetIncidentStatistics'; - return GetIncidentStatistics; - }()); - Queries.GetIncidentStatistics = GetIncidentStatistics; - var GetIncidentStatisticsResult = (function () { - function GetIncidentStatisticsResult() { - } - GetIncidentStatisticsResult.TYPE_NAME = 'GetIncidentStatisticsResult'; - return GetIncidentStatisticsResult; - }()); - Queries.GetIncidentStatisticsResult = GetIncidentStatisticsResult; - var ReportDay = (function () { - function ReportDay() { - } - ReportDay.TYPE_NAME = 'ReportDay'; - return ReportDay; - }()); - Queries.ReportDay = ReportDay; - })(Queries = Incidents.Queries || (Incidents.Queries = {})); - })(Incidents = Core.Incidents || (Core.Incidents = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Incidents; - (function (Incidents) { - var Events; - (function (Events) { - var IncidentIgnored = (function () { - function IncidentIgnored(incidentId, accountId, userName) { - this.IncidentId = incidentId; - this.AccountId = accountId; - this.UserName = userName; - } - IncidentIgnored.TYPE_NAME = 'IncidentIgnored'; - return IncidentIgnored; - }()); - Events.IncidentIgnored = IncidentIgnored; - var IncidentReOpened = (function () { - function IncidentReOpened(applicationId, incidentId, createdAtUtc) { - this.ApplicationId = applicationId; - this.IncidentId = incidentId; - this.CreatedAtUtc = createdAtUtc; - } - IncidentReOpened.TYPE_NAME = 'IncidentReOpened'; - return IncidentReOpened; - }()); - Events.IncidentReOpened = IncidentReOpened; - var ReportAddedToIncident = (function () { - function ReportAddedToIncident(incident, report, isReOpened) { - this.Incident = incident; - this.Report = report; - this.IsReOpened = isReOpened; - } - ReportAddedToIncident.TYPE_NAME = 'ReportAddedToIncident'; - return ReportAddedToIncident; - }()); - Events.ReportAddedToIncident = ReportAddedToIncident; - })(Events = Incidents.Events || (Incidents.Events = {})); - })(Incidents = Core.Incidents || (Core.Incidents = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Incidents; - (function (Incidents) { - var Commands; - (function (Commands) { - var CloseIncident = (function () { - function CloseIncident(solution, incidentId) { - this.Solution = solution; - this.IncidentId = incidentId; - } - CloseIncident.TYPE_NAME = 'CloseIncident'; - return CloseIncident; - }()); - Commands.CloseIncident = CloseIncident; - var IgnoreIncident = (function () { - function IgnoreIncident(incidentId) { - this.IncidentId = incidentId; - } - IgnoreIncident.TYPE_NAME = 'IgnoreIncident'; - return IgnoreIncident; - }()); - Commands.IgnoreIncident = IgnoreIncident; - })(Commands = Incidents.Commands || (Incidents.Commands = {})); - })(Incidents = Core.Incidents || (Core.Incidents = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Feedback; - (function (Feedback) { - var Commands; - (function (Commands) { - var SubmitFeedback = (function () { - function SubmitFeedback(errorId, remoteAddress) { - this.ErrorId = errorId; - this.RemoteAddress = remoteAddress; - } - SubmitFeedback.TYPE_NAME = 'SubmitFeedback'; - return SubmitFeedback; - }()); - Commands.SubmitFeedback = SubmitFeedback; - })(Commands = Feedback.Commands || (Feedback.Commands = {})); - })(Feedback = Core.Feedback || (Core.Feedback = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Applications; - (function (Applications) { - var ApplicationListItem = (function () { - function ApplicationListItem(id, name) { - this.Id = id; - this.Name = name; - } - ApplicationListItem.TYPE_NAME = 'ApplicationListItem'; - return ApplicationListItem; - }()); - Applications.ApplicationListItem = ApplicationListItem; - (function (TypeOfApplication) { - TypeOfApplication[TypeOfApplication["Mobile"] = 0] = "Mobile"; - TypeOfApplication[TypeOfApplication["DesktopApplication"] = 1] = "DesktopApplication"; - TypeOfApplication[TypeOfApplication["Server"] = 2] = "Server"; - })(Applications.TypeOfApplication || (Applications.TypeOfApplication = {})); - var TypeOfApplication = Applications.TypeOfApplication; - })(Applications = Core.Applications || (Core.Applications = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Applications; - (function (Applications) { - var Events; - (function (Events) { - var ApplicationCreated = (function () { - function ApplicationCreated(id, name, createdById, appKey, sharedSecret) { - this.CreatedById = createdById; - this.AppKey = appKey; - this.SharedSecret = sharedSecret; - } - ApplicationCreated.TYPE_NAME = 'ApplicationCreated'; - return ApplicationCreated; - }()); - Events.ApplicationCreated = ApplicationCreated; - var UserInvitedToApplication = (function () { - function UserInvitedToApplication(applicationId, emailAddress, invitedBy) { - this.ApplicationId = applicationId; - this.EmailAddress = emailAddress; - this.InvitedBy = invitedBy; - } - UserInvitedToApplication.TYPE_NAME = 'UserInvitedToApplication'; - return UserInvitedToApplication; - }()); - Events.UserInvitedToApplication = UserInvitedToApplication; - })(Events = Applications.Events || (Applications.Events = {})); - })(Applications = Core.Applications || (Core.Applications = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Applications; - (function (Applications) { - var Queries; - (function (Queries) { - var GetApplicationTeamResult = (function () { - function GetApplicationTeamResult() { - } - GetApplicationTeamResult.TYPE_NAME = 'GetApplicationTeamResult'; - return GetApplicationTeamResult; - }()); - Queries.GetApplicationTeamResult = GetApplicationTeamResult; - var OverviewStatSummary = (function () { - function OverviewStatSummary() { - } - OverviewStatSummary.TYPE_NAME = 'OverviewStatSummary'; - return OverviewStatSummary; - }()); - Queries.OverviewStatSummary = OverviewStatSummary; - var GetApplicationIdByKey = (function () { - function GetApplicationIdByKey(applicationKey) { - this.ApplicationKey = applicationKey; - } - GetApplicationIdByKey.TYPE_NAME = 'GetApplicationIdByKey'; - return GetApplicationIdByKey; - }()); - Queries.GetApplicationIdByKey = GetApplicationIdByKey; - var GetApplicationIdByKeyResult = (function () { - function GetApplicationIdByKeyResult() { - } - GetApplicationIdByKeyResult.TYPE_NAME = 'GetApplicationIdByKeyResult'; - return GetApplicationIdByKeyResult; - }()); - Queries.GetApplicationIdByKeyResult = GetApplicationIdByKeyResult; - var GetApplicationInfo = (function () { - function GetApplicationInfo() { - } - GetApplicationInfo.TYPE_NAME = 'GetApplicationInfo'; - return GetApplicationInfo; - }()); - Queries.GetApplicationInfo = GetApplicationInfo; - var GetApplicationInfoResult = (function () { - function GetApplicationInfoResult() { - } - GetApplicationInfoResult.TYPE_NAME = 'GetApplicationInfoResult'; - return GetApplicationInfoResult; - }()); - Queries.GetApplicationInfoResult = GetApplicationInfoResult; - var GetApplicationList = (function () { - function GetApplicationList() { - } - GetApplicationList.TYPE_NAME = 'GetApplicationList'; - return GetApplicationList; - }()); - Queries.GetApplicationList = GetApplicationList; - var GetApplicationOverviewResult = (function () { - function GetApplicationOverviewResult() { - } - GetApplicationOverviewResult.TYPE_NAME = 'GetApplicationOverviewResult'; - return GetApplicationOverviewResult; - }()); - Queries.GetApplicationOverviewResult = GetApplicationOverviewResult; - var GetApplicationTeam = (function () { - function GetApplicationTeam(applicationId) { - this.ApplicationId = applicationId; - } - GetApplicationTeam.TYPE_NAME = 'GetApplicationTeam'; - return GetApplicationTeam; - }()); - Queries.GetApplicationTeam = GetApplicationTeam; - var GetApplicationTeamMember = (function () { - function GetApplicationTeamMember() { - } - GetApplicationTeamMember.TYPE_NAME = 'GetApplicationTeamMember'; - return GetApplicationTeamMember; - }()); - Queries.GetApplicationTeamMember = GetApplicationTeamMember; - var GetApplicationTeamResultInvitation = (function () { - function GetApplicationTeamResultInvitation() { - } - GetApplicationTeamResultInvitation.TYPE_NAME = 'GetApplicationTeamResultInvitation'; - return GetApplicationTeamResultInvitation; - }()); - Queries.GetApplicationTeamResultInvitation = GetApplicationTeamResultInvitation; - var GetApplicationOverview = (function () { - function GetApplicationOverview(applicationId) { - this.ApplicationId = applicationId; - } - GetApplicationOverview.TYPE_NAME = 'GetApplicationOverview'; - return GetApplicationOverview; - }()); - Queries.GetApplicationOverview = GetApplicationOverview; - })(Queries = Applications.Queries || (Applications.Queries = {})); - })(Applications = Core.Applications || (Core.Applications = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Applications; - (function (Applications) { - var Commands; - (function (Commands) { - var CreateApplication = (function () { - function CreateApplication(name, typeOfApplication) { - this.Name = name; - this.TypeOfApplication = typeOfApplication; - } - CreateApplication.TYPE_NAME = 'CreateApplication'; - return CreateApplication; - }()); - Commands.CreateApplication = CreateApplication; - })(Commands = Applications.Commands || (Applications.Commands = {})); - })(Applications = Core.Applications || (Core.Applications = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Accounts; - (function (Accounts) { - var RegisterSimple = (function () { - function RegisterSimple(emailAddress) { - this.EmailAddress = emailAddress; - } - RegisterSimple.TYPE_NAME = 'RegisterSimple'; - return RegisterSimple; - }()); - Accounts.RegisterSimple = RegisterSimple; - })(Accounts = Core.Accounts || (Core.Accounts = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Accounts; - (function (Accounts) { - var Requests; - (function (Requests) { - var AcceptInvitation = (function () { - function AcceptInvitation(userName, password, invitationKey) { - this.UserName = userName; - this.Password = password; - this.InvitationKey = invitationKey; - } - AcceptInvitation.TYPE_NAME = 'AcceptInvitation'; - return AcceptInvitation; - }()); - Requests.AcceptInvitation = AcceptInvitation; - var AcceptInvitationReply = (function () { - function AcceptInvitationReply(accountId, userName) { - this.AccountId = accountId; - this.UserName = userName; - } - AcceptInvitationReply.TYPE_NAME = 'AcceptInvitationReply'; - return AcceptInvitationReply; - }()); - Requests.AcceptInvitationReply = AcceptInvitationReply; - var ActivateAccount = (function () { - function ActivateAccount(activationKey) { - this.ActivationKey = activationKey; - } - ActivateAccount.TYPE_NAME = 'ActivateAccount'; - return ActivateAccount; - }()); - Requests.ActivateAccount = ActivateAccount; - var ActivateAccountReply = (function () { - function ActivateAccountReply(accountId, userName) { - this.AccountId = accountId; - this.UserName = userName; - } - ActivateAccountReply.TYPE_NAME = 'ActivateAccountReply'; - return ActivateAccountReply; - }()); - Requests.ActivateAccountReply = ActivateAccountReply; - var ChangePassword = (function () { - function ChangePassword(currentPassword, newPassword) { - this.CurrentPassword = currentPassword; - this.NewPassword = newPassword; - } - ChangePassword.TYPE_NAME = 'ChangePassword'; - return ChangePassword; - }()); - Requests.ChangePassword = ChangePassword; - var ChangePasswordReply = (function () { - function ChangePasswordReply() { - } - ChangePasswordReply.TYPE_NAME = 'ChangePasswordReply'; - return ChangePasswordReply; - }()); - Requests.ChangePasswordReply = ChangePasswordReply; - var IgnoreFieldAttribute = (function () { - function IgnoreFieldAttribute() { - } - IgnoreFieldAttribute.TYPE_NAME = 'IgnoreFieldAttribute'; - return IgnoreFieldAttribute; - }()); - Requests.IgnoreFieldAttribute = IgnoreFieldAttribute; - var Login = (function () { - function Login(userName, password) { - this.UserName = userName; - this.Password = password; - } - Login.TYPE_NAME = 'Login'; - return Login; - }()); - Requests.Login = Login; - var LoginReply = (function () { - function LoginReply() { - } - LoginReply.TYPE_NAME = 'LoginReply'; - return LoginReply; - }()); - Requests.LoginReply = LoginReply; - (function (LoginResult) { - LoginResult[LoginResult["Locked"] = 0] = "Locked"; - LoginResult[LoginResult["IncorrectLogin"] = 1] = "IncorrectLogin"; - LoginResult[LoginResult["Successful"] = 2] = "Successful"; - })(Requests.LoginResult || (Requests.LoginResult = {})); - var LoginResult = Requests.LoginResult; - var ResetPassword = (function () { - function ResetPassword(activationKey, newPassword) { - this.ActivationKey = activationKey; - this.NewPassword = newPassword; - } - ResetPassword.TYPE_NAME = 'ResetPassword'; - return ResetPassword; - }()); - Requests.ResetPassword = ResetPassword; - var ResetPasswordReply = (function () { - function ResetPasswordReply() { - } - ResetPasswordReply.TYPE_NAME = 'ResetPasswordReply'; - return ResetPasswordReply; - }()); - Requests.ResetPasswordReply = ResetPasswordReply; - var ValidateNewLogin = (function () { - function ValidateNewLogin() { - } - ValidateNewLogin.TYPE_NAME = 'ValidateNewLogin'; - return ValidateNewLogin; - }()); - Requests.ValidateNewLogin = ValidateNewLogin; - var ValidateNewLoginReply = (function () { - function ValidateNewLoginReply() { - } - ValidateNewLoginReply.TYPE_NAME = 'ValidateNewLoginReply'; - return ValidateNewLoginReply; - }()); - Requests.ValidateNewLoginReply = ValidateNewLoginReply; - })(Requests = Accounts.Requests || (Accounts.Requests = {})); - })(Accounts = Core.Accounts || (Core.Accounts = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Accounts; - (function (Accounts) { - var Queries; - (function (Queries) { - var AccountDTO = (function () { - function AccountDTO() { - } - AccountDTO.TYPE_NAME = 'AccountDTO'; - return AccountDTO; - }()); - Queries.AccountDTO = AccountDTO; - (function (AccountState) { - AccountState[AccountState["VerificationRequired"] = 0] = "VerificationRequired"; - AccountState[AccountState["Active"] = 1] = "Active"; - AccountState[AccountState["Locked"] = 2] = "Locked"; - AccountState[AccountState["ResetPassword"] = 3] = "ResetPassword"; - })(Queries.AccountState || (Queries.AccountState = {})); - var AccountState = Queries.AccountState; - var FindAccountByUserName = (function () { - function FindAccountByUserName(userName) { - this.UserName = userName; - } - FindAccountByUserName.TYPE_NAME = 'FindAccountByUserName'; - return FindAccountByUserName; - }()); - Queries.FindAccountByUserName = FindAccountByUserName; - var GetAccountById = (function () { - function GetAccountById(accountId) { - this.AccountId = accountId; - } - GetAccountById.TYPE_NAME = 'GetAccountById'; - return GetAccountById; - }()); - Queries.GetAccountById = GetAccountById; - var GetAccountEmailById = (function () { - function GetAccountEmailById(accountId) { - this.AccountId = accountId; - } - GetAccountEmailById.TYPE_NAME = 'GetAccountEmailById'; - return GetAccountEmailById; - }()); - Queries.GetAccountEmailById = GetAccountEmailById; - var FindAccountByUserNameResult = (function () { - function FindAccountByUserNameResult(accountId, displayName) { - this.AccountId = accountId; - this.DisplayName = displayName; - } - FindAccountByUserNameResult.TYPE_NAME = 'FindAccountByUserNameResult'; - return FindAccountByUserNameResult; - }()); - Queries.FindAccountByUserNameResult = FindAccountByUserNameResult; - })(Queries = Accounts.Queries || (Accounts.Queries = {})); - })(Accounts = Core.Accounts || (Core.Accounts = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Accounts; - (function (Accounts) { - var Events; - (function (Events) { - var AccountActivated = (function () { - function AccountActivated(accountId, userName) { - this.AccountId = accountId; - this.UserName = userName; - } - AccountActivated.TYPE_NAME = 'AccountActivated'; - return AccountActivated; - }()); - Events.AccountActivated = AccountActivated; - var AccountRegistered = (function () { - function AccountRegistered(accountId, userName) { - this.AccountId = accountId; - this.UserName = userName; - } - AccountRegistered.TYPE_NAME = 'AccountRegistered'; - return AccountRegistered; - }()); - Events.AccountRegistered = AccountRegistered; - var InvitationAccepted = (function () { - function InvitationAccepted(accountId, invitedByUserName, userName) { - this.AccountId = accountId; - this.InvitedByUserName = invitedByUserName; - this.UserName = userName; - } - InvitationAccepted.TYPE_NAME = 'InvitationAccepted'; - return InvitationAccepted; - }()); - Events.InvitationAccepted = InvitationAccepted; - var LoginFailed = (function () { - function LoginFailed(userName) { - this.UserName = userName; - } - LoginFailed.TYPE_NAME = 'LoginFailed'; - return LoginFailed; - }()); - Events.LoginFailed = LoginFailed; - })(Events = Accounts.Events || (Accounts.Events = {})); - })(Accounts = Core.Accounts || (Core.Accounts = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); -var OneTrueError; -(function (OneTrueError) { - var Core; - (function (Core) { - var Accounts; - (function (Accounts) { - var Commands; - (function (Commands) { - var DeclineInvitation = (function () { - function DeclineInvitation(invitationId) { - this.InvitationId = invitationId; - } - DeclineInvitation.TYPE_NAME = 'DeclineInvitation'; - return DeclineInvitation; - }()); - Commands.DeclineInvitation = DeclineInvitation; - var RegisterAccount = (function () { - function RegisterAccount(userName, password, email) { - this.UserName = userName; - this.Password = password; - this.Email = email; - } - RegisterAccount.TYPE_NAME = 'RegisterAccount'; - return RegisterAccount; - }()); - Commands.RegisterAccount = RegisterAccount; - var RequestPasswordReset = (function () { - function RequestPasswordReset(emailAddress) { - this.EmailAddress = emailAddress; - } - RequestPasswordReset.TYPE_NAME = 'RequestPasswordReset'; - return RequestPasswordReset; - }()); - Commands.RequestPasswordReset = RequestPasswordReset; - })(Commands = Accounts.Commands || (Accounts.Commands = {})); - })(Accounts = Core.Accounts || (Core.Accounts = {})); - })(Core = OneTrueError.Core || (OneTrueError.Core = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/Scripts/Promise.js b/src/Server/OneTrueError.Web/Scripts/Promise.js deleted file mode 100644 index 7d17cf2f..00000000 --- a/src/Server/OneTrueError.Web/Scripts/Promise.js +++ /dev/null @@ -1,323 +0,0 @@ -/** - Module P: Generic Promises for TypeScript - - Project, documentation, and license: https://github.com/pragmatrix/Promise -*/ -var P; -(function (P) { - /** - Returns a new "Deferred" value that may be resolved or rejected. - */ - function defer() { - return new DeferredI(); - } - P.defer = defer; - /** - Converts a value to a resolved promise. - */ - function resolve(v) { - return defer().resolve(v).promise(); - } - P.resolve = resolve; - /** - Returns a rejected promise. - */ - function reject(err) { - return defer().reject(err).promise(); - } - P.reject = reject; - /** - http://en.wikipedia.org/wiki/Anamorphism - - Given a seed value, unfold calls the unspool function, waits for the returned promise to be resolved, and then - calls it again if a next seed value was returned. - - All the values of all promise results are collected into the resulting promise which is resolved as soon - the last generated element value is resolved. - */ - function unfold(unspool, seed) { - var d = defer(); - var elements = new Array(); - unfoldCore(elements, d, unspool, seed); - return d.promise(); - } - P.unfold = unfold; - function unfoldCore(elements, deferred, unspool, seed) { - var result = unspool(seed); - if (!result) { - deferred.resolve(elements); - return; - } - // fastpath: don't waste stack space if promise resolves immediately. - while (result.next && result.promise.status == P.Status.Resolved) { - elements.push(result.promise.result); - result = unspool(result.next); - if (!result) { - deferred.resolve(elements); - return; - } - } - result.promise - .done(function (v) { - elements.push(v); - if (!result.next) - deferred.resolve(elements); - else - unfoldCore(elements, deferred, unspool, result.next); - }) - .fail(function (e) { - deferred.reject(e); - }); - } - /** - The status of a Promise. Initially a Promise is Unfulfilled and may - change to Rejected or Resolved. - - Once a promise is either Rejected or Resolved, it can not change its - status anymore. - */ - (function (Status) { - Status[Status["Unfulfilled"] = 0] = "Unfulfilled"; - Status[Status["Rejected"] = 1] = "Rejected"; - Status[Status["Resolved"] = 2] = "Resolved"; - })(P.Status || (P.Status = {})); - var Status = P.Status; - /** - Creates a promise that gets resolved when all the promises in the argument list get resolved. - As soon one of the arguments gets rejected, the resulting promise gets rejected. - If no promises were provided, the resulting promise is immediately resolved. - */ - function when() { - var promises = []; - for (var _i = 0; _i < arguments.length; _i++) { - promises[_i - 0] = arguments[_i]; - } - var allDone = defer(); - if (!promises.length) { - allDone.resolve([]); - return allDone.promise(); - } - var resolved = 0; - var results = []; - promises.forEach(function (p, i) { - p - .done(function (v) { - results[i] = v; - ++resolved; - if (resolved === promises.length && allDone.status !== Status.Rejected) - allDone.resolve(results); - }) - .fail(function (e) { - if (allDone.status !== Status.Rejected) - allDone.reject(new Error("when: one or more promises were rejected")); - }); - }); - return allDone.promise(); - } - P.when = when; - /** - Implementation of a promise. - - The Promise instance is a proxy to the Deferred instance. - */ - var PromiseI = (function () { - function PromiseI(deferred) { - this.deferred = deferred; - } - Object.defineProperty(PromiseI.prototype, "status", { - get: function () { return this.deferred.status; }, - enumerable: true, - configurable: true - }); - Object.defineProperty(PromiseI.prototype, "result", { - get: function () { return this.deferred.result; }, - enumerable: true, - configurable: true - }); - Object.defineProperty(PromiseI.prototype, "error", { - get: function () { return this.deferred.error; }, - enumerable: true, - configurable: true - }); - PromiseI.prototype.done = function (f) { - this.deferred.done(f); - return this; - }; - PromiseI.prototype.fail = function (f) { - this.deferred.fail(f); - return this; - }; - PromiseI.prototype.always = function (f) { - this.deferred.always(f); - return this; - }; - PromiseI.prototype.then = function (f) { - return this.deferred.then(f); - }; - return PromiseI; - }()); - /** - Implementation of a deferred. - */ - var DeferredI = (function () { - function DeferredI() { - this._resolved = function (_) { }; - this._rejected = function (_) { }; - this._status = Status.Unfulfilled; - this._error = { message: "" }; - this._promise = new PromiseI(this); - } - DeferredI.prototype.promise = function () { - return this._promise; - }; - Object.defineProperty(DeferredI.prototype, "status", { - get: function () { - return this._status; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(DeferredI.prototype, "result", { - get: function () { - if (this._status != Status.Resolved) - throw new Error("Promise: result not available"); - return this._result; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(DeferredI.prototype, "error", { - get: function () { - if (this._status != Status.Rejected) - throw new Error("Promise: rejection reason not available"); - return this._error; - }, - enumerable: true, - configurable: true - }); - DeferredI.prototype.then = function (f) { - var d = defer(); - this - .done(function (v) { - var promiseOrValue = f(v); - // todo: need to find another way to check if r is really of interface - // type Promise, otherwise we would not support other - // implementations here. - if (promiseOrValue instanceof PromiseI) { - var p = promiseOrValue; - p.done(function (v2) { return d.resolve(v2); }) - .fail(function (err) { return d.reject(err); }); - return p; - } - d.resolve(promiseOrValue); - }) - .fail(function (err) { return d.reject(err); }); - return d.promise(); - }; - DeferredI.prototype.done = function (f) { - if (this.status === Status.Resolved) { - f(this._result); - return this; - } - if (this.status !== Status.Unfulfilled) - return this; - var prev = this._resolved; - this._resolved = function (v) { prev(v); f(v); }; - return this; - }; - DeferredI.prototype.fail = function (f) { - if (this.status === Status.Rejected) { - f(this._error); - return this; - } - if (this.status !== Status.Unfulfilled) - return this; - var prev = this._rejected; - this._rejected = function (e) { prev(e); f(e); }; - return this; - }; - DeferredI.prototype.always = function (f) { - this - .done(function (v) { return f(v); }) - .fail(function (err) { return f(null, err); }); - return this; - }; - DeferredI.prototype.resolve = function (result) { - if (this._status !== Status.Unfulfilled) - throw new Error("tried to resolve a fulfilled promise"); - this._result = result; - this._status = Status.Resolved; - this._resolved(result); - this.detach(); - return this; - }; - DeferredI.prototype.reject = function (err) { - if (this._status !== Status.Unfulfilled) - throw new Error("tried to reject a fulfilled promise"); - this._error = err; - this._status = Status.Rejected; - this._rejected(err); - this.detach(); - return this; - }; - DeferredI.prototype.detach = function () { - this._resolved = function (_) { }; - this._rejected = function (_) { }; - }; - return DeferredI; - }()); - function generator(g) { - return function () { return iterator(g()); }; - } - P.generator = generator; - ; - function iterator(f) { - return new IteratorI(f); - } - P.iterator = iterator; - var IteratorI = (function () { - function IteratorI(f) { - this.f = f; - this.current = undefined; - } - IteratorI.prototype.advance = function () { - var _this = this; - var res = this.f(); - return res.then(function (value) { - if (isUndefined(value)) - return false; - _this.current = value; - return true; - }); - }; - return IteratorI; - }()); - /** - Iterator functions. - */ - function each(gen, f) { - var d = defer(); - eachCore(d, gen(), f); - return d.promise(); - } - P.each = each; - function eachCore(fin, it, f) { - it.advance() - .done(function (hasValue) { - if (!hasValue) { - fin.resolve({}); - return; - } - f(it.current); - eachCore(fin, it, f); - }) - .fail(function (err) { return fin.reject(err); }); - } - /** - std - */ - function isUndefined(v) { - return typeof v === 'undefined'; - } - P.isUndefined = isUndefined; -})(P || (P = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Account/AcceptedViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Account/AcceptedViewModel.js deleted file mode 100644 index efb788b6..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Account/AcceptedViewModel.js +++ /dev/null @@ -1,17 +0,0 @@ -var OneTrueError; -(function (OneTrueError) { - var Account; - (function (Account) { - var AcceptedViewModel = (function () { - function AcceptedViewModel() { - } - AcceptedViewModel.prototype.getTitle = function () { return "Invitation accepted"; }; - AcceptedViewModel.prototype.activate = function (context) { - context.resolve(); - }; - AcceptedViewModel.prototype.deactivate = function () { }; - return AcceptedViewModel; - }()); - Account.AcceptedViewModel = AcceptedViewModel; - })(Account = OneTrueError.Account || (OneTrueError.Account = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Account/SettingsViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Account/SettingsViewModel.js deleted file mode 100644 index a5fef529..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Account/SettingsViewModel.js +++ /dev/null @@ -1,56 +0,0 @@ -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Account; - (function (Account) { - var CqsClient = Griffin.Cqs.CqsClient; - var GetUserSettings = OneTrueError.Core.Users.Queries.GetUserSettings; - var ChangePassword = OneTrueError.Core.Accounts.Requests.ChangePassword; - var AccountSettings = (function () { - function AccountSettings() { - this.notifyNewIncident = true; - } - return AccountSettings; - }()); - Account.AccountSettings = AccountSettings; - var SettingsViewModel = (function () { - function SettingsViewModel() { - } - SettingsViewModel.load = function () { - var def = P.defer(); - var query = new GetUserSettings(); - CqsClient.query(query). - done(function (response) { - var vm = new SettingsViewModel(); - def.resolve(vm); - }); - return def.promise(); - }; - SettingsViewModel.prototype.saveSettings = function () { - var mapping = { - 'ignore': ["saveSettings"] - }; - }; - SettingsViewModel.prototype.changePassword = function () { - var json = { - currentPassword: $('#CurrentPassword').val(), - newPassword: $('#NewPassword').val() - }; - if (json.newPassword != $('#NewPassword2').val()) { - alert("The new password fields do not match."); - return; - } - var newPw = $('#NewPassword2').val(); - var oldPw = $('#CurrentPassword').val(); - var pw = new ChangePassword(newPw, oldPw); - CqsClient.command(pw) - .done(function (value) { - }).fail(function (err) { - }); - }; - return SettingsViewModel; - }()); - Account.SettingsViewModel = SettingsViewModel; - })(Account = OneTrueError.Account || (OneTrueError.Account = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Account/WelcomeViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Account/WelcomeViewModel.js deleted file mode 100644 index 59b05385..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Account/WelcomeViewModel.js +++ /dev/null @@ -1,17 +0,0 @@ -var OneTrueError; -(function (OneTrueError) { - var Account; - (function (Account) { - var WelcomeViewModel = (function () { - function WelcomeViewModel() { - } - WelcomeViewModel.prototype.getTitle = function () { return "Welcome"; }; - WelcomeViewModel.prototype.activate = function (context) { - context.resolve(); - }; - WelcomeViewModel.prototype.deactivate = function () { }; - return WelcomeViewModel; - }()); - Account.WelcomeViewModel = WelcomeViewModel; - })(Account = OneTrueError.Account || (OneTrueError.Account = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Application/DetailsViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Application/DetailsViewModel.js deleted file mode 100644 index 67eab774..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Application/DetailsViewModel.js +++ /dev/null @@ -1,282 +0,0 @@ -/// -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Application; - (function (Application) { - var CqsClient = Griffin.Cqs.CqsClient; - var IncidentOrder = OneTrueError.Core.Incidents.IncidentOrder; - var FindIncidents = OneTrueError.Core.Incidents.Queries.FindIncidents; - var Yo = Griffin.Yo; - var DetailsViewModel = (function () { - function DetailsViewModel() { - this._sortType = IncidentOrder.Newest; - this._sortAscending = false; - this._incidentType = "active"; - } - DetailsViewModel.prototype.getTitle = function () { - $("#appTitle").text(this.applicationName); - return this.applicationName; - }; - DetailsViewModel.prototype.activate = function (ctx) { - var _this = this; - this._ctx = ctx; - this.applicationId = ctx.routeData["applicationId"]; - this.pager = new Griffin.WebApp.Pager(0, 0, 0); - this.pager.subscribe(this); - this.pager.draw(ctx.select.one("#pager")); - var self = this; - var firstIsRun = false; - var chartResult = null; - var chartRendering = function (result) { - //chart must be rendered after the element being attached and visible. - ctx.resolve(); - self.lineChart = new OneTrueError.LineChart(ctx.select.one("#myChart")); - self.renderChart(result); - }; - var appQuery = new OneTrueError.Core.Applications.Queries.GetApplicationInfo(); - appQuery.ApplicationId = ctx.routeData["applicationId"]; - CqsClient.query(appQuery) - .done(function (info) { - Yo.GlobalConfig.applicationScope["application"] = info; - _this.applicationName = info.Name; - if (chartResult != null) { - chartRendering(chartResult); - } - firstIsRun = true; - _this.renderInfo(info); - }); - var query = new OneTrueError.Core.Applications.Queries.GetApplicationOverview(this.applicationId); - CqsClient.query(query) - .done(function (response) { - if (!firstIsRun) { - chartResult = response; - } - else { - chartRendering(response); - } - }); - this.getIncidentsFromServer(1); - ctx.handle.click("#btnClosed", function (e) { return _this.onBtnClosed(e); }); - ctx.handle.click("#btnActive", function (e) { return _this.onBtnActive(e); }); - ctx.handle.click("#btnIgnored", function (e) { return _this.onBtnIgnored(e); }); - ctx.handle.click("#LastReportCol", function (e) { return _this.onLastReportCol(e); }); - ctx.handle.click("#CountCol", function (e) { return _this.onCountCol(e); }); - ctx.handle.change('[name="range"]', function (e) { return _this.onRange(e); }); - }; - DetailsViewModel.prototype.deactivate = function () { - }; - DetailsViewModel.prototype.onRange = function (e) { - var _this = this; - var elem = e.target; - var days = parseInt(elem.value, 10); - var query = new OneTrueError.Core.Applications.Queries.GetApplicationOverview(this.applicationId); - query.NumberOfDays = days; - CqsClient.query(query) - .done(function (response) { - _this.renderChart(response); - }); - }; - DetailsViewModel.prototype.onBtnActive = function (e) { - e.preventDefault(); - this._incidentType = "active"; - this.pager.reset(); - this.getIncidentsFromServer(-1); - }; - DetailsViewModel.prototype.onBtnClosed = function (e) { - e.preventDefault(); - this._incidentType = "closed"; - this.pager.reset(); - this.getIncidentsFromServer(-1); - }; - DetailsViewModel.prototype.onBtnIgnored = function (e) { - e.preventDefault(); - this._incidentType = "ignored"; - this.pager.reset(); - this.getIncidentsFromServer(-1); - }; - DetailsViewModel.prototype.onPager = function (pager) { - this.getIncidentsFromServer(pager.currentPage); - var table = this._ctx.select.one("#incidentTable"); - //.scrollIntoView(true); - var y = this.findYPosition(table); - window.scrollTo(null, y - 50); //navbar - }; - DetailsViewModel.prototype.findYPosition = function (element) { - var curtop = 0; - if (element.offsetParent) { - do { - curtop += element.offsetTop; - element = (element.offsetParent); - } while (element); - return curtop; - } - }; - DetailsViewModel.prototype.onCountCol = function (args) { - if (this._sortType !== IncidentOrder.MostReports) { - this._sortType = IncidentOrder.MostReports; - this._sortAscending = true; //will be changed below - } - this.updateSortingUI(args.target); - this.getIncidentsFromServer(this.pager.currentPage); - }; - DetailsViewModel.prototype.onLastReportCol = function (args) { - if (this._sortType !== IncidentOrder.Newest) { - this._sortType = IncidentOrder.Newest; - this._sortAscending = true; //will be changed below - } - this.updateSortingUI(args.target); - this.getIncidentsFromServer(this.pager.currentPage); - }; - DetailsViewModel.prototype.renderTable = function (pageNumber, data) { - var directives = { - Items: { - IncidentName: { - text: function (data) { - return data; - }, - href: function (data, dto) { - return "#/application/" + dto.ApplicationId + "/incident/" + dto.Id; - } - }, - CreatedAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - LastUpdateAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - ApplicationName: { - text: function (value) { - return value; - }, - href: function (value, dto) { - return "#/application/" + dto.ApplicationId; - } - } - } - }; - //workaround for root dto name rendering over our collection name - data.Items.forEach(function (item) { - item.IncidentName = item.Name; - }); - this._ctx.renderPartial("#incidentTable", data, directives); - }; - DetailsViewModel.prototype.renderInfo = function (dto) { - var directives = { - CreatedAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - UpdatedAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - SolvedAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - } - }; - dto["StatSummary"] = { - AppKey: dto.AppKey, - SharedSecret: dto.SharedSecret - }; - this._ctx.render(dto, directives); - }; - DetailsViewModel.prototype.updateSortingUI = function (parentElement) { - this._sortAscending = !this._sortAscending; - var icon = DetailsViewModel.UP; - if (!this._sortAscending) { - icon = DetailsViewModel.DOWN; - } - $("#ApplicationView thead th span") - .removeClass("glyphicon-chevron-down") - .addClass("glyphicon " + icon) - .css("visibility", "hidden"); - $("span", parentElement) - .attr("class", "glyphicon " + icon) - .css("visibility", "inherit"); - }; - DetailsViewModel.prototype.getIncidentsFromServer = function (pageNumber) { - var _this = this; - if (pageNumber === -1) { - pageNumber = this.pager.currentPage; - } - var query = new FindIncidents(); - query.SortType = this._sortType; - query.SortAscending = this._sortAscending; - query.PageNumber = pageNumber; - query.ItemsPerPage = 10; - query.ApplicationId = this.applicationId; - if (this._incidentType === "closed") { - query.Closed = true; - query.Open = false; - } - else if (this._incidentType === "ignored") { - query.Closed = false; - query.Open = false; - query.ReOpened = false; - query.Ignored = true; - } - CqsClient.query(query) - .done(function (response) { - if (_this.pager.pageCount === 0) { - _this.pager.update(response.PageNumber, response.PageSize, response.TotalCount); - } - _this.renderTable(pageNumber, response); - }); - }; - DetailsViewModel.prototype.renderChart = function (result) { - var legend = [ - { - color: OneTrueError.LineChart.LineThemes[0].strokeColor, - label: "Incidents" - }, { - color: OneTrueError.LineChart.LineThemes[1].strokeColor, - label: "Reports" - } - ]; - var incidentsDataset = new OneTrueError.Dataset(); - incidentsDataset.label = "Incidents"; - incidentsDataset.data = result.Incidents; - var reportDataset = new OneTrueError.Dataset(); - reportDataset.label = "Reports"; - reportDataset.data = result.ErrorReports; - var directives = { - color: { - text: function () { - return ""; - }, - style: function (value, dto) { - return "display: inline; font-weight: bold; color: " + dto.color; - } - }, - label: { - style: function (value, dto) { - return "font-weight: bold; color: " + dto.color; - } - } - }; - this._ctx.renderPartial("#chart-legend", legend, directives); - //$('#chart-legend').render(legend, directives); - var data = new OneTrueError.LineData(); - data.datasets = [incidentsDataset, reportDataset]; - data.labels = result.TimeAxisLabels; - this.lineChart.render(data); - this._ctx.renderPartial('[data-name="StatSummary"]', result.StatSummary); - }; - DetailsViewModel.UP = "glyphicon-chevron-up"; - DetailsViewModel.DOWN = "glyphicon-chevron-down"; - return DetailsViewModel; - }()); - Application.DetailsViewModel = DetailsViewModel; - })(Application = OneTrueError.Application || (OneTrueError.Application = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Application/InstallationViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Application/InstallationViewModel.js deleted file mode 100644 index cf3daec6..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Application/InstallationViewModel.js +++ /dev/null @@ -1,26 +0,0 @@ -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Application; - (function (Application) { - var InstallationViewModel = (function () { - function InstallationViewModel() { - } - InstallationViewModel.prototype.getTitle = function () { return "Installation instructions"; }; - InstallationViewModel.prototype.activate = function (context) { - var service = new OneTrueError.Applications.ApplicationService(); - service.get(context.routeData['applicationId']) - .done(function (app) { - app.AppUrl = window["API_URL"]; - context.render(app); - $('#appTitle').text(app.Name); - context.resolve(); - }); - }; - InstallationViewModel.prototype.deactivate = function () { }; - return InstallationViewModel; - }()); - Application.InstallationViewModel = InstallationViewModel; - })(Application = OneTrueError.Application || (OneTrueError.Application = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Application/InstallationViewModel.js.map b/src/Server/OneTrueError.Web/ViewModels/Application/InstallationViewModel.js.map deleted file mode 100644 index 4e7d241d..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Application/InstallationViewModel.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"InstallationViewModel.js","sourceRoot":"","sources":["InstallationViewModel.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,gDAAgD;AAEhD,IAAO,YAAY,CAkBlB;AAlBD,WAAO,YAAY;IAAC,IAAA,WAAW,CAkB9B;IAlBmB,WAAA,WAAW,EAAC,CAAC;QAG7B;YAAA;YAcA,CAAC;YAbG,wCAAQ,GAAR,cAAqB,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;YAE1D,wCAAQ,GAAR,UAAS,OAAqD;gBAC1D,IAAI,OAAO,GAAG,IAAI,yBAAY,CAAC,kBAAkB,EAAE,CAAC;gBACpD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;qBAC1C,IAAI,CAAC,UAAA,GAAG;oBACT,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAChB,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC9B,OAAO,CAAC,OAAO,EAAE,CAAC;gBACtB,CAAC,CAAC,CAAC;YACX,CAAC;YAED,0CAAU,GAAV,cAAc,CAAC;YACnB,4BAAC;QAAD,CAAC,AAdD,IAcC;QAdY,iCAAqB,wBAcjC,CAAA;IACL,CAAC,EAlBmB,WAAW,GAAX,wBAAW,KAAX,wBAAW,QAkB9B;AAAD,CAAC,EAlBM,YAAY,KAAZ,YAAY,QAkBlB"} \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/ViewModels/Application/TeamViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Application/TeamViewModel.js deleted file mode 100644 index 01c7737b..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Application/TeamViewModel.js +++ /dev/null @@ -1,47 +0,0 @@ -/// -var OneTrueError; -(function (OneTrueError) { - var Application; - (function (Application) { - var CqsClient = Griffin.Cqs.CqsClient; - var TeamViewModel = (function () { - function TeamViewModel() { - } - TeamViewModel.prototype.getTitle = function () { - return "Team members"; - }; - TeamViewModel.prototype.activate = function (context) { - var _this = this; - this.context = context; - this.applicationId = parseInt(context.routeData["applicationId"], 10); - context.render({ Members: [], Invited: [] }); - var query = new OneTrueError.Core.Applications.Queries.GetApplicationTeam(this.applicationId); - CqsClient.query(query) - .done(function (result) { - context.render(result); - _this.data = result; - context.resolve(); - context.handle.click('#InviteUserBtn', function (e) { return _this.onInviteUser(e); }); - }); - }; - TeamViewModel.prototype.deactivate = function () { }; - TeamViewModel.prototype.onInviteUser = function (mouseEvent) { - mouseEvent.preventDefault(); - var inputElement = this.context.select.one("emailAddress"); - var email = inputElement.value; - var el = this.context.select.one("reason"); - var reason = el.value; - var cmd = new OneTrueError.Core.Invitations.Commands.InviteUser(this.applicationId, email); - cmd.Text = reason; - CqsClient.command(cmd); - var newItem = new OneTrueError.Core.Applications.Queries.GetApplicationTeamResultInvitation(); - newItem.EmailAddress = email; - this.data.Invited.push(newItem); - this.context.render(this.data); - inputElement.value = ""; - }; - return TeamViewModel; - }()); - Application.TeamViewModel = TeamViewModel; - })(Application = OneTrueError.Application || (OneTrueError.Application = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/ChartViewModel.js b/src/Server/OneTrueError.Web/ViewModels/ChartViewModel.js deleted file mode 100644 index cd19fad1..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/ChartViewModel.js +++ /dev/null @@ -1,144 +0,0 @@ -var OneTrueError; -(function (OneTrueError) { - ; - var Dataset = (function () { - function Dataset() { - } - return Dataset; - }()); - OneTrueError.Dataset = Dataset; - ; - var LineData = (function () { - function LineData() { - } - return LineData; - }()); - OneTrueError.LineData = LineData; - var LineChart = (function () { - function LineChart(targetElementOrId) { - this.chart = null; - this.lineChart = null; - this.initChartGlobals(); - if (typeof targetElementOrId === "string") { - var elem = document.getElementById(targetElementOrId); - if (!elem) - throw new Error("Failed to find " + targetElementOrId); - this.ctx = elem.getContext("2d"); - } - else { - if (!targetElementOrId) - throw new Error("Is not a HTMLElement: " + targetElementOrId); - this.ctx = targetElementOrId.getContext("2d"); - } - this.chart = new Chart(this.ctx); - } - LineChart.prototype.mergeOptions = function (obj1, obj2) { - for (var p in obj2) { - try { - // Property in destination object set; update its value. - if (obj2[p].constructor == Object) { - obj1[p] = this.mergeOptions(obj1[p], obj2[p]); - } - else { - obj1[p] = obj2[p]; - } - } - catch (e) { - // Property in destination object not set; create it and set its value. - obj1[p] = obj2[p]; - } - } - return obj1; - }; - LineChart.prototype.render = function (data) { - if (this.lineChart !== null) - this.lineChart.destroy(); - if (data.datasets.length) { - } - for (var j = 0; j < data.datasets.length; j++) { - data.datasets[j] = this.mergeOptions(data.datasets[j], LineChart.LineThemes[j]); - } - var allEmpty; - data.datasets.forEach(function (dataset) { - dataset.data.forEach(function (item) { - if (item !== 0) { - allEmpty = false; - return; - } - }); - }); - //if (allEmpty || data.datasets.length === 0) { - // this.ctx.font = "20px Arial"; - // this.ctx.fillStyle = 'white'; - // this.ctx.fillText("No reports have been received during the specified period.", 10, 50); - // return; - //} - this.lineChart = this.chart.Line(data, Chart.DefaultOptions); - }; - LineChart.prototype.initChartGlobals = function () { - Chart.defaults.global.scaleLineColor = "#eee"; - Chart.defaults.global.scaleFontColor = "#eee"; - Chart.defaults.global.responsive = true; - Chart.DefaultOptions = { - ///Boolean - Whether grid lines are shown across the chart - scaleShowGridLines: true, - //String - Colour of the grid lines - scaleGridLineColor: "rgba(255,255,255,.05)", - //Number - Width of the grid lines - scaleGridLineWidth: 1, - //Boolean - Whether to show horizontal lines (except X axis) - scaleShowHorizontalLines: true, - //Boolean - Whether to show vertical lines (except Y axis) - scaleShowVerticalLines: false, - //Boolean - Whether the line is curved between points - bezierCurve: true, - //Number - Tension of the bezier curve between points - bezierCurveTension: 0.2, - //Boolean - Whether to show a dot for each point - pointDot: true, - //Number - Radius of each point dot in pixels - pointDotRadius: 4, - //Number - Pixel width of point dot stroke - pointDotStrokeWidth: 1, - //Number - amount extra to add to the radius to cater for hit detection outside the drawn point - pointHitDetectionRadius: 20, - //Boolean - Whether to show a stroke for datasets - datasetStroke: true, - //Number - Pixel width of dataset stroke - datasetStrokeWidth: 2, - //Boolean - Whether to fill the dataset with a colour - datasetFill: false, - //String - A legend template - legendTemplate: "
    -legend\"><% for (var i=0; i
  • \"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>
" - }; - }; - LineChart.LineThemes = [ - { - fillColor: "rgba(245,254,22,0.2)", - strokeColor: "#ffda70", - pointColor: "#ffda70", - pointStrokeColor: "#ffda70", - pointHighlightFill: "#fff", - pointHighlightStroke: "rgba(255,255,255,0.5)" - }, - { - fillColor: "rgba(221,19,165,0.2)", - strokeColor: "#ff9570", - pointColor: "#ff9570", - pointStrokeColor: "#ff9570", - pointHighlightFill: "#fff", - pointHighlightStroke: "rgba(255,255,255,0.5)" - }, - { - fillColor: "rgba(255,82,22,0.2)", - strokeColor: "#ff5216", - pointColor: "#ff5216", - pointStrokeColor: "#ff5216", - pointHighlightFill: "#fff", - pointHighlightStroke: "rgba(255,255,255,0.5)" - } - ]; - return LineChart; - }()); - OneTrueError.LineChart = LineChart; -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Feedback/ApplicationViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Feedback/ApplicationViewModel.js deleted file mode 100644 index 5301252b..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Feedback/ApplicationViewModel.js +++ /dev/null @@ -1,74 +0,0 @@ -/// -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Feedback; - (function (Feedback) { - var CqsClient = Griffin.Cqs.CqsClient; - var Yo = Griffin.Yo; - var ApplicationViewModel = (function () { - function ApplicationViewModel() { - this.RenderDirectives = { - Items: { - Message: { - html: function (value) { - return nl2br(value); - } - }, - Title: { - style: function () { - return "color:#ccc"; - }, - html: function (value, dto) { - return "Reported for " + dto.ApplicationName + " at " + new Date(dto.WrittenAtUtc).toLocaleString(); - } - }, - EmailAddressVisible: { - style: function (value, dto) { - if (!dto.EmailAddress || dto.EmailAddress === "") { - return "display:none"; - } - return ""; - } - }, - EmailAddress: { - text: function (value) { - return value; - }, - href: function (value) { - return "mailto:" + value; - }, - style: function () { - return "color: #ee99ee"; - } - } - } - }; - } - ApplicationViewModel.prototype.getTitle = function () { - var app = Yo.GlobalConfig.applicationScope["application"]; - if (app) { - return app.Name; - } - return "Feedback"; - }; - ApplicationViewModel.prototype.activate = function (context) { - var _this = this; - this.context = context; - var query = new OneTrueError.Web.Feedback.Queries.GetFeedbackForApplicationPage(context.routeData["applicationId"]); - CqsClient.query(query) - .done(function (result) { - _this.dto = result; - context.render(result, _this.RenderDirectives); - context.resolve(); - }); - }; - ApplicationViewModel.prototype.deactivate = function () { - }; - return ApplicationViewModel; - }()); - Feedback.ApplicationViewModel = ApplicationViewModel; - })(Feedback = OneTrueError.Feedback || (OneTrueError.Feedback = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Feedback/IncidentViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Feedback/IncidentViewModel.js deleted file mode 100644 index 2e702bb2..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Feedback/IncidentViewModel.js +++ /dev/null @@ -1,63 +0,0 @@ -/// -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Feedback; - (function (Feedback) { - var CqsClient = Griffin.Cqs.CqsClient; - var GetIncidentFeedback = OneTrueError.Web.Feedback.Queries.GetIncidentFeedback; - var IncidentViewModel = (function () { - function IncidentViewModel() { - } - IncidentViewModel.prototype.activate = function (ctx) { - var _this = this; - this.ctx = ctx; - var query = new GetIncidentFeedback(ctx.routeData["incidentId"]); - CqsClient.query(query).done(function (result) { - _this.ctx.render(result, IncidentViewModel.directives); - ctx.resolve(); - }); - }; - IncidentViewModel.prototype.deactivate = function () { - }; - IncidentViewModel.prototype.getTitle = function () { - return "Incident"; - }; - IncidentViewModel.directives = { - Items: { - Message: { - html: function (value) { - return nl2br(value); - } - }, - Title: { - style: function () { - return "color:#ccc"; - }, - html: function (value, dto) { - return "Written at " + new Date(dto.WrittenAtUtc).toLocaleString(); - } - }, - EmailAddress: { - text: function (value) { - return value; - }, - href: function (value) { - return "mailto:" + value; - }, - style: function (value) { - if (!value) { - return "display:none"; - } - return "color: #ee99ee"; - } - } - } - }; - return IncidentViewModel; - }()); - Feedback.IncidentViewModel = IncidentViewModel; - })(Feedback = OneTrueError.Feedback || (OneTrueError.Feedback = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Feedback/OverviewViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Feedback/OverviewViewModel.js deleted file mode 100644 index 6d92f491..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Feedback/OverviewViewModel.js +++ /dev/null @@ -1,64 +0,0 @@ -/// -/// -/// -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Feedback; - (function (Feedback) { - var CqsClient = Griffin.Cqs.CqsClient; - var OverviewFeedback = OneTrueError.Web.Feedback.Queries.GetFeedbackForDashboardPage; - var OverviewViewModel = (function () { - function OverviewViewModel() { - this.feedbackDirectives = { - Items: { - Message: { - html: function (value) { - return nl2br(value); - } - }, - Title: { - style: function () { - return "color:#ccc"; - }, - html: function (value, dto) { - return "Reported for " + dto.ApplicationName + " at " + new Date(dto.WrittenAtUtc).toLocaleString(); - } - }, - EmailAddress: { - text: function (value) { - return value; - }, - href: function (value) { - return "mailto:" + value; - }, - style: function (value) { - if (!value) { - return "display:none"; - } - return "color: #ee99ee"; - } - } - } - }; - } - OverviewViewModel.prototype.getTitle = function () { - return "All feedback"; - }; - OverviewViewModel.prototype.activate = function (context) { - var _this = this; - var query = new OverviewFeedback(); - CqsClient.query(query).done(function (result) { - context.render(result, _this.feedbackDirectives); - context.resolve(); - }); - }; - OverviewViewModel.prototype.deactivate = function () { - }; - return OverviewViewModel; - }()); - Feedback.OverviewViewModel = OverviewViewModel; - })(Feedback = OneTrueError.Feedback || (OneTrueError.Feedback = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Home/WelcomeViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Home/WelcomeViewModel.js deleted file mode 100644 index 33dc670f..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Home/WelcomeViewModel.js +++ /dev/null @@ -1,17 +0,0 @@ -var OneTrueError; -(function (OneTrueError) { - var Home; - (function (Home) { - var WelcomeViewModel = (function () { - function WelcomeViewModel() { - } - WelcomeViewModel.prototype.getTitle = function () { return "Welcome"; }; - WelcomeViewModel.prototype.activate = function (context) { - context.resolve(); - }; - WelcomeViewModel.prototype.deactivate = function () { }; - return WelcomeViewModel; - }()); - Home.WelcomeViewModel = WelcomeViewModel; - })(Home = OneTrueError.Home || (OneTrueError.Home = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Incident/CloseViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Incident/CloseViewModel.js deleted file mode 100644 index 205193b9..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Incident/CloseViewModel.js +++ /dev/null @@ -1,72 +0,0 @@ -/// -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Incident; - (function (Incident) { - var CqsClient = Griffin.Cqs.CqsClient; - var ApplicationService = OneTrueError.Applications.ApplicationService; - var GetIncident = OneTrueError.Core.Incidents.Queries.GetIncident; - var CloseIncident = OneTrueError.Core.Incidents.Commands.CloseIncident; - var CloseViewModel = (function () { - function CloseViewModel() { - } - CloseViewModel.prototype.getTitle = function () { - return "Close incident"; - }; - CloseViewModel.prototype.activate = function (context) { - var _this = this; - this.context = context; - this.incidentId = parseInt(context.routeData["incidentId"]); - var query = new GetIncident(parseInt(context.routeData["incidentId"], 10)); - var incidentPromise = CqsClient.query(query); - incidentPromise.done(function (result) { return context.render(result); }); - var service = new ApplicationService(); - var appPromise = service.get(context.routeData["applicationId"]); - appPromise.done(function (result) { - _this.app = result; - }); - P.when(incidentPromise, appPromise) - .then(function (result) { - context.resolve(); - }); - context.handle.click("#saveSolution", function (evt) { return _this.onCloseIncident(); }); - context.handle.click('[name="sendCustomerMessage"]', function (evt) { return _this.onToggleMessagePane(); }); - }; - CloseViewModel.prototype.deactivate = function () { }; - CloseViewModel.prototype.onToggleMessagePane = function () { - var panel = this.context.select.one("#status-panel"); - if (panel.style.display === "none") { - panel.style.display = ""; - } - else { - panel.style.display = "none"; - } - }; - CloseViewModel.prototype.onCloseIncident = function () { - var solution = this.context.select.one('[name="solution"]'); - var closeCmd = new CloseIncident(solution.value, this.incidentId); - var sendMessage = this.context.select.one('sendCustomerMessage'); - console.log(sendMessage); - if (sendMessage.checked) { - var subject = this.context.select.one('[name="UserSubject"]'); - var text = this.context.select.one('[name="UserText"]'); - if (subject.value.length === 0 || text.value.length === 0) { - alert("You specified that you wanted to send a notification to your users, but you have not specified subject or body of the message."); - return; - } - closeCmd.NotificationText = text.value; - closeCmd.CanSendNotification = true; - closeCmd.NotificationTitle = subject.value; - } - CqsClient.command(closeCmd); - window.location.hash = "#/application/" + this.context.routeData["applicationId"]; - humane.log("Incident have been closed."); - }; - return CloseViewModel; - }()); - Incident.CloseViewModel = CloseViewModel; - })(Incident = OneTrueError.Incident || (OneTrueError.Incident = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Incident/IgnoreViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Incident/IgnoreViewModel.js deleted file mode 100644 index 203c9085..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Incident/IgnoreViewModel.js +++ /dev/null @@ -1,48 +0,0 @@ -/// -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Incident; - (function (Incident) { - var CqsClient = Griffin.Cqs.CqsClient; - var ApplicationService = OneTrueError.Applications.ApplicationService; - var GetIncident = OneTrueError.Core.Incidents.Queries.GetIncident; - var IgnoreIncident = OneTrueError.Core.Incidents.Commands.IgnoreIncident; - var IgnoreViewModel = (function () { - function IgnoreViewModel() { - } - IgnoreViewModel.prototype.getTitle = function () { - return "Ignore incident"; - }; - IgnoreViewModel.prototype.activate = function (context) { - var _this = this; - this.context = context; - this.incidentId = parseInt(context.routeData["incidentId"]); - var query = new GetIncident(parseInt(context.routeData["incidentId"], 10)); - var incidentPromise = CqsClient.query(query); - incidentPromise.done(function (result) { return context.render(result); }); - var service = new ApplicationService(); - var appPromise = service.get(context.routeData["applicationId"]); - appPromise.done(function (result) { - _this.app = result; - }); - P.when(incidentPromise, appPromise) - .then(function (result) { - context.resolve(); - }); - context.handle.click("#ignoreIncident", function (evt) { return _this.onIgnoreIncident(); }); - }; - IgnoreViewModel.prototype.deactivate = function () { }; - IgnoreViewModel.prototype.onIgnoreIncident = function () { - var ignoreCmd = new IgnoreIncident(this.incidentId); - CqsClient.command(ignoreCmd); - humane.log("Incident have been marked as ignored."); - window.location.hash = "#/application/" + this.context.routeData["applicationId"]; - }; - return IgnoreViewModel; - }()); - Incident.IgnoreViewModel = IgnoreViewModel; - })(Incident = OneTrueError.Incident || (OneTrueError.Incident = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Incident/IncidentViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Incident/IncidentViewModel.js deleted file mode 100644 index cb706c5b..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Incident/IncidentViewModel.js +++ /dev/null @@ -1,163 +0,0 @@ -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Incident; - (function (Incident) { - var CqsClient = Griffin.Cqs.CqsClient; - var Pager = Griffin.WebApp.Pager; - var IncidentViewModel = (function () { - function IncidentViewModel(appScope) { - this.isIgnored = false; - } - IncidentViewModel.prototype.getTitle = function () { - return "Incident " + this.name; - }; - IncidentViewModel.prototype.activate = function (ctx) { - var _this = this; - var query = new OneTrueError.Core.Incidents.Queries.GetIncident(ctx.routeData["incidentId"]); - this.ctx = ctx; - CqsClient.query(query) - .done(function (response) { - _this.isIgnored = response.IsIgnored; - _this.name = response.Description; - _this.id = response.Id; - _this.applicationId = response.ApplicationId; - _this.pager = new Pager(0, 0, 0); - _this.pager.subscribe(_this); - _this.pager.draw(ctx.select.one("#pager")); - _this.renderInfo(response); - var query = new OneTrueError.Core.Reports.Queries.GetReportList(_this.id); - query.PageNumber = 1; - query.PageSize = 20; - CqsClient.query(query).done(function (result) { - _this.pager.update(result.PageNumber, result.PageSize, result.TotalCount); - _this.renderTable(1, result); - }); - var elem = ctx.select.one("#myChart"); - ctx.resolve(); - _this.renderInitialChart(elem, response.DayStatistics); - }); - ctx.handle.change('[name="range"]', function (e) { return _this.onRange(e); }); - }; - IncidentViewModel.prototype.deactivate = function () { - }; - IncidentViewModel.prototype.onPager = function (pager) { - var _this = this; - var query = new OneTrueError.Core.Reports.Queries.GetReportList(this.id); - query.PageNumber = pager.currentPage; - query.PageSize = 20; - CqsClient.query(query).done(function (result) { - _this.renderTable(1, result); - }); - }; - IncidentViewModel.prototype.onRange = function (e) { - var elem = e.target; - var days = parseInt(elem.value, 10); - this.loadChartInfo(days); - }; - IncidentViewModel.prototype.renderInitialChart = function (chartElement, stats) { - var labels = new Array(); - var dataset = new OneTrueError.Dataset(); - dataset.label = "Error reports"; - dataset.data = new Array(); - stats.forEach(function (item) { - labels.push(new Date(item.Date).toLocaleDateString()); - dataset.data.push(item.Count); - }); - var data = new OneTrueError.LineData(); - data.datasets = [dataset]; - data.labels = labels; - this.lineChart = new OneTrueError.LineChart(chartElement); - this.lineChart.render(data); - //this.loadChartInfo(30); - }; - IncidentViewModel.prototype.renderTable = function (pageNumber, data) { - var self = this; - var directives = { - Items: { - CreatedAtUtc: { - text: function (value, dto) { - return new Date(value).toLocaleString(); - } - }, - Message: { - text: function (value, dto) { - if (!value) { - return "(No exception message)"; - } - return dto.Message; - }, - href: function (value, dto) { - return "#/application/" + self.applicationId + "/incident/" + self.id + "/report/" + dto.Id; - } - } - } - }; - this.ctx.renderPartial("#reportsTable", data, directives); - }; - IncidentViewModel.prototype.renderInfo = function (dto) { - var self = this; - if (dto.IsSolved) { - dto.Tags.push("solved"); - } - var directives = { - CreatedAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - UpdatedAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - SolvedAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - Tags: { - "class": function (value) { - if (value === "solved") - return "tag bg-danger"; - return "tag nephritis"; - }, - text: function (value) { - return value; - }, - href: function (value) { - return "http://stackoverflow.com/search?q=%5B" + value + "%5D+" + dto.Description; - } - } - }; - this.ctx.render(dto, directives); - if (dto.IsSolved) { - this.ctx.select.one("#actionButtons").style.display = "none"; - this.ctx.select.one('[data-name="Description"]').style.textDecoration = "line-through"; - } - }; - IncidentViewModel.prototype.loadChartInfo = function (days) { - var _this = this; - var query = new OneTrueError.Core.Incidents.Queries.GetIncidentStatistics(); - query.IncidentId = this.id; - query.NumberOfDays = days; - CqsClient.query(query) - .done(function (response) { - var dataset = new OneTrueError.Dataset(); - dataset.label = "Error reports"; - dataset.data = response.Values; - var data = new OneTrueError.LineData(); - data.datasets = [dataset]; - data.labels = response.Labels; - _this.lineChart.render(data); - }); - }; - IncidentViewModel.UP = "glyphicon-chevron-up"; - IncidentViewModel.DOWN = "glyphicon-chevron-down"; - return IncidentViewModel; - }()); - Incident.IncidentViewModel = IncidentViewModel; - })(Incident = OneTrueError.Incident || (OneTrueError.Incident = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Incident/IndexViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Incident/IndexViewModel.js deleted file mode 100644 index d2cb8d67..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Incident/IndexViewModel.js +++ /dev/null @@ -1,164 +0,0 @@ -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Incident; - (function (Incident) { - var CqsClient = Griffin.Cqs.CqsClient; - var IncidentOrder = OneTrueError.Core.Incidents.IncidentOrder; - var Yo = Griffin.Yo; - var IndexViewModel = (function () { - function IndexViewModel(dto) { - this.sortType = IncidentOrder.Newest; - this.sortAscending = false; - this.closed = false; - this.open = true; - this.reOpened = false; - } - IndexViewModel.prototype.getTitle = function () { - return "Incidents"; - }; - IndexViewModel.prototype.activate = function (ctx) { - var _this = this; - var query = new OneTrueError.Core.Incidents.Queries.FindIncidents(); - query.PageNumber = 1; - query.ItemsPerPage = 20; - CqsClient.query(query) - .done(function (response) { - var itemsElem = ctx.viewContainer.querySelector("#incidentTable"); - _this.renderTable(itemsElem, response); - ctx.resolve(); - _this.pager = new Griffin.WebApp.Pager(response.PageNumber, 20, response.TotalCount); - _this.pager.subscribe(_this); - _this.pager.draw(ctx.select.one("#pager")); - }); - ctx.handle.click("#btnClosed", function (e) { return _this.onBtnClosed(e); }); - ctx.handle.click("#btnActive", function (e) { return _this.onBtnActive(e); }); - ctx.handle.click("#btnIgnored", function (e) { return _this.onBtnIgnored(e); }); - ctx.handle.click("#LastReportCol", function (e) { return _this.onLastReportCol(e); }); - ctx.handle.click("#CountCol", function (e) { return _this.onCountCol(e); }); - }; - IndexViewModel.prototype.deactivate = function () { - }; - IndexViewModel.prototype.onPager = function (pager) { - this.loadItems(pager.currentPage); - }; - IndexViewModel.prototype.onBtnActive = function (e) { - e.preventDefault(); - this.reOpened = true; - this.open = true; - this.closed = false; - this.pager.reset(); - this.loadItems(0); - }; - IndexViewModel.prototype.onBtnClosed = function (e) { - e.preventDefault(); - this.reOpened = false; - this.open = false; - this.closed = true; - this.pager.reset(); - this.loadItems(0); - }; - IndexViewModel.prototype.onBtnIgnored = function (e) { - e.preventDefault(); - this.reOpened = false; - this.open = false; - this.closed = false; - this.pager.reset(); - this.loadItems(0); - }; - IndexViewModel.prototype.onCountCol = function (args) { - if (this.sortType !== IncidentOrder.MostReports) { - this.sortType = IncidentOrder.MostReports; - this.sortAscending = true; //will be changed below - } - if (this.sortAscending) { - } - else { - } - this.updateSorting(args.target); - this.loadItems(); - }; - IndexViewModel.prototype.onLastReportCol = function (args) { - if (this.sortType !== IncidentOrder.Newest) { - this.sortType = IncidentOrder.Newest; - this.sortAscending = false; //will be changed below - } - if (this.sortAscending) { - } - else { - } - this.updateSorting(args.target); - this.loadItems(); - }; - IndexViewModel.prototype.updateSorting = function (parentElement) { - this.sortAscending = !this.sortAscending; - var icon = IndexViewModel.UP; - if (!this.sortAscending) { - icon = IndexViewModel.DOWN; - } - $("#IndexView thead th span") - .removeClass("glyphicon-chevron-down") - .addClass("glyphicon " + icon) - .css("visibility", "hidden"); - $("span", parentElement) - .attr("class", "glyphicon " + icon) - .css("visibility", "inherit"); - }; - IndexViewModel.prototype.renderTable = function (target, data) { - var directives = { - Name: { - href: function (params, dto) { - return "#/application/" + dto.ApplicationId + "/incident/" + dto.Id; - }, - text: function (value) { - return value; - } - }, - ApplicationName: { - href: function (params, dto) { - return "#application/" + dto.ApplicationId + "/incidents/"; - }, - text: function (value) { - return value; - } - }, - LastUpdateAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - } - }; - Yo.G.render(target, data.Items, directives); - }; - IndexViewModel.prototype.loadItems = function (pageNumber) { - var _this = this; - if (pageNumber === void 0) { pageNumber = 0; } - var query = new OneTrueError.Core.Incidents.Queries.FindIncidents(); - query.SortType = this.sortType; - query.SortAscending = this.sortAscending; - query.Closed = this.closed; - query.Open = this.open; - query.ReOpened = this.reOpened; - query.Ignored = !this.reOpened && !this.closed && !this.open; - if (pageNumber === 0) { - query.PageNumber = this.pager.currentPage; - } - else { - query.PageNumber = pageNumber; - } - query.ItemsPerPage = 20; - CqsClient.query(query) - .done(function (response) { - //this.pager.update(response.PageNumber, 20, response.TotalCount); - _this.renderTable(document.getElementById("incidentTable"), response); - window.scrollTo(0, 0); - }); - }; - IndexViewModel.UP = "glyphicon-chevron-up"; - IndexViewModel.DOWN = "glyphicon-chevron-down"; - return IndexViewModel; - }()); - Incident.IndexViewModel = IndexViewModel; - })(Incident = OneTrueError.Incident || (OneTrueError.Incident = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Incident/OriginsViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Incident/OriginsViewModel.js deleted file mode 100644 index ec7c2ad9..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Incident/OriginsViewModel.js +++ /dev/null @@ -1,64 +0,0 @@ -/// -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Incident; - (function (Incident) { - var CqsClient = Griffin.Cqs.CqsClient; - var OriginsViewModel = (function () { - function OriginsViewModel() { - } - OriginsViewModel.prototype.getTitle = function () { - return "Error origins"; - }; - OriginsViewModel.prototype.activate = function (context) { - this.context = context; - context.resolve(); - var js = document.createElement("script"); - js.type = "text/javascript"; - js.src = "https://maps.googleapis.com/maps/api/js?key=AIzaSyBleXqcxCLRwuhcXk-3904HaJt9Vd1-CZc&libraries=visualization"; - this.context.viewContainer.appendChild(js); - //var myLatLng = { lat: -25.363, lng: 131.044 }; - //var marker = new google.maps.Marker({ - // position: myLatLng, - // map: map, - // title: 'Hello World!' - //}); - js.onload = function (e) { - var mapDiv = context.select.one('#map'); - var map = new google.maps.Map(mapDiv, { - zoom: 3, - center: { lat: 37.775, lng: -122.434 } - }); - google.maps.event.addDomListener(window, "resize", function () { - var center = map.getCenter(); - google.maps.event.trigger(map, "resize"); - map.setCenter(center); - }); - var query = new OneTrueError.Modules.ErrorOrigins.Queries.GetOriginsForIncident(context.routeData["incidentId"]); - CqsClient.query(query) - .done(function (response) { - var points = []; - response.Items.forEach(function (item) { - var point = new google.maps.LatLng(item.Latitude, item.Longitude); - for (var a = 0; a < item.NumberOfErrorReports; a++) { - points.push(point); - } - }); - var heatmap = new google.maps.visualization.HeatmapLayer({ - data: points, - map: map, - dissipating: false, - radius: 5 - }); - }); - }; - }; - OriginsViewModel.prototype.deactivate = function () { }; - return OriginsViewModel; - }()); - Incident.OriginsViewModel = OriginsViewModel; - })(Incident = OneTrueError.Incident || (OneTrueError.Incident = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Incident/SimilaritiesViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Incident/SimilaritiesViewModel.js deleted file mode 100644 index 164dfab1..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Incident/SimilaritiesViewModel.js +++ /dev/null @@ -1,112 +0,0 @@ -/// -/// -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Incident; - (function (Incident) { - var CqsClient = Griffin.Cqs.CqsClient; - var ViewRenderer = Griffin.Yo.Views.ViewRenderer; - var Similarities = OneTrueError.Modules.ContextData; - var SimilaritiesViewModel = (function () { - function SimilaritiesViewModel() { - } - SimilaritiesViewModel.prototype.activate = function (context) { - var _this = this; - this.incidentId = parseInt(context.routeData["incidentId"], 10); - this.ctx = context; - CqsClient.query(new Similarities.Queries.GetSimilarities(this.incidentId)) - .done(function (result) { - _this.dto = result; - context.render(result); - context.resolve(); - }); - //context.render(result); - context.handle.click('#ContextCollections', function (evt) { - var target = evt.target; - if (target.tagName === 'LI') { - _this.selectCollection(target.firstElementChild.textContent); - $('li', target.parentElement).removeClass('active'); - $(target).addClass('active'); - } - else if (target.tagName === 'A') { - _this.selectCollection(target.textContent); - $('li', target.parentElement.parentElement).removeClass('active'); - $(target.parentElement).addClass('active'); - } - }, true); - context.handle.click('#ContextProperty', function (evt) { - var target = evt.target; - if (target.tagName === 'LI') { - _this.selectProperty(target.firstElementChild.textContent); - $('li', target.parentElement).removeClass('active'); - $(target).addClass('active'); - } - else if (target.tagName === 'A') { - _this.selectProperty(target.textContent); - $('li', target.parentElement.parentElement).removeClass('active'); - $(target.parentElement).addClass('active'); - } - }); - // var service = new ApplicationService(); - // var appId = parseInt(context.routeData["applicationId"], 10); - // service.get(appId).done(result => { - // this.app = result; - // }) - // context.resolve(); - //}); - }; - SimilaritiesViewModel.prototype.getTitle = function () { - return "context data"; - }; - SimilaritiesViewModel.prototype.deactivate = function () { - }; - SimilaritiesViewModel.prototype.selectCollection = function (collectionName) { - var _this = this; - this.dto.Collections.forEach(function (item) { - if (item.Name === collectionName) { - var directives = { - SimilarityName: { - html: function (value, dto) { - return dto.Name; - } - } - }; - _this.currentCollection = item; - var container = _this.ctx.select.one('ContextProperty'); - container.style.display = ''; - var renderer = new ViewRenderer(container); - renderer.render(item.Similarities, directives); - _this.ctx.select.one("Values").style.display = 'none'; - return; - } - }); - }; - SimilaritiesViewModel.prototype.selectProperty = function (name) { - var _this = this; - var self = this; - this.currentCollection.Similarities.forEach(function (item) { - if (item.Name === name) { - var directives = { - Value: { - html: function (value, dto) { - return value; - } - } - }; - var elem = _this.ctx.select.one("Values"); - elem.style.display = ''; - var renderer = new ViewRenderer(elem); - renderer.render(item.Values, directives); - return; - } - }); - }; - SimilaritiesViewModel.VIEW_NAME = "SimilaritiesView"; - return SimilaritiesViewModel; - }()); - Incident.SimilaritiesViewModel = SimilaritiesViewModel; - })(Incident = OneTrueError.Incident || (OneTrueError.Incident = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Overview/OverviewViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Overview/OverviewViewModel.js deleted file mode 100644 index 1b4663eb..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Overview/OverviewViewModel.js +++ /dev/null @@ -1,244 +0,0 @@ -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Overview; - (function (Overview) { - var CqsClient = Griffin.Cqs.CqsClient; - var IncidentOrder = OneTrueError.Core.Incidents.IncidentOrder; - var Pager = Griffin.WebApp.Pager; - var FindIncidents = OneTrueError.Core.Incidents.Queries.FindIncidents; - var OverviewViewModel = (function () { - function OverviewViewModel() { - this._sortType = IncidentOrder.Newest; - this._sortAscending = false; - this._incidentType = 'active'; - this.pager = new Pager(0, 0, 0); - this.pager.subscribe(this); - } - OverviewViewModel.prototype.getTitle = function () { - return 'Overview'; - }; - OverviewViewModel.prototype.activate = function (ctx) { - var _this = this; - this._ctx = ctx; - var query = new OneTrueError.Web.Overview.Queries.GetOverview(); - CqsClient.query(query) - .done(function (response) { - _this.renderInfo(response); - ctx.resolve(); - _this.lineChart = new OneTrueError.LineChart(ctx.select.one("#myChart")); - _this.renderChart(response); - }); - var pagerElement = ctx.select.one("pager"); - this.pager.draw(pagerElement); - this.getIncidentsFromServer(1); - ctx.handle.change('[name="range"]', function (e) { return _this.OnRange(e); }); - ctx.handle.click('#btnClosed', function (e) { return _this.onBtnClosed(e); }); - ctx.handle.click('#btnActive', function (e) { return _this.onBtnActive(e); }); - ctx.handle.click('#btnIgnored', function (e) { return _this.onBtnIgnored(e); }); - ctx.handle.click('#LastReportCol', function (e) { return _this.onLastReportCol(e); }); - ctx.handle.click('#CountCol', function (e) { return _this.onCountCol(e); }); - }; - OverviewViewModel.prototype.deactivate = function () { - }; - OverviewViewModel.prototype.onPager = function (pager) { - this.getIncidentsFromServer(pager.currentPage); - var table = this._ctx.select.one("#incidentTable"); - //.scrollIntoView(true); - var y = this.findYPosition(table); - window.scrollTo(null, y - 50); //navbar - }; - OverviewViewModel.prototype.findYPosition = function (element) { - var curtop = 0; - if (element.offsetParent) { - do { - curtop += element.offsetTop; - element = (element.offsetParent); - } while (element); - return curtop; - } - }; - OverviewViewModel.prototype.OnRange = function (e) { - var _this = this; - var query = new OneTrueError.Web.Overview.Queries.GetOverview(); - var elem = e.target; - query.NumberOfDays = parseInt(elem.value, 10); - CqsClient.query(query) - .done(function (response) { - _this.renderChart(response); - }); - }; - OverviewViewModel.prototype.onBtnClosed = function (e) { - e.preventDefault(); - this._incidentType = 'closed'; - this.pager.reset(); - this.getIncidentsFromServer(0); - }; - OverviewViewModel.prototype.onBtnActive = function (e) { - e.preventDefault(); - this._incidentType = 'active'; - this.pager.reset(); - this.getIncidentsFromServer(0); - }; - OverviewViewModel.prototype.onBtnIgnored = function (e) { - e.preventDefault(); - this._incidentType = 'ignored'; - this.pager.reset(); - this.getIncidentsFromServer(0); - }; - OverviewViewModel.prototype.onCountCol = function (e) { - if (this._sortType !== IncidentOrder.MostReports) { - this._sortType = IncidentOrder.MostReports; - this._sortAscending = true; //will be changed below - } - this.updateSortingUI(e.target); - this.getIncidentsFromServer(this.pager.currentPage); - }; - OverviewViewModel.prototype.onLastReportCol = function (e) { - if (this._sortType !== IncidentOrder.Newest) { - this._sortType = IncidentOrder.Newest; - this._sortAscending = true; //will be changed below - } - this.updateSortingUI(e.target); - this.getIncidentsFromServer(this.pager.currentPage); - }; - OverviewViewModel.prototype.renderTable = function (pageNumber, data) { - var self = this; - var directives = { - Items: { - Name: { - text: function (value) { - return value; - }, - href: function (data, parentDto) { - return '#/application/' + parentDto.ApplicationId + '/incident/' + parentDto.Id; - } - }, - CreatedAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - LastUpdateAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - ApplicationName: { - text: function (value) { - return value; - }, - href: function (params, parentDto) { - return '#/application/' + parentDto.ApplicationId; - } - } - } - }; - if (data.TotalCount === 0) { - this._ctx.select.one('getting-started').style.display = ''; - } - this._ctx.renderPartial('#incidentTable', data, directives); - }; - OverviewViewModel.prototype.renderInfo = function (dto) { - var self = this; - var directives = { - CreatedAtUtc: { - text: function (params) { - return new Date(this.CreatedAtUtc).toLocaleString(); - } - }, - UpdatedAtUtc: { - text: function (params) { - return new Date(this.UpdatedAtUtc).toLocaleString(); - } - }, - SolvedAtUtc: { - text: function (params) { - return new Date(this.SolvedAtUtc).toLocaleString(); - } - }, - }; - this._ctx.render(dto, directives); - }; - OverviewViewModel.prototype.updateSortingUI = function (parentElement) { - this._sortAscending = !this._sortAscending; - var icon = OverviewViewModel.UP; - if (!this._sortAscending) { - icon = OverviewViewModel.DOWN; - } - $('#OverviewView thead th span') - .removeClass('glyphicon-chevron-down') - .addClass('glyphicon ' + icon) - .css('visibility', 'hidden'); - $('span', parentElement) - .attr('class', 'glyphicon ' + icon) - .css('visibility', 'inherit'); - }; - OverviewViewModel.prototype.getIncidentsFromServer = function (pageNumber) { - var _this = this; - var query = new FindIncidents(); - query.SortType = this._sortType; - query.SortAscending = this._sortAscending; - query.PageNumber = pageNumber; - query.ItemsPerPage = 10; - if (this._incidentType === 'closed') { - query.Closed = true; - query.Open = false; - } - //else if (this._incidentType === '') - CqsClient.query(query) - .done(function (response) { - if (_this.pager.pageCount === 0) { - _this.pager.update(response.PageNumber, response.PageSize, response.TotalCount); - } - _this.renderTable(pageNumber, response); - }); - }; - OverviewViewModel.prototype.renderChart = function (result) { - var data = new OneTrueError.LineData(); - data.datasets = []; - var legend = []; - var found = false; - var index = 0; - result.IncidentsPerApplication.forEach(function (app) { - var ds = new OneTrueError.Dataset(); - ds.label = app.Label; - ds.data = app.Values; - data.datasets.push(ds); - var l = { - label: app.Label, - color: OneTrueError.LineChart.LineThemes[index++].strokeColor - }; - legend.push(l); - found = true; - }); - var directives = { - color: { - text: function () { - return ''; - }, - style: function (value, dto) { - return 'display: inline; font-weight: bold; color: ' + dto.color; - } - }, - label: { - style: function (value, dto) { - return 'font-weight: bold; color: ' + dto.color; - } - } - }; - this._ctx.renderPartial('#chart-legend', legend, directives); - data.labels = result.TimeAxisLabels; - //if (data.) - this.lineChart.render(data); - this._ctx.renderPartial('StatSummary', result.StatSummary); - }; - OverviewViewModel.UP = 'glyphicon-chevron-up'; - OverviewViewModel.DOWN = 'glyphicon-chevron-down'; - return OverviewViewModel; - }()); - Overview.OverviewViewModel = OverviewViewModel; - })(Overview = OneTrueError.Overview || (OneTrueError.Overview = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/Report/ReportViewModel.js b/src/Server/OneTrueError.Web/ViewModels/Report/ReportViewModel.js deleted file mode 100644 index 42ea06e0..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/Report/ReportViewModel.js +++ /dev/null @@ -1,95 +0,0 @@ -/// -/// -/// -/// -var OneTrueError; -(function (OneTrueError) { - var Report; - (function (Report) { - var CqsClient = Griffin.Cqs.CqsClient; - var ReportViewModel = (function () { - function ReportViewModel() { - } - ReportViewModel.prototype.renderView = function () { - var directives = { - CreatedAtUtc: { - text: function (value) { - return new Date(value).toLocaleString(); - } - }, - ContextCollections: { - ContextCollectionName: { - html: function (value, dto) { - return dto.Name; - }, - href: function (value, dto) { - return '#' + dto.Name; - } - } - } - }; - this.context.render(this.dto, directives); - }; - ReportViewModel.prototype.getTitle = function () { - return 'Report'; - }; - ReportViewModel.prototype.activate = function (context) { - var _this = this; - this.context = context; - var reportId = context.routeData["reportId"]; - var query = new OneTrueError.Core.Reports.Queries.GetReport(reportId); - CqsClient.query(query) - .done(function (dto) { - _this.dto = dto; - _this.renderView(); - context.resolve(); - }); - context.handle.click('[data-collection="ContextCollections"]', function (evt) { - evt.preventDefault(); - var target = evt.target; - if (target.tagName === 'LI') { - _this.selectCollection(target.firstElementChild.textContent); - $('li', target.parentElement).removeClass('active'); - $(target).addClass('active'); - } - else if (target.tagName === 'A') { - _this.selectCollection(target.textContent); - $('li', target.parentElement.parentElement).removeClass('active'); - $(target.parentElement).addClass('active'); - } - }, true); - }; - ReportViewModel.prototype.selectCollection = function (collectionName) { - var _this = this; - this.dto.ContextCollections.forEach(function (item) { - if (item.Name === collectionName) { - var directives = { - Properties: { - Key: { - html: function (value) { - return value; - } - }, - Value: { - html: function (value, dto) { - if (collectionName === 'Screenshots') { - return 'Embedded Image'; - } - else { - return value.replace(/;;/g, "
"); - } - } - } - } - }; - _this.context.renderPartial('propertyTable', item, directives); - return; - } - }); - }; - ReportViewModel.prototype.deactivate = function () { }; - return ReportViewModel; - }()); - Report.ReportViewModel = ReportViewModel; - })(Report = OneTrueError.Report || (OneTrueError.Report = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/User/NotificationsViewModel.js b/src/Server/OneTrueError.Web/ViewModels/User/NotificationsViewModel.js deleted file mode 100644 index e6a1a38f..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/User/NotificationsViewModel.js +++ /dev/null @@ -1,42 +0,0 @@ -/// -/// -var OneTrueError; -(function (OneTrueError) { - var User; - (function (User) { - var cqs = Griffin.Cqs.CqsClient; - var GetUserSettings = OneTrueError.Core.Users.Queries.GetUserSettings; - var CqsClient = Griffin.Cqs.CqsClient; - var NotificationsViewModel = (function () { - function NotificationsViewModel() { - } - NotificationsViewModel.prototype.saveSettings_click = function (e) { - e.isHandled = true; - var dto = this.ctx.readForm('NotificationsView'); - var cmd = new OneTrueError.Core.Users.Commands.UpdateNotifications(); - cmd.NotifyOnNewIncidents = dto.NotifyOnNewIncidents; - cmd.NotifyOnNewReport = dto.NotifyOnNewReport; - cmd.NotifyOnPeaks = dto.NotifyOnPeaks; - cmd.NotifyOnReOpenedIncident = dto.NotifyOnReOpenedIncident; - cmd.NotifyOnUserFeedback = dto.NotifyOnUserFeedback; - CqsClient.command(cmd); - humane.log("Settings have been saved."); - }; - NotificationsViewModel.prototype.getTitle = function () { return "Notifications settings"; }; - NotificationsViewModel.prototype.activate = function (context) { - var _this = this; - this.ctx = context; - context.handle.click("#saveSettings", function (ev) { return _this.saveSettings_click(ev); }); - var query = new GetUserSettings(); - cqs.query(query).done(function (result) { - context.render(result.Notifications); - context.resolve(); - }); - }; - NotificationsViewModel.prototype.deactivate = function () { - }; - return NotificationsViewModel; - }()); - User.NotificationsViewModel = NotificationsViewModel; - })(User = OneTrueError.User || (OneTrueError.User = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/ViewModels/User/SettingsViewModel.js b/src/Server/OneTrueError.Web/ViewModels/User/SettingsViewModel.js deleted file mode 100644 index 047cabb8..00000000 --- a/src/Server/OneTrueError.Web/ViewModels/User/SettingsViewModel.js +++ /dev/null @@ -1,64 +0,0 @@ -/// -/// -var OneTrueError; -(function (OneTrueError) { - var User; - (function (User) { - var cqs = Griffin.Cqs.CqsClient; - var CqsClient = Griffin.Cqs.CqsClient; - var SettingsViewModel = (function () { - function SettingsViewModel() { - } - SettingsViewModel.prototype.changePassword_click = function (e) { - var _this = this; - e.preventDefault(); - var dto = this.context.readForm("PasswordView"); - if (dto.NewPassword !== dto.NewPassword2) { - humane.error("New passwords do not match."); - return; - } - if (!dto.CurrentPassword) { - humane.error("You must enter the current password."); - return; - } - var cmd = new OneTrueError.Core.Accounts.Requests.ChangePassword(dto.CurrentPassword, dto.NewPassword); - CqsClient.request(cmd) - .done(function (result) { - if (result.Success) { - _this.context.render({ NewPassword: "", NewPassword2: "", CurrentPassword: "" }); - humane.log("Password have been changed."); - } - else { - humane.error("Password could not be changed. Did you enter your current password correctly?"); - } - }); - }; - SettingsViewModel.prototype.saveSettings_click = function (e) { - e.isHandled = true; - var dto = this.context.readForm("PersonalSettings"); - var cmd = new OneTrueError.Core.Users.Commands.UpdatePersonalSettings(); - cmd.FirstName = dto.FirstName; - cmd.LastName = dto.LastName; - cmd.MobileNumber = dto.MobileNumber; - CqsClient.command(cmd); - humane.log("Settings have been saved."); - }; - SettingsViewModel.prototype.getTitle = function () { return "Personal settings"; }; - SettingsViewModel.prototype.activate = function (context) { - var _this = this; - this.context = context; - context.handle.click("[name=\"saveSettings\"]", function (ev) { return _this.saveSettings_click(ev); }); - context.handle.click("[name='changePassword']", function (ev) { return _this.changePassword_click(ev); }); - var query = new OneTrueError.Core.Users.Queries.GetUserSettings(); - cqs.query(query).done(function (result) { - context.render(result); - context.resolve(); - }); - }; - SettingsViewModel.prototype.deactivate = function () { - }; - return SettingsViewModel; - }()); - User.SettingsViewModel = SettingsViewModel; - })(User = OneTrueError.User || (OneTrueError.User = {})); -})(OneTrueError || (OneTrueError = {})); diff --git a/src/Server/OneTrueError.Web/app/Application.js.map b/src/Server/OneTrueError.Web/app/Application.js.map index 8c42f9b0..4e2b2e2b 100644 --- a/src/Server/OneTrueError.Web/app/Application.js.map +++ b/src/Server/OneTrueError.Web/app/Application.js.map @@ -1 +1 @@ -{"version":3,"file":"Application.js","sourceRoot":"","sources":["Application.ts"],"names":[],"mappings":"AAAC,sDAAsD;AACvD,kDAAkD;AAClD,+CAA+C;AAC/C,6CAA6C;AAE7C,IAAO,YAAY,CA0BlB;AA1BD,WAAO,YAAY;IAAC,IAAA,YAAY,CA0B/B;IA1BmB,WAAA,YAAY,EAAC,CAAC;QAC9B,IAAO,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;QACvB,IAAO,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QAEzC;YAAA;YAqBA,CAAC;YAnBU,gCAAG,GAAV,UAAW,aAAqB;gBAC5B,IAAI,GAAG,GAAG,CAAC,CAAC,KAAK,EAAmE,CAAC;gBAErF,IAAI,SAAS,GAAoE,EAAE,CAAC,YAAY,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;gBACjI,EAAE,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC,CAAC;oBAC9C,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBACvB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;gBACzB,CAAC;gBAED,IAAI,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;gBAC5E,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;gBACpC,SAAS,CAAC,KAAK,CAAqD,KAAK,CAAC;qBACrE,IAAI,CAAC,UAAA,MAAM;oBACZ,EAAE,CAAC,YAAY,CAAC,gBAAgB,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC;oBACzD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBACxB,CAAC,CAAC,CAAC;gBAEH,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACzB,CAAC;YACL,yBAAC;QAAD,CAAC,AArBD,IAqBC;QArBY,+BAAkB,qBAqB9B,CAAA;IACL,CAAC,EA1BmB,YAAY,GAAZ,yBAAY,KAAZ,yBAAY,QA0B/B;AAAD,CAAC,EA1BM,YAAY,KAAZ,YAAY,QA0BlB;AAAA,CAAC"} \ No newline at end of file +{"version":3,"file":"Application.js","sourceRoot":"","sources":["Application.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,kDAAkD;AAClD,+CAA+C;AAC/C,6CAA6C;AAE7C,IAAO,YAAY,CA0BlB;AA1BD,WAAO,YAAY;IAAC,IAAA,YAAY,CA0B/B;IA1BmB,WAAA,YAAY,EAAC,CAAC;QAC9B,IAAO,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;QACvB,IAAO,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;QAEzC;YAAA;YAqBA,CAAC;YAnBU,gCAAG,GAAV,UAAW,aAAqB;gBAC5B,IAAI,GAAG,GAAG,CAAC,CAAC,KAAK,EAAmE,CAAC;gBAErF,IAAI,SAAS,GAAoE,EAAE,CAAC,YAAY,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;gBACjI,EAAE,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,EAAE,KAAK,aAAa,CAAC,CAAC,CAAC;oBAC9C,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBACvB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;gBACzB,CAAC;gBAED,IAAI,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;gBAC5E,KAAK,CAAC,aAAa,GAAG,aAAa,CAAC;gBACpC,SAAS,CAAC,KAAK,CAAqD,KAAK,CAAC;qBACrE,IAAI,CAAC,UAAA,MAAM;oBACZ,EAAE,CAAC,YAAY,CAAC,gBAAgB,CAAC,aAAa,CAAC,GAAG,MAAM,CAAC;oBACzD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBACxB,CAAC,CAAC,CAAC;gBAEH,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACzB,CAAC;YACL,yBAAC;QAAD,CAAC,AArBD,IAqBC;QArBY,+BAAkB,qBAqB9B,CAAA;IACL,CAAC,EA1BmB,YAAY,GAAZ,yBAAY,KAAZ,yBAAY,QA0B/B;AAAD,CAAC,EA1BM,YAAY,KAAZ,YAAY,QA0BlB;AAAA,CAAC"} \ No newline at end of file diff --git a/src/Server/OneTrueError.Web/packages.config b/src/Server/OneTrueError.Web/packages.config index d0f7a441..c6f20e94 100644 --- a/src/Server/OneTrueError.Web/packages.config +++ b/src/Server/OneTrueError.Web/packages.config @@ -7,7 +7,7 @@ - + diff --git a/src/Server/OneTrueError.sln b/src/Server/OneTrueError.sln index e0e3b85c..fb7ccb98 100644 --- a/src/Server/OneTrueError.sln +++ b/src/Server/OneTrueError.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.25123.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneTrueError.Web", "OneTrueError.Web\OneTrueError.Web.csproj", "{0476895C-6A61-4DE1-B06B-E8BF496FB651}" EndProject @@ -19,6 +19,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneTrueError.App.Tests", "O EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneTrueError.Infrastructure", "OneTrueError.Data.Common\OneTrueError.Infrastructure.csproj", "{A78A50DA-C9D7-47F2-8528-D7EE39D91924}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneTrueError.Api.Client", "OneTrueError.Api.Client\OneTrueError.Api.Client.csproj", "{017F8863-3DE0-4AD2-9ED3-5ACB87BBBCD0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneTrueError.Api.Client.Tests", "OneTrueError.Api.Client.Tests\OneTrueError.Api.Client.Tests.csproj", "{62989500-31BC-44FA-97CA-84F484C6F1AA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -57,6 +61,14 @@ Global {A78A50DA-C9D7-47F2-8528-D7EE39D91924}.Debug|Any CPU.Build.0 = Debug|Any CPU {A78A50DA-C9D7-47F2-8528-D7EE39D91924}.Release|Any CPU.ActiveCfg = Release|Any CPU {A78A50DA-C9D7-47F2-8528-D7EE39D91924}.Release|Any CPU.Build.0 = Release|Any CPU + {017F8863-3DE0-4AD2-9ED3-5ACB87BBBCD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {017F8863-3DE0-4AD2-9ED3-5ACB87BBBCD0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {017F8863-3DE0-4AD2-9ED3-5ACB87BBBCD0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {017F8863-3DE0-4AD2-9ED3-5ACB87BBBCD0}.Release|Any CPU.Build.0 = Release|Any CPU + {62989500-31BC-44FA-97CA-84F484C6F1AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62989500-31BC-44FA-97CA-84F484C6F1AA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62989500-31BC-44FA-97CA-84F484C6F1AA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62989500-31BC-44FA-97CA-84F484C6F1AA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE