Skip to content

Commit b2bf98e

Browse files
Release version 3.0.0
2 parents d49bcf8 + 6534608 commit b2bf98e

File tree

761 files changed

+2407
-2382
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

761 files changed

+2407
-2382
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
using IconCaptcha.Demo.ViewModels;
2+
using IconCaptcha.Exceptions;
3+
using Microsoft.AspNetCore.Mvc;
4+
5+
namespace IconCaptcha.Demo.Controllers
6+
{
7+
public class HomeController : Controller
8+
{
9+
private readonly IconCaptchaService _captcha;
10+
11+
public ActionResult Index()
12+
{
13+
return View();
14+
}
15+
16+
public HomeController(IconCaptchaService captcha)
17+
{
18+
_captcha = captcha;
19+
}
20+
21+
/// <summary>
22+
/// Handles the HTTP GET request for the regular, non-AJAX form page.
23+
/// </summary>
24+
[HttpGet("regular-form")]
25+
public ActionResult RegularForm()
26+
{
27+
return View(new SubmissionViewModel());
28+
}
29+
30+
/// <summary>
31+
/// Handles the HTTP POST request for submitting a regular, non-AJAX form.
32+
/// </summary>
33+
[HttpPost("regular-form-submit")]
34+
public ActionResult RegularFormSubmit()
35+
{
36+
var submissionViewModel = new SubmissionViewModel
37+
{
38+
Error = false,
39+
};
40+
41+
try
42+
{
43+
_captcha.ValidateSubmission();
44+
}
45+
catch (IconCaptchaSubmissionException e)
46+
{
47+
submissionViewModel.Error = true;
48+
submissionViewModel.ErrorMessage = e.Message;
49+
}
50+
51+
return View("RegularForm", submissionViewModel);
52+
}
53+
54+
/// <summary>
55+
/// Handles the HTTP GET request for the AJAX form page.
56+
/// </summary>
57+
[HttpGet("ajax-form")]
58+
public ActionResult AjaxForm()
59+
{
60+
return View();
61+
}
62+
63+
/// <summary>
64+
/// Handles the HTTP POST request for submitting the AJAX form.
65+
/// The AJAX form simply expects either a success or error message to be returned.
66+
/// </summary>
67+
[HttpPost("ajax-form-submit")]
68+
public ActionResult<string> AjaxFormSubmit()
69+
{
70+
try
71+
{
72+
_captcha.ValidateSubmission();
73+
74+
return "It looks like you are a human";
75+
}
76+
catch (IconCaptchaSubmissionException e)
77+
{
78+
return e.Message;
79+
}
80+
}
81+
}
82+
}
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<ProjectReference Include="..\IconCaptcha\IconCaptcha.csproj" />
10+
</ItemGroup>
11+
12+
</Project>

IconCaptcha.Demo/Program.cs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
namespace IconCaptcha.Demo
2+
{
3+
public class Program
4+
{
5+
public static void Main(string[] args)
6+
{
7+
var builder = WebApplication.CreateBuilder(args);
8+
9+
builder.Configuration
10+
.AddJsonFile("appsettings.json")
11+
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json");
12+
13+
builder.Services.AddControllersWithViews();
14+
15+
// IconCaptcha: Required, the configuration section can be renamed.
16+
// The configuration key must match the one set in the 'appsettings.json' file.
17+
builder.Services.AddIconCaptcha(builder.Configuration.GetSection("IconCaptcha"));
18+
19+
// IconCaptcha: Optional, can be used to programmatically alter the configuration.
20+
builder.Services.Configure<IconCaptchaOptions>(options =>
21+
{
22+
// options.IconPath = "assets/icons";
23+
});
24+
25+
var app = builder.Build();
26+
app.UseStaticFiles();
27+
app.UseRouting();
28+
app.UseAuthorization();
29+
app.UseSession();
30+
31+
app.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
32+
33+
// IconCaptcha: Required, the endpoint can be changed to your liking.
34+
app.MapIconCaptcha("/iconcaptcha");
35+
36+
app.Run();
37+
}
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"profiles": {
3+
"IconCaptcha.Demo": {
4+
"commandName": "Project",
5+
"launchBrowser": true,
6+
"applicationUrl": "http://localhost:5000",
7+
"environmentVariables": {
8+
"ASPNETCORE_ENVIRONMENT": "Development"
9+
}
10+
}
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace IconCaptcha.Demo.ViewModels;
2+
3+
public class SubmissionViewModel
4+
{
5+
public bool? Error { get; set; }
6+
public string ErrorMessage { get; set; }
7+
}
+217
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
@model IconCaptcha.Demo.ViewModels.SubmissionViewModel
2+
@inject IconCaptcha.IconCaptchaService IconCaptcha
3+
4+
<!DOCTYPE HTML>
5+
<html lang="en">
6+
<head>
7+
<title>@ViewBag.Title</title>
8+
<meta charset="UTF-8" />
9+
<meta http-equiv="X-UA-Compatible" content="IE=10" />
10+
<meta name="author" content="Fabian Wennink © @DateTime.Now.Year" />
11+
<meta name="viewport" content="width=device-width, initial-scale=1">
12+
<link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" />
13+
14+
<!-- JUST FOR THE DEMO PAGE -->
15+
<link href="/demo.css" rel="stylesheet" type="text/css">
16+
<script src="/demo.js" type="text/javascript"></script>
17+
<link href="https://fonts.googleapis.com/css?family=Poppins:400,700" rel="stylesheet">
18+
19+
<!-- Include IconCaptcha stylesheet - REQUIRED -->
20+
<link href="/css/icon-captcha.min.css" rel="stylesheet" type="text/css">
21+
</head>
22+
<body>
23+
<div class="container">
24+
25+
<div class="logo-text">
26+
<a href="https://github.com/fabianwennink/IconCaptcha-ASP.NET/" target="_blank" rel="noopener">
27+
Ic<span>o</span>nCaptcha
28+
</a>
29+
</div>
30+
31+
<div class="shields">
32+
<div class="shields-row">
33+
<a href="https://github.com/fabianwennink/IconCaptcha-ASP.NET/releases" target="_blank" rel="noopener">
34+
<img src="https://img.shields.io/badge/Version-3.0.0-orange.svg?style=flat-square" alt="Version 3.0.0 Badge"/>
35+
</a>
36+
<a href="https://github.com/fabianwennink/IconCaptcha-ASP.NET/blob/master/LICENSE" target="_blank" rel="noopener">
37+
<img src="https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square" alt="License-MIT Badge" />
38+
</a>
39+
<a href="https://github.com/fabianwennink/IconCaptcha-ASP.NET/issues" target="_blank" rel="noopener">
40+
<img src="https://img.shields.io/github/issues/fabianwennink/IconCaptcha-ASP.NET?style=flat-square" alt="Git Issues Badge" />
41+
</a>
42+
<a href="https://github.com/fabianwennink/IconCaptcha-ASP.NET" target="_blank" rel="noopener">
43+
<img src="https://img.shields.io/github/stars/fabianwennink/IconCaptcha-ASP.NET?color=%23ffff&logo=github&style=flat-square" alt="Git Stars Badge" />
44+
</a>
45+
</div>
46+
</div>
47+
48+
<div class="section">
49+
50+
<!-- Captcha message placeholder -->
51+
<p class="message"></p>
52+
53+
<!-- The IconCaptcha holder should ALWAYS be placed WITHIN the <form> element -->
54+
<form method="post" asp-action="AjaxFormSubmit">
55+
56+
<!-- Additional security token to prevent CSRF. Optional but highly recommended - disable via IconCaptcha options. -->
57+
<input type="hidden" name="_iconcaptcha-token" value="@IconCaptcha.Token()"/>
58+
59+
<!-- The IconCaptcha will be rendered in this element - REQUIRED -->
60+
<div class="iconcaptcha-holder" data-theme="light"></div>
61+
62+
<!-- Submit button to test your IconCaptcha input -->
63+
<input type="submit" value="Submit demo captcha" class="btn" >
64+
</form>
65+
66+
<!-- Theme selector - JUST FOR THE DEMO PAGE -->
67+
<div class="themes">
68+
<div class="theme theme--light"><span data-theme="light"></span><span>Light</span></div>
69+
<div class="theme theme--legacy-light"><span data-theme="legacy-light"></span><span>Legacy Light</span></div>
70+
<div class="theme theme--dark"><span data-theme="dark"></span><span>Dark</span></div>
71+
<div class="theme theme--legacy-dark"><span data-theme="legacy-dark"></span><span>Legacy Dark</span></div>
72+
</div>
73+
<small>(theme selector only works when the challenge has not been requested yet)</small>
74+
</div>
75+
76+
<div class="copyright">
77+
<p>Copyright &copy; @DateTime.Now.Year Fabian Wennink - All rights reserved</p>
78+
<p>
79+
<small>
80+
IconCaptcha is licensed under <a href="https://www.fabianwennink.nl/projects/IconCaptcha-ASP.NET/license" class="link-underline" target="_blank" rel="noopener">MIT</a>.
81+
Icons made by <a href="https://blendicons.com" class="link-underline" target="_blank" rel="nofollow noopener">BlendIcons</a>.
82+
</small>
83+
</p>
84+
</div>
85+
</div>
86+
87+
<a href="../">
88+
<div class="btn btn-bottom">
89+
<span>GO BACK</span>
90+
</div>
91+
</a>
92+
93+
<a href="https://github.com/fabianwennink/IconCaptcha-ASP.NET/" target="_blank" rel="noopener">
94+
<div class="corner-ribbon top-left">STAR ME ON GITHUB</div>
95+
</a>
96+
97+
<!-- Buy Me A Coffee widget - JUST FOR THE DEMO PAGE -->
98+
<script data-name="BMC-Widget" src="https://cdnjs.buymeacoffee.com/1.0.0/widget.prod.min.js" data-id="fabianwennink"
99+
data-description="Support me on Buy me a coffee!" data-message="If you like IconCaptcha, consider buying me a coffee!"
100+
data-color="#ffffff" data-position="right" data-x_margin="25" data-y_margin="25"></script>
101+
102+
<!-- Include IconCaptcha script - REQUIRED -->
103+
<script src="/js/icon-captcha.min.js" type="text/javascript"></script>
104+
105+
<!-- Include jQuery Library -->
106+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
107+
108+
<!-- Include IconCaptcha script - REQUIRED -->
109+
<script src="/js/icon-captcha.min.js" type="text/javascript"></script>
110+
111+
<!-- Initialize the IconCaptcha - REQUIRED -->
112+
<script type="text/javascript">
113+
$(document).ready(function() {
114+
$('.iconcaptcha-holder').iconCaptcha({
115+
general: {
116+
validationPath: '/iconcaptcha',
117+
fontFamily: 'Poppins',
118+
credits: 'show',
119+
},
120+
security: {
121+
clickDelay: 500,
122+
hoverDetection: true,
123+
enableInitialMessage: true,
124+
initializeDelay: 500,
125+
selectionResetDelay: 3000,
126+
loadingAnimationDelay: 1000,
127+
invalidateTime: 1000 * 60 * 2,
128+
},
129+
messages: {
130+
initialization: {
131+
verify: 'Verify that you are human.',
132+
loading: 'Loading challenge...',
133+
},
134+
header: 'Select the image displayed the <u>least</u> amount of times',
135+
correct: 'Verification complete.',
136+
incorrect: {
137+
title: 'Uh oh.',
138+
subtitle: "You've selected the wrong image."
139+
},
140+
timeout: {
141+
title: 'Please wait 60 sec.',
142+
subtitle: 'You made too many incorrect selections.'
143+
}
144+
}
145+
})
146+
// .bind('init', function(e) { // You can bind to custom events, in case you want to execute custom code.
147+
// console.log('Event: Captcha initialized', e.detail.captchaId);
148+
// }).bind('selected', function(e) {
149+
// console.log('Event: Icon selected', e.detail.captchaId);
150+
// }).bind('refreshed', function(e) {
151+
// console.log('Event: Captcha refreshed', e.detail.captchaId);
152+
// }).bind('invalidated', function(e) {
153+
// console.log('Event: Invalidated', e.detail.captchaId);
154+
// }).bind('reset', function(e) {
155+
// console.log('Event: Reset', e.detail.captchaId);
156+
// }).bind('success', function(e) {
157+
// console.log('Event: Correct input', e.detail.captchaId);
158+
// }).bind('error', function(e) {
159+
// console.log('Event: Wrong input', e.detail.captchaId);
160+
// });
161+
});
162+
</script>
163+
164+
<!--
165+
Script to submit the form(s) with Ajax.
166+
167+
NOTE: If you want to use FormData instead of .serialize(), make sure to
168+
include the inputs 'ic-hf-se', 'ic-hf-id' and 'ic-hf-hp' into your FormData object.
169+
Take a look at the commented code down below.
170+
-->
171+
<script type="text/javascript">
172+
$(document).ready(function() {
173+
$('form').submit(function(e) {
174+
e.preventDefault();
175+
176+
// Get the form element.
177+
const form = $(this);
178+
179+
// Perform the AJAX call.
180+
$.ajax({
181+
type: 'POST',
182+
url: form.attr('action'),
183+
data: form.serialize()
184+
}).done(function (data) {
185+
$('.message').html(data);
186+
}).fail(function () {
187+
console.log('Error: Failed to submit form.')
188+
});
189+
190+
// // FormData example:
191+
//
192+
// // Get the form element.
193+
// const form = $(this);
194+
//
195+
// // Build the FormData object.
196+
// const formData = new FormData();
197+
// formData.append('ic-hf-se', form.find('input[name="ic-hf-se"]').val());
198+
// formData.append('ic-hf-id', form.find('input[name="ic-hf-id"]').val());
199+
// formData.append('ic-hf-hp', form.find('input[name="ic-hf-hp"]').val());
200+
//
201+
// // Perform the AJAX call.
202+
// $.ajax({
203+
// type: 'POST',
204+
// url: form.attr('action'),
205+
// data: formData,
206+
// processData: false,
207+
// contentType: false
208+
// }).done(function (data) {
209+
// $('.message').html(data);
210+
// }).fail(function () {
211+
// console.log('Error: Failed to submit form.')
212+
// });
213+
});
214+
});
215+
</script>
216+
</body>
217+
</html>

0 commit comments

Comments
 (0)