binita
1 year ago
14 changed files with 608 additions and 34 deletions
-
68API/GoogleAuthenticatorAPI.cs
-
170API/Model/EncryptDecryptUtility.cs
-
15API/Model/GoogleAuthenticatorModel.cs
-
6Business/Account/AccountServices.cs
-
3Business/Account/IAccountServices.cs
-
10JMEAgentSystem/Scripts/Account/Login.js
-
2JMEAgentSystem/Scripts/Customer/CustomerRegistration.js
-
137JMEAgentSystem/WebPages/Account/Authenticate.aspx
-
64JMEAgentSystem/WebPages/Account/Authenticate.aspx.cs
-
80JMEAgentSystem/WebPages/Account/Authenticate.aspx.designer.cs
-
65JMEAgentSystem/WebPages/Account/Login.aspx.cs
-
11JMEAgentSystem/WebPages/CustomerRegistration/Manage.aspx
-
10Repository/DAO/Account/AccountRepo.cs
-
1Repository/DAO/Account/IAccountRepo.cs
@ -0,0 +1,68 @@ |
|||||
|
using API.Model; |
||||
|
using Common.Utility; |
||||
|
using Google.Authenticator; |
||||
|
using System.Configuration; |
||||
|
using System.Web; |
||||
|
|
||||
|
namespace API |
||||
|
{ |
||||
|
public class GoogleAuthenticatorAPI |
||||
|
{ |
||||
|
protected TwoFactorAuthenticator _tfa = new TwoFactorAuthenticator(); |
||||
|
protected string _key = ReadWebConfig("2FAGoogle", ""); |
||||
|
protected string _keyForEncDec = ReadWebConfig("keyForEncryptionDecryption", ""); |
||||
|
|
||||
|
public GoogleAuthenticatorModel GenerateCodeAndImageURL(string userName) |
||||
|
{ |
||||
|
GoogleAuthenticatorModel _model = new GoogleAuthenticatorModel(); |
||||
|
string userUniqueKeyEncrypted = EncryptDecryptUtility.Encrypt(userName + _key, _keyForEncDec); |
||||
|
WriteSession("UserUniqueKey", userUniqueKeyEncrypted); |
||||
|
|
||||
|
var _googleSetupInfo = _tfa.GenerateSetupCode("JME REMIT", userName, userUniqueKeyEncrypted, 200, 200, true); |
||||
|
_model.SetupCode = _googleSetupInfo.ManualEntryKey; |
||||
|
_model.BarCodeImageUrl = _googleSetupInfo.QrCodeSetupImageUrl; |
||||
|
|
||||
|
return _model; |
||||
|
} |
||||
|
|
||||
|
public GoogleAuthenticatorModel GenerateCodeAndImageURL(string userName, string userUniqueKeyEncrypted) |
||||
|
{ |
||||
|
GoogleAuthenticatorModel _model = new GoogleAuthenticatorModel(); |
||||
|
|
||||
|
var _googleSetupInfo = _tfa.GenerateSetupCode("JME REMIT", userName, userUniqueKeyEncrypted, 200, 200, true); |
||||
|
_model.SetupCode = _googleSetupInfo.ManualEntryKey; |
||||
|
_model.BarCodeImageUrl = _googleSetupInfo.QrCodeSetupImageUrl; |
||||
|
_model.ManualEntryKey = _googleSetupInfo.ManualEntryKey; |
||||
|
|
||||
|
return _model; |
||||
|
} |
||||
|
|
||||
|
public DbResult Verify2FA(string otp, string userUniqueKey) |
||||
|
{ |
||||
|
DbResult _dbRes = new DbResult(); |
||||
|
if (string.IsNullOrEmpty(otp)) |
||||
|
{ |
||||
|
_dbRes.SetError("1", "OTP Code can not be blank!", null); |
||||
|
return _dbRes; |
||||
|
} |
||||
|
|
||||
|
bool isValid = _tfa.ValidateTwoFactorPIN(userUniqueKey, otp); |
||||
|
if (isValid) |
||||
|
_dbRes.SetError("0", "Two factor authentication verified successfully!", null); |
||||
|
else |
||||
|
_dbRes.SetError("1", "Please enter valid OTP!", null); |
||||
|
|
||||
|
return _dbRes; |
||||
|
} |
||||
|
|
||||
|
public static string ReadWebConfig(string key, string defValue) |
||||
|
{ |
||||
|
return (ConfigurationSettings.AppSettings[key] ?? defValue).ToString(); |
||||
|
} |
||||
|
|
||||
|
public static void WriteSession(string key, string value) |
||||
|
{ |
||||
|
HttpContext.Current.Session[key] = value; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,170 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Security.Cryptography; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace API.Model |
||||
|
{ |
||||
|
public class EncryptDecryptUtility |
||||
|
{ |
||||
|
protected static string saltValue = "K0r3@GM3"; |
||||
|
protected static string hashAlgorithm = "SHA1"; |
||||
|
protected static int passwordIterations = 5; |
||||
|
protected static string initVector = "P@s$w0rDGm3KoR3@"; |
||||
|
protected static int keySize = 256; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Encrypts specified plaintext using Rijndael symmetric key algorithm
|
||||
|
/// and returns a base64-encoded result.
|
||||
|
/// </summary>
|
||||
|
/// <param name="plainText">Plain Text to Encrypt</param>
|
||||
|
/// <param name="passPhrase">Pass Phrase to use in Password Generation</param>
|
||||
|
/// <returns>Encrypted text encoded into Base 64 text format </returns>
|
||||
|
public static string Encrypt(string plainText, string passPhrase) |
||||
|
{ |
||||
|
// Convert strings into byte arrays.
|
||||
|
// Let us assume that strings only contain ASCII codes.
|
||||
|
// If strings include Unicode characters, use Unicode, UTF7, or UTF8
|
||||
|
// encoding.
|
||||
|
byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); |
||||
|
byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue); |
||||
|
|
||||
|
// Convert our plaintext into a byte array.
|
||||
|
// Let us assume that plaintext contains UTF8-encoded characters.
|
||||
|
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); |
||||
|
|
||||
|
// First, we must create a password, from which the key will be derived.
|
||||
|
// This password will be generated from the specified passphrase and
|
||||
|
// salt value. The password will be created using the specified hash
|
||||
|
// algorithm. Password creation can be done in several iterations.
|
||||
|
var password = new PasswordDeriveBytes( |
||||
|
passPhrase, |
||||
|
saltValueBytes, |
||||
|
hashAlgorithm, |
||||
|
passwordIterations); |
||||
|
|
||||
|
// Use the password to generate pseudo-random bytes for the encryption
|
||||
|
// key. Specify the size of the key in bytes (instead of bits).
|
||||
|
#pragma warning disable 618, 612
|
||||
|
byte[] keyBytes = password.GetBytes(keySize / 8); |
||||
|
#pragma warning restore 618, 612
|
||||
|
|
||||
|
// Create uninitialized Rijndael encryption object.
|
||||
|
var symmetricKey = new RijndaelManaged(); |
||||
|
|
||||
|
// It is reasonable to set encryption mode to Cipher Block Chaining
|
||||
|
// (CBC). Use default options for other symmetric key parameters.
|
||||
|
symmetricKey.Mode = CipherMode.CBC; |
||||
|
|
||||
|
// Generate encryptor from the existing key bytes and initialization
|
||||
|
// vector. Key size will be defined based on the number of the key
|
||||
|
// bytes.
|
||||
|
ICryptoTransform encryptor = symmetricKey.CreateEncryptor( |
||||
|
keyBytes, |
||||
|
initVectorBytes); |
||||
|
|
||||
|
var memoryStream = new MemoryStream(); |
||||
|
|
||||
|
// Define memory stream which will be used to hold encrypted data.
|
||||
|
var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write); |
||||
|
|
||||
|
// Start encrypting.
|
||||
|
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); |
||||
|
|
||||
|
// Finish encrypting.
|
||||
|
cryptoStream.FlushFinalBlock(); |
||||
|
|
||||
|
// Convert our encrypted data from a memory stream into a byte array.
|
||||
|
byte[] cipherTextBytes = memoryStream.ToArray(); |
||||
|
|
||||
|
// Close both streams.
|
||||
|
memoryStream.Close(); |
||||
|
cryptoStream.Close(); |
||||
|
|
||||
|
// Convert encrypted data into a base64-encoded string.
|
||||
|
string cipherText = Convert.ToBase64String(cipherTextBytes); |
||||
|
|
||||
|
// Return encrypted string.
|
||||
|
return cipherText; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Decrypts specified cipherText using Rijndael symmetric key algorithm
|
||||
|
/// and returns a plain text result.
|
||||
|
/// </summary>
|
||||
|
/// <param name="cipherText">Encryted Text</param>
|
||||
|
/// <param name="passPhrase">Pass Phrase used in Password Generation</param>
|
||||
|
/// <returns></returns>
|
||||
|
public static string Decrypt(string cipherText, string passPhrase) |
||||
|
{ |
||||
|
// Convert strings defining encryption key characteristics into byte
|
||||
|
// arrays. Let us assume that strings only contain ASCII codes.
|
||||
|
// If strings include Unicode characters, use Unicode, UTF7, or UTF8
|
||||
|
// encoding.
|
||||
|
byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector); |
||||
|
byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue); |
||||
|
|
||||
|
// Convert our ciphertext into a byte array.
|
||||
|
byte[] cipherTextBytes = Convert.FromBase64String(cipherText); |
||||
|
|
||||
|
// First, we must create a password, from which the key will be
|
||||
|
// derived. This password will be generated from the specified
|
||||
|
// passphrase and salt value. The password will be created using
|
||||
|
// the specified hash algorithm. Password creation can be done in
|
||||
|
// several iterations.
|
||||
|
var password = new PasswordDeriveBytes( |
||||
|
passPhrase, |
||||
|
saltValueBytes, |
||||
|
hashAlgorithm, |
||||
|
passwordIterations); |
||||
|
|
||||
|
// Use the password to generate pseudo-random bytes for the encryption
|
||||
|
// key. Specify the size of the key in bytes (instead of bits).
|
||||
|
#pragma warning disable 618, 612
|
||||
|
byte[] keyBytes = password.GetBytes(keySize / 8); |
||||
|
#pragma warning restore 618, 612
|
||||
|
|
||||
|
// Create uninitialized Rijndael encryption object.
|
||||
|
var symmetricKey = new RijndaelManaged(); |
||||
|
|
||||
|
// It is reasonable to set encryption mode to Cipher Block Chaining
|
||||
|
// (CBC). Use default options for other symmetric key parameters.
|
||||
|
symmetricKey.Mode = CipherMode.CBC; |
||||
|
|
||||
|
// Generate decryptor from the existing key bytes and initialization
|
||||
|
// vector. Key size will be defined based on the number of the key
|
||||
|
// bytes.
|
||||
|
ICryptoTransform decryptor = symmetricKey.CreateDecryptor( |
||||
|
keyBytes, |
||||
|
initVectorBytes); |
||||
|
|
||||
|
// Define memory stream which will be used to hold encrypted data.
|
||||
|
var memoryStream = new MemoryStream(cipherTextBytes); |
||||
|
|
||||
|
// Define cryptographic stream (always use Read mode for encryption).
|
||||
|
var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); |
||||
|
|
||||
|
// Since at this point we don't know what the size of decrypted data
|
||||
|
// will be, allocate the buffer long enough to hold ciphertext;
|
||||
|
// plaintext is never longer than ciphertext.
|
||||
|
var plainTextBytes = new byte[cipherTextBytes.Length]; |
||||
|
|
||||
|
// Start decrypting.
|
||||
|
int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); |
||||
|
|
||||
|
// Close both streams.
|
||||
|
memoryStream.Close(); |
||||
|
cryptoStream.Close(); |
||||
|
|
||||
|
// Convert decrypted data into a string.
|
||||
|
// Let us assume that the original plaintext string was UTF8-encoded.
|
||||
|
string plainText = Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); |
||||
|
|
||||
|
// Return decrypted string.
|
||||
|
return plainText; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace API.Model |
||||
|
{ |
||||
|
public class GoogleAuthenticatorModel |
||||
|
{ |
||||
|
public string BarCodeImageUrl { get; set; } |
||||
|
public string SetupCode { get; set; } |
||||
|
public string ManualEntryKey { get; set; } |
||||
|
} |
||||
|
} |
@ -0,0 +1,137 @@ |
|||||
|
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Authenticate.aspx.cs" Inherits="JMEAgentSystem.WebPages.Account.Authenticate" %> |
||||
|
|
||||
|
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %> |
||||
|
<!DOCTYPE html> |
||||
|
<html xmlns="http://www.w3.org/1999/xhtml"> |
||||
|
<head id="Head1" runat="server"> |
||||
|
|
||||
|
|
||||
|
<link href="../../js/jquery/jquery-ui.css" rel="stylesheet" /> |
||||
|
<link href="../../ui/css/menu.css" rel="stylesheet" /> |
||||
|
<link href="../../ui/bootstrap/css/bootstrap.min.css" rel="stylesheet" /> |
||||
|
<link href="../../ui/css/waves.min.css" rel="stylesheet" /> |
||||
|
<link href="../../ui/css/style.css" rel="stylesheet" /> |
||||
|
<link href="../../ui/font-awesome/css/font-awesome.min.css" rel="stylesheet" /> |
||||
|
<script src="../../ui/bootstrap/js/bootstrap.min.js"></script> |
||||
|
<script src="../../js/functions.js"></script> |
||||
|
<style> |
||||
|
/*body {*/ |
||||
|
/*font-family: Arial, sans-serif;*/ |
||||
|
/*background-color: #f7f7f7; |
||||
|
}*/ |
||||
|
|
||||
|
.page-wrapper { |
||||
|
margin: 30px; |
||||
|
} |
||||
|
|
||||
|
.panel-heading { |
||||
|
background-color: #f7f7f7; |
||||
|
} |
||||
|
|
||||
|
.panel-title { |
||||
|
font-size: 24px; |
||||
|
margin-bottom: 0; |
||||
|
} |
||||
|
|
||||
|
.form-group { |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.form-group label { |
||||
|
font-weight: bold; |
||||
|
padding-top: 7px; |
||||
|
color: black; |
||||
|
} |
||||
|
|
||||
|
.form-control { |
||||
|
border-radius: 5px; |
||||
|
box-shadow: none; |
||||
|
border: 1px solid #ddd; |
||||
|
} |
||||
|
|
||||
|
.btn-primary { |
||||
|
background-color: #007bff; |
||||
|
border-color: #007bff; |
||||
|
} |
||||
|
|
||||
|
.btn-primary:hover { |
||||
|
background-color: #0056b3; |
||||
|
border-color: #0056b3; |
||||
|
} |
||||
|
|
||||
|
.btn-primary:focus { |
||||
|
box-shadow: none; |
||||
|
} |
||||
|
|
||||
|
.errormsg { |
||||
|
color: red; |
||||
|
padding-left: 5px; |
||||
|
} |
||||
|
|
||||
|
p { |
||||
|
font-size: 13px; |
||||
|
color: black; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
</head> |
||||
|
<body> |
||||
|
<form id="form1" runat="server"> |
||||
|
<contenttemplate> |
||||
|
<div class="page-wrapper"> |
||||
|
<div class="tab-content"> |
||||
|
<div role="tabpanel" class="tab-pane active" id="list"> |
||||
|
<div class="row"> |
||||
|
<div class="col-md-8"> |
||||
|
<div class="panel panel-default "> |
||||
|
<div class="panel-heading"> |
||||
|
<h4 class="panel-title">Verify OTP</h4> |
||||
|
<div class="panel-actions"> |
||||
|
<a href="#" class="panel-action panel-action-toggle" data-panel-toggle></a> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-body"> |
||||
|
<div id="msg" runat="server" class="error"> |
||||
|
<div class="alert alert-danger" runat="server" id="errMsg" visible="false"></div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-3"> |
||||
|
User Name : |
||||
|
</label> |
||||
|
<div class="col-md-5"> |
||||
|
<asp:TextBox ID="txtUserId" runat="server" ReadOnly="true" CssClass="form-control"></asp:TextBox> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<label class="col-md-3"> |
||||
|
Enter OTP :<span class="errormsg">*</span> |
||||
|
</label> |
||||
|
<div class="col-md-5"> |
||||
|
<asp:TextBox ID="txtOtp" runat="server" CssClass="form-control"></asp:TextBox> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<div class="col-md-6 col-md-offset-3"> |
||||
|
<asp:Button ID="btnVerify" runat="server" Text="Verify" ValidationGroup="user" |
||||
|
CssClass="btn btn-primary m-t-25" TabIndex="5" OnClick="btnVerify_Click" /> |
||||
|
|
||||
|
<%-- <asp:Button ID="btnCancel" runat="server" Text="Cancel" ValidationGroup="user" |
||||
|
CssClass="btn btn-primary m-t-25" TabIndex="5" OnClick="btnCancel_Click" />--%> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</contenttemplate> |
||||
|
</form> |
||||
|
</body> |
||||
|
</html> |
||||
|
|
||||
|
|
||||
|
|
@ -0,0 +1,64 @@ |
|||||
|
using Common.Helper; |
||||
|
using Common.Utility; |
||||
|
using System; |
||||
|
using Repository.DAO; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Data; |
||||
|
using System.Linq; |
||||
|
using System.Web; |
||||
|
using System.Web.UI; |
||||
|
using System.Web.UI.WebControls; |
||||
|
using Business.Account; |
||||
|
using Business.Configuration; |
||||
|
using Common.Model; |
||||
|
using API; |
||||
|
|
||||
|
namespace JMEAgentSystem.WebPages.Account |
||||
|
{ |
||||
|
public partial class Authenticate : System.Web.UI.Page |
||||
|
{ |
||||
|
protected GoogleAuthenticatorAPI _auth = new GoogleAuthenticatorAPI(); |
||||
|
private readonly IAccountServices _accountServices = AutoFacContainer.Resolve<IAccountServices>(); |
||||
|
|
||||
|
private readonly string userId = GetStatic.ReadQueryString("referralCode", ""); |
||||
|
private readonly string password = GetStatic.ReadQueryString("password", ""); |
||||
|
private readonly string uniqueKey = GetStatic.ReadQueryString("uniqueKey", ""); |
||||
|
private string ipAddress = ""; |
||||
|
protected string use2FA = "Y"; |
||||
|
|
||||
|
protected void Page_Load(object sender, EventArgs e) |
||||
|
{ |
||||
|
|
||||
|
LoadLoginData(); |
||||
|
} |
||||
|
protected void LoadLoginData() |
||||
|
{ |
||||
|
txtUserId.Text = userId; |
||||
|
} |
||||
|
protected void btnVerify_Click(object sender, EventArgs e) |
||||
|
{ |
||||
|
var otp = txtOtp.Text; |
||||
|
|
||||
|
if (string.IsNullOrEmpty(uniqueKey)) |
||||
|
{ |
||||
|
errMsg.InnerText = "Please contact JME Head office to get QR code for accessing JME Remit system!"; |
||||
|
errMsg.Visible = true; |
||||
|
//EnableLogin();
|
||||
|
return; |
||||
|
} |
||||
|
// var response = _accountServices.AuthenticateAgent(userId, otp, uniqueKey);
|
||||
|
var _dbRes = _auth.Verify2FA(otp, uniqueKey); |
||||
|
|
||||
|
if (_dbRes.ErrorCode != "0") |
||||
|
{ |
||||
|
errMsg.InnerText = _dbRes.Msg; |
||||
|
errMsg.Visible = true; |
||||
|
// EnableLogin();
|
||||
|
return; |
||||
|
} |
||||
|
{ |
||||
|
Response.Redirect("/WebPages/"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,80 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace JMEAgentSystem.WebPages.Account |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
public partial class Authenticate |
||||
|
{ |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Head1 control.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Auto-generated field.
|
||||
|
/// To modify move field declaration from designer file to code-behind file.
|
||||
|
/// </remarks>
|
||||
|
protected global::System.Web.UI.HtmlControls.HtmlHead Head1; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// form1 control.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Auto-generated field.
|
||||
|
/// To modify move field declaration from designer file to code-behind file.
|
||||
|
/// </remarks>
|
||||
|
protected global::System.Web.UI.HtmlControls.HtmlForm form1; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// msg control.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Auto-generated field.
|
||||
|
/// To modify move field declaration from designer file to code-behind file.
|
||||
|
/// </remarks>
|
||||
|
protected global::System.Web.UI.HtmlControls.HtmlGenericControl msg; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// errMsg control.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Auto-generated field.
|
||||
|
/// To modify move field declaration from designer file to code-behind file.
|
||||
|
/// </remarks>
|
||||
|
protected global::System.Web.UI.HtmlControls.HtmlGenericControl errMsg; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// txtUserId control.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Auto-generated field.
|
||||
|
/// To modify move field declaration from designer file to code-behind file.
|
||||
|
/// </remarks>
|
||||
|
protected global::System.Web.UI.WebControls.TextBox txtUserId; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// txtOtp control.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Auto-generated field.
|
||||
|
/// To modify move field declaration from designer file to code-behind file.
|
||||
|
/// </remarks>
|
||||
|
protected global::System.Web.UI.WebControls.TextBox txtOtp; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// btnVerify control.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// Auto-generated field.
|
||||
|
/// To modify move field declaration from designer file to code-behind file.
|
||||
|
/// </remarks>
|
||||
|
protected global::System.Web.UI.WebControls.Button btnVerify; |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue