update of some deps + fixed cookie bug #1

* Updated `Readme`
* Fixed cookie bug
* Added `Jira OAuth` support
* Updated dependencies:
	* `Bootstrap` and `Bootswatch`: `4` to `5` major release
	* `jQuery` minor update to `3.7.1`
	* `fontawesome`: `5` to `6` major release
	* `Atlassian SDK` to `13.0.0` version
* migtateed to bs5 and rebase this commit
This commit is contained in:
STAM 2024-09-23 16:30:12 +03:00
parent ce30acbc17
commit 257ab40ce3
No known key found for this signature in database
GPG Key ID: 711526C6938897F1
4298 changed files with 1098932 additions and 1723 deletions

View File

@ -1,8 +1,17 @@
# Changelog # Changelog
## 2024 ## 2024
* `sep` * `sep`
* `2.0.0.0` - New Major release:
* Migrated to `dotnet8`
* Updated `Readme`
* Fixed cookie bug
* Added `Jira OAuth` support
* Updated dependencies:
* `Bootstrap` and `Bootswatch`: `4` to `5` major release
* `jQuery` minor update to `3.7.1`
* `fontawesome`: `5` to `6` major release
* `Atlassian SDK` to `13.0.0` version
* `1.0.0.17` - public release * `1.0.0.17` - public release
* `WIP`: migrating to `dotnet8` and bugfixes.
------------------------------------------------------------------- -------------------------------------------------------------------
## 2020 ## 2020
* `1.0.0.17` - internal stable release. * `1.0.0.17` - internal stable release.

136
README.md
View File

@ -7,7 +7,82 @@
Jira Quick Issue Creator - webtool for quick creation and checking issues from Jira instance by customers. Jira Quick Issue Creator - webtool for quick creation and checking issues from Jira instance by customers.
### Supported themes: ## Supported Platforms:
* Checked with `Jira Server and DataCenter` editions and versions from `7.x` to `10.x` with `JiraAuthTypeBasic`.
* Cloud versions `technically` supported via `JiraAuthTypeOAuth` but *NOT* tested.
# Full `appsettings.json` example:
```
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Jira": {
"Domain": "",
"AuthType": "Basic", //Oauth
"JiraAuthTypeBasic": {
"Login": "",
"Password": ""
},
"JiraAuthTypeOAuth": {
"ConsumerKey": "",
"ConsumerSecret": "",
"AccessToken": "",
"TokenSecret": ""
},
"AllowedProjects": [
"",
""
],
"AllowedIssueTypes": [
"",
""
]
},
"UI": {
"Theme": "",
"LogoUrl": "",
"HeaderText": "",
"DescriptionText": "",
"LicensedTo": ""
},
"Captcha": {
"key": "",
"secret": ""
}
}
```
### Descriptions of some options
* `AuthType` - kind of auth type. `Basic` or `OAuth`. How to setup `OAuth` - described [here](https://developer.atlassian.com/server/jira/platform/oauth/).
* `Captcha` - is optionan section. Official google Captcha docs [here](https://www.google.com/recaptcha/about/).
* `AllowedProjects` - list of allowed projects to connect. Use `Jira's Project Key`.
* `AllowedIssueTypes` - list of allowed project types to connect. Kind of `Bug`, `Task`, etc. Get names from your Jira Admin section of instance.
### Logging
File `appSettings.json` contains additional settings, like [loglevel](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel?view=dotnet-plat-ext-5.0#fields) and [console output theme](https://github.com/serilog/serilog-sinks-console). You can set it up via editing this file.
#### Supported log levels
| Level | Enum | Description
|-------------|:-------------:|-------------|
| `Critical` | `5` | Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires immediate attention.
| `Debug` | `1` | Logs that are used for interactive investigation during development. These logs should primarily contain information useful for debugging and have no long-term value.
| `Error` | `4` | Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a failure in the current activity, not an application-wide failure.
| `Information` | `2` | Logs that track the general flow of the application. These logs should have long-term value.
| `None` | `6` | Not used for writing log messages. Specifies that a logging category should not write any messages.
| `Trace` | `0` | Logs that contain the most detailed messages. These messages may contain sensitive application data. These messages are disabled by default and should never be enabled in a production environment.
| `Warning` | `3` | Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the application execution to stop.
### Themes:
Set theme in UI section of appsettings.json: Set theme in UI section of appsettings.json:
@ -17,7 +92,7 @@ Set theme in UI section of appsettings.json:
``` ```
of via enviroment-file vars or compose-file: of via enviroment-file vars or compose-file:
``` ```
- UI_Theme: default - UI__Theme: default
``` ```
Themes: Themes:
@ -33,7 +108,9 @@ Themes:
* `lux` * `lux`
* `materia` * `materia`
* `minty` * `minty`
* `morph`
* `pulse` * `pulse`
* `quartz`
* `sandstone` * `sandstone`
* `simplex` * `simplex`
* `sketchy` * `sketchy`
@ -42,10 +119,65 @@ Themes:
* `spacelab` * `spacelab`
* `superhero` * `superhero`
* `united` * `united`
* `vapor`
* `yeti` * `yeti`
* `zephyr`
You cah check live demos at official https://bootswatch.com/ site. You cah check live demos at official https://bootswatch.com/ site.
## Setup envs
1. Read officia Microsoft docs [here](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-8.0)
2. Setup.
### ENV example (docker-compose.yml):
```
- AllowedHosts: "*"
<...>
- UI__LicensedTo: "Me"
- UI__Theme: "darkly"
- UI__HeaderText: "Header"
- UI__DescriptionText: "Description"
<...>
- Jira__Domain: "https://my-selfhosted-jira.local"
- Jira__AuthType: "Basic"
- Jira__AuthType__JiraAuthTypeBasic__Login: "my-user"
- Jira__AuthType__JiraAuthTypeBasic__Password: my-user-password"
- Jira__AllowedProjects__0: "KEY0"
- Jira__AllowedProject__1: "KEY1"
- Jira__AllowedIssueTypes__0: "Bug"
- Jira__AllowedIssueTypes__1: "Support"
- Jira__AllowedIssueTypes__2: "Feedback"
- Jira__AllowedIssueTypes__3: "Story"
<...>
- Captcha__key: "key"
- Captcha__secret: "secret"
<...>
```
#### example
```
```
# Used componets:
| Compoment | Link | Version |
|---------------------------------|-----------------------------------------------------|-----------|
| .NET 8 (ASP.NET Core) | [dotnet.microsoft.com](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) | 8.0 |
| jQuery | [jquery.com](https://jquery.com/) | 3.7.1 |
| jQuery Localization Plugin | [github.com/coderifous/jquery-localize](https://github.com/coderifous/jquery-localize) | 0.2.0 |
| jQuery Validation Plugin | [github.com/jquery-validation/jquery-validation](https://github.com/jquery-validation/jquery-validation) | 1.19.3 |
| jQuery Validation Unobtrusive | [github.com/aspnet/jquery-validation-unobtrusive](https://github.com/aspnet/jquery-validation-unobtrusive) | 3.2.12 |
| Bootstrap | [getbootstrap.com](https://getbootstrap.com/) | 5.3.3 |
| Bootswatch | [bootswatch.com](https://bootswatch.com/) | 5.3 |
| FontAwesome | [fontawesome.com](https://fontawesome.com/) | 6.6.0 |
| Flaticon (Freepik) | [flaticon.com/authors/freepik](https://www.flaticon.com/authors/freepik) | - |
Если нужно внести изменения или дополнить информацию, дайте знать!
# [Stargazers](https://github.com/EpicMorg/jira-issue-web-reporter/stargazers) # [Stargazers](https://github.com/EpicMorg/jira-issue-web-reporter/stargazers)
# [Forkers](https://github.com/EpicMorg/jira-issue-web-reporter/network/members) # [Forkers](https://github.com/EpicMorg/jira-issue-web-reporter/network/members)

View File

@ -1,6 +1,11 @@
#version: '3' #version: '3'
services: services:
app: app:
image: "epicmorg/jira-issue-web-reporter-docker:latest"
build:
context: .
services:
app-develop:
image: "epicmorg/jira-issue-web-reporter-docker:develop" image: "epicmorg/jira-issue-web-reporter-docker:develop"
build: build:
context: . context: .

View File

@ -5,19 +5,50 @@
public class JiraConfig public class JiraConfig
{ {
[Url] [Url]
public string Domain { get; set; } public required string Domain { get; set; }
[Required] [Required]
public string Login { get; set; } public required string[] AllowedProjects { get; set; }
[Required] [Required]
public string Password { get; set; } public required string[] AllowedIssueTypes { get; set; }
[Required] [Required]
public string[] AllowedProjects { get; set; } public required JiraAuthTypes AuthType { get; set; }
public JiraAuthTypeBasic? JiraAuthTypeBasic { get; set; }
public JiraAuthTypeOAuth? JiraAuthTypeOAuth { get; set; }
}
public class JiraAuthTypeBasic
{
[Required]
public required string Login { get; set; }
[Required] [Required]
public string[] AllowedIssueTypes { get; set; } public required string Password { get; set; }
}
public class JiraAuthTypeOAuth
{
[Required]
public required string ConsumerKey { get; set; }
[Required]
public required string ConsumerSecret { get; set; }
[Required]
public required string AccessToken { get; set; }
[Required]
public required string TokenSecret { get; set; }
}
public enum JiraAuthTypes
{
OAuth,
Basic,
} }
} }

View File

@ -4,6 +4,7 @@
using epicmorg.jira.issue.web.reporter.Models.Configuration; using epicmorg.jira.issue.web.reporter.Models.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System;
public static class AtlassianExtensions public static class AtlassianExtensions
{ {
@ -12,14 +13,27 @@
services.AddScoped<Jira>(context => services.AddScoped<Jira>(context =>
{ {
var jiraOptions = context.GetService<IOptions<JiraConfig>>().Value; var jiraOptions = context.GetService<IOptions<JiraConfig>>().Value;
var client = Jira.CreateRestClient(
jiraOptions.Domain,
jiraOptions.Login, var client = jiraOptions.AuthType switch
jiraOptions.Password, {
new JiraRestClientSettings JiraAuthTypes.Basic => Jira.CreateRestClient(
url: jiraOptions.Domain,
username: jiraOptions.JiraAuthTypeBasic.Login,
password: jiraOptions.JiraAuthTypeBasic.Password,
settings: new JiraRestClientSettings
{ {
Cache = new Atlassian.Jira.JiraCache(), Cache = new Atlassian.Jira.JiraCache(),
}); }),
JiraAuthTypes.OAuth => Jira.CreateOAuthRestClient(
url: jiraOptions.Domain,
consumerKey: jiraOptions.JiraAuthTypeOAuth.ConsumerKey,
consumerSecret: jiraOptions.JiraAuthTypeOAuth.ConsumerSecret,
oAuthAccessToken: jiraOptions.JiraAuthTypeOAuth.AccessToken,
oAuthTokenSecret: jiraOptions.JiraAuthTypeOAuth.TokenSecret),
_ => throw new Exception($"Invalid auth type!: {jiraOptions.AuthType}")
};
return client; return client;
}); });
return services; return services;

View File

@ -11,6 +11,7 @@ namespace epicmorg.jira.issue.web.reporter
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
public class Startup public class Startup
{ {
@ -41,7 +42,9 @@ namespace epicmorg.jira.issue.web.reporter
.AddAntiforgery(o => .AddAntiforgery(o =>
{ {
o.SuppressXFrameOptionsHeader = true; o.SuppressXFrameOptionsHeader = true;
o.Cookie.SameSite = SameSiteMode.None; // o.Cookie.SameSite = SameSiteMode.None;
// o.Cookie.HttpOnly = true;
//o.Cookie.SecurePolicy = CookieSecurePolicy.Always;
}) })
.AddHttpClient() .AddHttpClient()
.AddHttpClient<ICaptchaValidator, GoogleRecaptchaValidator>(); .AddHttpClient<ICaptchaValidator, GoogleRecaptchaValidator>();
@ -73,7 +76,8 @@ namespace epicmorg.jira.issue.web.reporter
app.UseRouting(); app.UseRouting();
app.UseAuthorization(); // Some legacy
//app.UseAuthorization();
app.UseEndpoints(endpoints => app.UseEndpoints(endpoints =>
{ {

View File

@ -2,7 +2,7 @@
@model CheckRequest @model CheckRequest
<form asp-action="Check" id="form" asp-all-route-data="new Dictionary<string, string>()"> <form asp-action="Check" id="form" asp-all-route-data="new Dictionary<string, string>()">
<div class="mb-3"> <div class="mb-3">
<div class="form-group"> <div class="">
<div asp-validation-summary="ModelOnly" class="text-danger"></div> <div asp-validation-summary="ModelOnly" class="text-danger"></div>
<label asp-for="Issue"><i class="fas fa-keyboard"></i> <span data-localize="label-enter-issue-key">Enter issue key</span>:</label> <label asp-for="Issue"><i class="fas fa-keyboard"></i> <span data-localize="label-enter-issue-key">Enter issue key</span>:</label>
<input type="text" asp-for="Issue" class="form-control" placeholder="ABC-123" value="" required> <input type="text" asp-for="Issue" class="form-control" placeholder="ABC-123" value="" required>
@ -11,14 +11,14 @@
</div> </div>
<div class="mb-3"> <div class="mb-3">
<div class="form-group"> <div class="">
<div class="g-recaptcha" data-sitekey="@captchaConfig.Value.Key" data-callback="recaptchaCallback"></div> <div class="g-recaptcha" data-sitekey="@captchaConfig.Value.Key" data-callback="recaptchaCallback"></div>
</div> </div>
<span asp-validation-for="Captcha" class="text-danger"></span> <span asp-validation-for="Captcha" class="text-danger"></span>
</div> </div>
<div class="form-group"> <div class="">
<button class="btn btn-primary btn-lg btn-block" type="submit"><span data-localize="label-check">Check</span> <i class="fas fa-hand-pointer"></i></button> <button class="btn btn-primary btn-lg w-100" type="submit"><span data-localize="label-check">Check</span> <i class="fas fa-hand-pointer"></i></button>
</div> </div>
</form> </form>

View File

@ -1,29 +1,25 @@
@model CheckResponse @model CheckResponse
<div class="mb-3"> <div class="mb-3">
<div class="form-group"> <div class="">
<label for="disabled-ui-text"><i class="fas fa-keyboard"></i> <span data-localize="label-issue-key">Issue key</span>:</label> <label for="disabled-ui-text"><i class="fas fa-keyboard"></i> <span data-localize="label-issue-key">Issue key</span>:</label>
</div> </div>
</div> </div>
@if (!Model.Success) { @if (!Model.Success) {
<div class="alert alert-danger alert-dismissible fade show" role="alert"> <div class="alert alert-danger alert-dismissible fade show" role="alert">
<strong><i class="fas fa-exclamation-triangle"></i> <span data-localize="message-error">Error!</span></strong> <span data-localize="message-something-wrong-2">Something went wrong. Failed to create request.</span> @Model.Message <strong><i class="fas fa-exclamation-triangle"></i> <span data-localize="message-error">Error!</span></strong> <span data-localize="message-something-wrong-2">Something went wrong. Failed to create request.</span> @Model.Message
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
} else { } else {
<div class="mb-3"> <div class="mb-3">
<div class="card"> <div class="card">
<h5 class="card-header"><input asp-for="Issue" id="disabled-ui-text" class="form-control" readonly></h5> <h5 class="card-header">
<input asp-for="Issue" id="disabled-ui-text" class="form-control" readonly>
</h5>
<div class="card-body"> <div class="card-body">
@if (Model.Status != null) { @if (Model.Status != null) {
<p class="card-text"><span data-localize="message-status">Status</span>: <span class="badge badge-info">@Model.Status</span></p> <p class="card-text"><span data-localize="message-status">Status</span>: <span class="badge bg-info">@Model.Status</span></p>
} }
@if (Model.Resolution != null) { @if (Model.Resolution != null) {
<p class="card-text"><span data-localize="message-resolution">Resolution</span>: <span class="text-muted">@Model.Resolution</span></p> <p class="card-text"><span data-localize="message-resolution">Resolution</span>: <span class="text-muted">@Model.Resolution</span></p>
@ -31,16 +27,16 @@
</div> </div>
</div> </div>
</div> </div>
} }
<div class="row"> <div class="row">
<div class="col-sm-6 padding-fix"> <div class="col-sm-6 padding-fix">
<a class="btn btn-primary btn-lg btn-block" asp-action="Create"> <a class="btn btn-primary btn-lg w-100" asp-action="Create">
<i class="fas fa-bug"></i> <span data-localize="label-submit-another">Submit Another Issue</span> <i class="fas fa-bug"></i> <span data-localize="label-submit-another">Submit Another Issue</span>
</a> </a>
</div> </div>
<div class="col-sm-6 padding-fix"> <div class="col-sm-6 padding-fix">
<a class="btn btn-primary btn-lg btn-block" asp-action="Check"> <a class="btn btn-primary btn-lg w-100" asp-action="Check">
<i class="fas fa-search"></i> <span data-localize="label-check-another">Check Another Report</span> <i class="fas fa-search"></i> <span data-localize="label-check-another">Check Another Report</span>
</a> </a>
</div> </div>

View File

@ -6,40 +6,32 @@
<form asp-action="Create" enctype="multipart/form-data" id="form"> <form asp-action="Create" enctype="multipart/form-data" id="form">
<div asp-validation-summary="ModelOnly" class="alert alert-danger alert-dismissible fade show" role="alert"> <div asp-validation-summary="ModelOnly" class="alert alert-danger alert-dismissible fade show" role="alert">
<strong><i class="fas fa-exclamation-triangle"></i> <span data-localize="message-error">Error!</span></strong> <span data-localize="message-something-wrong">Something went wrong.</span> <strong><i class="fas fa-exclamation-triangle"></i> <span data-localize="message-error">Error!</span></strong> <span data-localize="message-something-wrong">Something went wrong.</span>
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<div class="form-group"> <label asp-for="Name" class="form-label"><i class="fas fa-user"></i> <span data-localize="label-fn">First name</span>:</label>
<label asp-for="Name" class="control-label"><i class="fas fa-user"></i> <span data-localize="label-fn">First name</span>:</label>
<input asp-for="Name" type="text" class="form-control" id="firstName" placeholder="" value="" required> <input asp-for="Name" type="text" class="form-control" id="firstName" placeholder="" value="" required>
<span asp-validation-for="Name" class="text-danger"></span> <span asp-validation-for="Name" class="text-danger"></span>
</div> </div>
</div>
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<div class="form-group"> <label asp-for="Email" class="form-label"><i class="far fa-envelope"></i> Email:</label>
<label asp-for="Email" class="control-label"><i class="far fa-envelope"></i> Email:</label>
<input asp-for="Email" type="email" class="form-control" id="email" placeholder="you@example.com"> <input asp-for="Email" type="email" class="form-control" id="email" placeholder="you@example.com">
<span asp-validation-for="Email" class="text-danger"></span> <span asp-validation-for="Email" class="text-danger"></span>
</div> </div>
</div> </div>
</div>
<div class="row"> <div class="row">
@if (Model.IssueTypes?.Count() > 1) @if (Model.IssueTypes?.Count() > 1)
{ {
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<div class="form-group"> <label asp-for="IssueType" class="form-label"><i class="fas fa-list"></i> <span data-localize="label-rep-type">Report type</span>:</label>
<label asp-for="IssueType" class="control-label"><i class="fas fa-list"></i> <span data-localize="label-rep-type">Report type</span>:</label> <select asp-for="IssueType" asp-items="@Model.IssueTypes" class="form-select d-block w-100" required>
<select asp-for="IssueType" asp-items="@Model.IssueTypes" class="form-control custom-select d-block w-100" required>
<option disabled selected data-localize="label-select">--- SELECT ---</option> <option disabled selected data-localize="label-select">--- SELECT ---</option>
</select> </select>
<span asp-validation-for="IssueType" class="text-danger"></span> <span asp-validation-for="IssueType" class="text-danger"></span>
</div> </div>
</div>
} }
else else
{ {
@ -48,14 +40,12 @@
@if (Model.Projects?.Count() > 1) @if (Model.Projects?.Count() > 1)
{ {
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<div class="form-group"> <label asp-for="Project" class="form-label"><i class="fas fa-list"></i> <span data-localize="label-project">Select project</span>:</label>
<label asp-for="Project" class="control-label"><i class="fas fa-list"></i> <span data-localize="label-project">Select project</span>:</label> <select class="form-select d-block w-100" asp-for="Project" asp-items="@Model.Projects" required>
<select class="custom-select d-block w-100 form-control" asp-for="Project" asp-items="@Model.Projects" required>
<option disabled selected data-localize="label-select">--- SELECT ---</option> <option disabled selected data-localize="label-select">--- SELECT ---</option>
</select> </select>
<span asp-validation-for="Project" class="text-danger"></span> <span asp-validation-for="Project" class="text-danger"></span>
</div> </div>
</div>
} }
else else
{ {
@ -64,32 +54,27 @@
</div> </div>
<div class="mb-3"> <div class="mb-3">
<div class="form-group"> <label asp-for="Description" class="form-label"><i class="fas fa-keyboard"></i> <span data-localize="label-description">Your description</span>:</label>
<label asp-for="Description" class="control-label"><i class="fas fa-keyboard"></i> <span data-localize="label-description">Your description</span>:</label>
<textarea asp-for="Description" class="form-control" rows="3"></textarea> <textarea asp-for="Description" class="form-control" rows="3"></textarea>
<span asp-validation-for="Description" class="text-danger"></span> <span asp-validation-for="Description" class="text-danger"></span>
</div> </div>
</div>
<div class="row"> <div class="row">
<div class="col-md-6 mb-3"> <div class="col-md-6 mb-3">
<div class="form-group"> <label asp-for="Files" class="form-label"><i class="fas fa-file-upload"></i> <span data-localize="label-attach-file">Attach file</span>:</label>
<label asp-for="Files" class="control-label"><i class="fas fa-file-upload"></i> <span data-localize="label-attach-file">Attach file</span>:</label> <input asp-for="Files" multiple type="file" class="form-control-file">
<input asp-for="Files" typeclass="form-control" multiple type="file" class="form-control-file">
<span asp-validation-for="Files" class="text-danger"></span> <span asp-validation-for="Files" class="text-danger"></span>
</div> </div>
</div> <div class="col-md-6 mb-3">
<div class="form-group col-md-6 mb-3">
<div class="g-recaptcha" data-sitekey="@captchaConfig.Value.Key"></div> <div class="g-recaptcha" data-sitekey="@captchaConfig.Value.Key"></div>
<span asp-validation-for="Captcha" class="text-danger"></span> <span asp-validation-for="Captcha" class="text-danger"></span>
</div> </div>
</div> </div>
<button class="btn btn-primary btn-lg btn-block" type="submit"><span data-localize="label-submit">Submit report</span> <i class="fas fa-paper-plane"></i></button> <button class="btn btn-primary btn-lg w-100" type="submit"><span data-localize="label-submit">Submit report</span> <i class="fas fa-paper-plane"></i></button>
</form> </form>
</div> </div>
</div> </div>
@section Head { @section Head {
<script src='https://www.google.com/recaptcha/api.js'></script> <script src='https://www.google.com/recaptcha/api.js'></script>
} }

View File

@ -6,33 +6,29 @@
<strong> <strong>
<i class="fas fa-hands-helping"></i> <span data-localize="message-awesome">Awesome!</span> <i class="fas fa-hands-helping"></i> <span data-localize="message-awesome">Awesome!</span>
</strong> </strong>
<span data-localize="message-reported-ok">You successfully send your report. Your issue-key is</span>: <span data-localize="message-reported-ok">You successfully sent your report. Your issue-key is</span>:
<strong> <strong>
<a asp-action="Check" asp-route-id="@Model.IssueKey">@Model.IssueKey</a> <a asp-action="Check" asp-route-id="@Model.IssueKey">@Model.IssueKey</a>
</strong>. </strong>.
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
} }
else else
{ {
<div class="alert alert-danger alert-dismissible fade show" role="alert"> <div class="alert alert-danger alert-dismissible fade show" role="alert">
<strong><i class="fas fa-exclamation-triangle"></i> <span data-localize="message-error">Error!</span></strong> <span data-localize="message-something-wrong">Something went wrong.</span> @Model.Message <strong><i class="fas fa-exclamation-triangle"></i> <span data-localize="message-error">Error!</span></strong> <span data-localize="message-something-wrong">Something went wrong.</span> @Model.Message
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
} }
<div class="row"> <div class="row">
<div class="col-sm-6 padding-fix"> <div class="col-sm-6 padding-fix">
<a class="btn btn-primary btn-lg btn-block" asp-action="Create"> <a class="btn btn-primary btn-lg w-100" asp-action="Create">
<i class="fas fa-bug"></i> <span data-localize="label-submit-another">Submit Another Issue</span> <i class="fas fa-bug"></i> <span data-localize="label-submit-another">Submit Another Issue</span>
</a> </a>
</div> </div>
<div class="col-sm-6 padding-fix"> <div class="col-sm-6 padding-fix">
<a class="btn btn-primary btn-lg btn-block" asp-action="Check"> <a class="btn btn-primary btn-lg w-100" asp-action="Check">
<i class="fas fa-search"></i> <span data-localize="label-check-another">Check Another Report</span> <i class="fas fa-search"></i> <span data-localize="label-check-another">Check Another Report</span>
</a> </a>
</div> </div>

View File

@ -4,7 +4,7 @@
<div class="col-sm-6 padding-fix"> <div class="col-sm-6 padding-fix">
<div class="card border-secondary"> <div class="card border-secondary">
<div class="card-body"> <div class="card-body">
<a class="btn btn-link btn-lg btn-block text-muted" asp-action="Create"> <a class="btn btn-link btn-lg w-100 text-muted" asp-action="Create">
<i class="fas fa-bug"></i> <span data-localize="btn-submit-new-issue">Submit New Issue</span> <i class="fas fa-bug"></i> <span data-localize="btn-submit-new-issue">Submit New Issue</span>
</a> </a>
</div> </div>
@ -13,7 +13,7 @@
<div class="col-sm-6 padding-fix"> <div class="col-sm-6 padding-fix">
<div class="card border-secondary"> <div class="card border-secondary">
<div class="card-body"> <div class="card-body">
<a class="btn btn-link btn-lg btn-block text-muted" asp-action="Check"> <a class="btn btn-link btn-lg w-100 text-muted" asp-action="Check">
<i class="fas fa-search"></i> <span data-localize="btn-check-report">Check Report</span> <i class="fas fa-search"></i> <span data-localize="btn-check-report">Check Report</span>
</a> </a>
</div> </div>

View File

@ -6,9 +6,10 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>@uiConfig.Value.HeaderText - @uiConfig.Value.GetAssemblyProduct</title> <title>@uiConfig.Value.HeaderText - @uiConfig.Value.GetAssemblyProduct</title>
<link href="~/lib/fontawesome/5.11.2-web/css/all.min.css" rel="stylesheet"> <link rel="stylesheet" href="~/lib/fontawesome/6.6.0/web/css/all.min.css" />
<link rel="stylesheet" href="~/lib/bootstrap/themes/@uiConfig.Value.Theme/bootstrap.min.css" /> <link rel="stylesheet" href="~/lib/fontawesome/6.6.0/web/css/v5-font-face.css" />
<link rel="stylesheet" href="~/css/site.css" /> <link rel="stylesheet" href="~/lib/bootstrap/5.3.3/themes/@uiConfig.Value.Theme/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/crap.css" />
@RenderSection("Head", required: false) @RenderSection("Head", required: false)
</head> </head>
<body> <body>
@ -41,7 +42,7 @@
</div> </div>
<div class="col-sm"> <div class="col-sm">
<p class="mb-1"> <p class="mb-1">
<i class="fas fa-key"></i> <span data-localize="label-licensed-to">Liceensed to</span>: @uiConfig.Value.LicensedTo <i class="fas fa-key"></i> <span data-localize="label-licensed-to">Licensed to</span>: @uiConfig.Value.LicensedTo
</p> </p>
</div> </div>
</div> </div>
@ -59,32 +60,28 @@
</li> </li>
<li class="list-inline-item"> <li class="list-inline-item">
<div class="dropdown dropup"> <div class="dropdown dropup">
<a class="dropdown-toggle" href="#" role="button" id="" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="dropdown-toggle" href="#" role="button" id="" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fas fa-language"></i> <span data-localize="lang-language">Language</span> <i class="fas fa-language"></i> <span data-localize="lang-language">Language</span>
</a> </a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<a class="dropdown-item" href="#" id="lang_en_btn"> <a class="dropdown-item" href="#" id="lang_en_btn">
<img height="16" src="~/lib/flags/png/260-united-kingdom.png" alt="" class="mr-2"> <img height="16" src="~/lib/flags/png/260-united-kingdom.png" alt="" class="me-2">
<span data-localize="lang-english">English</span> <span data-localize="lang-english">English</span>
</a> </a>
<a class="dropdown-item" href="#" id="lang_ru_btn"> <a class="dropdown-item" href="#" id="lang_ru_btn">
<img height="16" src="~/lib/flags/png/248-russia.png" alt="" class="mr-2"> <img height="16" src="~/lib/flags/png/248-russia.png" alt="" class="me-2">
<span data-localize="lang-rusian">Russian</span> <span data-localize="lang-rusian">Russian</span>
</a> </a>
</div> </div>
</div> </div>
</li> </li>
</ul> </ul>
</footer> </footer>
<script src="~/lib/jquery/3.7.1/jquery-3.7.1.min.js"></script>
<script src="~/lib/jquery/dist/jquery.min.js"></script> <script src="~/lib/jquery-localize/0.2.0/jquery.localize.min.js"></script>
<script src="~/lib/jquery-localize/jquery.localize.min.js"></script> <script src="~/lib/bootstrap/5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> <script src="~/js/crap.js" asp-append-version="true"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false) @RenderSection("Scripts", required: false)
</body> </body>
</html> </html>

View File

@ -1,5 +1,5 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script> <script src="~/lib/jquery-validation/1.19.5/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script> <script src="~/lib/jquery-validation-unobtrusive/4.0.0/dist/jquery.validate.unobtrusive.min.js"></script>
<script> <script>
window.onload = function () { window.onload = function () {
jQuery.validator.addMethod('checkCaptcha', function (value, element) { jQuery.validator.addMethod('checkCaptcha', function (value, element) {

View File

@ -5,5 +5,40 @@
"Microsoft": "Warning", "Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information" "Microsoft.Hosting.Lifetime": "Information"
} }
} },
"AllowedHosts": "*"
// "AllowedHosts": "*",
// "Jira": {
// "Domain": "",
// "AuthType": "Basic", //OAuth
// "JiraAuthTypeBasic": {
// "Login": "",
// "Password": ""
// },
// "JiraAuthTypeOAuth": {
// "ConsumerKey": "",
// "ConsumerSecret": "",
// "AccessToken": "",
// "TokenSecret": ""
// },
// "AllowedProjects": [
// "",
// ""
// ],
// "AllowedIssueTypes": [
// "",
// ""
// ]
// },
// "UI": {
// "Theme": "",
// "LogoUrl": "",
// "HeaderText": "",
// "DescriptionText": "",
// "LicensedTo": ""
// },
// "Captcha": {
// "key": "",
// "secret": ""
// }
} }

View File

@ -40,7 +40,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="Automapper" Version="13.0.1" /> <PackageReference Include="Automapper" Version="13.0.1" />
<PackageReference Include="Atlassian.SDK" Version="13.0.0" /> <PackageReference Include="Atlassian.SDK" Version="13.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.4" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.5" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Update="appsettings.Development.json"> <Content Update="appsettings.Development.json">

View File

@ -1,4 +1,6 @@
 /* crap.ss v1.0
-------------------------------------------------- */
a.navbar-brand { a.navbar-brand {
white-space: normal; white-space: normal;
text-align: center; text-align: center;

BIN
src/wwwroot/faviocn.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -1,5 +1,5 @@
$(document).ready(function () { $(document).ready(function () {
console.log("crap.js v1.1 inintialized"); console.log("crap.js v2.0 inintialized");
var userLang = navigator.language || navigator.userLanguage; var userLang = navigator.language || navigator.userLanguage;
@ -12,13 +12,13 @@
$.setRussianLang = function () { $.setRussianLang = function () {
$("#lang_en_btn").removeClass("active"); $("#lang_en_btn").removeClass("active");
$("#lang_ru_btn").addClass("active"); $("#lang_ru_btn").addClass("active");
$("[data-localize]").localize("site", { language: "ru", pathPrefix: "/lib/jquery-localize/lang/" }); $("[data-localize]").localize("site", { language: "ru", pathPrefix: "/json/lang/" });
}; };
$.setEnglishLang = function () { $.setEnglishLang = function () {
$("#lang_ru_btn").removeClass("active"); $("#lang_ru_btn").removeClass("active");
$("#lang_en_btn").addClass("active"); $("#lang_en_btn").addClass("active");
$("[data-localize]").localize("site", { language: "en", pathPrefix: "/lib/jquery-localize/lang/" }); $("[data-localize]").localize("site", { language: "en", pathPrefix: "/json/lang/" });
}; };
switch (localStorage.selectedLang) { switch (localStorage.selectedLang) {

Some files were not shown because too many files have changed in this diff Show More