Use CAPICOM in Server Side - javascript

I have a code in .net for sign in client side and verify in server side.
And I must convert my code in asp classic.
In .net code on client side I sign with capicom by javascript.
My code:
<script type="text/javascript">
// Some needed constants
CAPICOM_CURRENT_USER_STORE = 2;
CAPICOM_STORE_OPEN_READ_ONLY = 0;
CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME = 0;
CAPICOM_ENCODE_BASE64 = 0;
function Authenticate() {
try {
var challenge = document.getElementById("<%=hid_Challenge.ClientID %>");
var response = document.getElementById("<%=hid_Response.ClientID %>");
// Open windows certificate store
var store = new ActiveXObject("CAPICOM.Store");
store.Open(CAPICOM_CURRENT_USER_STORE, "My", CAPICOM_STORE_OPEN_READ_ONLY);
// Show personal certificates which are installed for this user
var certificates = store.Certificates.Select("KeyA3 Sample PKI Authentication", "Please select a certificate to authenticate.");
// Proceed if any certificate is selected
if (certificates.Count > 0) {
var signer = new ActiveXObject("CAPICOM.Signer");
signer.Certificate = certificates.Item(1);
var timeAttrib = new ActiveXObject("CAPICOM.Attribute");
timeAttrib.Name = CAPICOM_AUTHENTICATED_ATTRIBUTE_SIGNING_TIME;
var date = new Date('<%=DateTime.Now.ToString("F", new System.Globalization.CultureInfo("en-US")) %>');
timeAttrib.Value = date.getVarDate();
signer.AuthenticatedAttributes.Add(timeAttrib);
var signedData = new ActiveXObject("CAPICOM.SignedData");
signedData.Content = challenge.value;
response.value = signedData.Sign(signer, true, CAPICOM_ENCODE_BASE64);
return true;
}
return false;
}
catch (e) {
alert(e.description);
return false;
}
}
</script>
And
I check signed data in this code:
Byte[] signedData;
ContentInfo content;
SignedCms signed;
if (hid_Response.Value == null)
throw new ArgumentNullException("Response");
signedData = Encoding.Unicode.GetBytes(Session["Challenge"].ToString());
content = new ContentInfo(signedData);
signed = new SignedCms(content, true);
signed.Decode(Convert.FromBase64String(hid_Response.Value));
// Set the parameter to 'true' if you want the certificate not be checked.
signed.CheckSignature(true);
// Do further authentication and user mapping here.
// For example you could check some certificate parameters against your database.
// Here we only show the certificate information. Nothing checked here.
lbl_Message1.Text = "Authenticated successfully.";
lbl_Message1.Visible = true;
Dictionary<String, String> certProps = new Dictionary<String, String>();
certProps.Add("Subject", signed.Certificates[0].Subject);
certProps.Add("Issuer", signed.Certificates[0].Issuer);
certProps.Add("Valid From", signed.Certificates[0].NotBefore.ToString());
certProps.Add("Valid To", signed.Certificates[0].NotAfter.ToString());
certProps.Add("Friendly Name", signed.Certificates[0].FriendlyName);
certProps.Add("Version", signed.Certificates[0].Version.ToString());
certProps.Add("Serial Number", signed.Certificates[0].SerialNumber);
certProps.Add("Thumbprint", signed.Certificates[0].Thumbprint);
gvCertificate.DataSource = certProps;
gvCertificate.DataBind();
gvCertificate.Visible = true;
But I must run this code in asp classic
I successfully sign my data in client side by javascript.
And I want to verify data in server side by VBSCRIPT OR JAVASCRIPT.
Is any way?
Thanks

I found answer.
It will be helpful.
Dim verification
Set verification = Server.CreateObject("CAPICOM.SignedData")
verification.Verify signed_Data, false, 0
For Each Certificate In verification.Certificates
subject = Certificate.SubjectName
Next
If Err.Number <> 0 Then
result = Err.Description & Hex(Err.Number)
Else
result = "Signature is OK"
End If

Related

asked chatgpt to create a script to run through my gmail account and count the number of emails per sender and list the results in a spreadsheet

i'm not a programmer. i'm just trying to clean my gmail account and i figured i could put chatgpt to use. it came up with this code, but i'm getting an error when i run it in apps script: hoping someone can shed some light on what's wrong with it.
thanks
function countEmailsBySender() {
// Replace the following variables with your own values
var maxEmails = 4000; // the maximum number of emails to process
var spreadsheetId = 'YOUR_SPREADSHEET_ID'; // the ID of your Google Spreadsheet
var sheetName = 'Emails By Sender'; // the name of the sheet to create in your Google Spreadsheet
var clientId = 'YOUR_CLIENT_ID'; // your OAuth 2.0 client ID
var clientSecret = 'YOUR_CLIENT_SECRET'; // your OAuth 2.0 client secret
// Create a new sheet in the specified spreadsheet
var sheet = SpreadsheetApp.openById(spreadsheetId).insertSheet(sheetName);
// Get the authorization token
var service = getGmailService(clientId, clientSecret);
if (!service.hasAccess()) {
Logger.log(service.getAuthorizationUrl());
throw new Error('Authorization required');
}
// Get the list of messages
var query = 'is:inbox';
var threads = Gmail.Users.Threads.list('me', { q: query, maxResults: maxEmails }, { auth: service }).threads;
// Count the number of emails sent by each sender
var emailCount = {};
threads.forEach(function(thread) {
var messages = Gmail.Users.Messages.get('me', thread.messages[0].id, { auth: service }).payload.headers;
var sender = messages.find(header => header.name === 'From').value;
emailCount[sender] = (emailCount[sender] || 0) + 1;
});
// Sort the senders by the number of emails they sent
var senders = Object.keys(emailCount).sort(function(a, b) {
return emailCount[b] - emailCount[a];
});
// Output the senders and the number of emails they sent to the spreadsheet
sheet.appendRow(['Sender', 'Email Count']);
senders.forEach(function(sender) {
sheet.appendRow([sender, emailCount[sender]]);
});
Logger.log('Done.');
}
function getGmailService(clientId, clientSecret) {
return OAuth2.createService('gmail')
.setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
.setClientId(clientId)
.setClientSecret(clientSecret)
.setScope('https://www.googleapis.com/auth/gmail.readonly')
.setCallbackFunction('authCallback')
.setPropertyStore(PropertiesService.getUserProperties())
.setCache(CacheService.getUserCache())
.setParam('access_type', 'offline')
.setParam('approval_prompt', 'force');
}
function authCallback(request) {
var service = getGmailService();
var authorized = service.handleCallback(request);
if (authorized) {
return HtmlService.createHtmlOutput('Success! You can close this tab.');
} else {
return HtmlService.createHtmlOutput('Access denied.');
}
}
i get an error (ReferenceError: OAuth2 is not defined) on these lines :
return OAuth2.createService('gmail')
var service = getGmailService(clientId, clientSecret);
am i missing something?
thanks in advance
haven't tried anything else

Socket.IO / JavaScript problem when broadcasting message to room(s)

I am working on a chat-app with Socket.IO (server using flask-SocketIO). Users can create new channels (rooms) and switch between them. In my code below for some reason, every time I switch (back) to a room (even having a single room and "switching" back to it), the "broadcast message"-handler function gets executed an additional time. I.e. if I send "Hello" on "channel_1", switch back to another channel and then back to "channel_1", then send "Hello again", it gets broadcasted (console.log in my example) TWICE. And next time I switch back to "channel_1", 3 TIMES, etc. I figured it must have something to do with the JS-code, maybe the way connectSocket() is called, because the flask-app only emits "broadcast message" once each time. Apologies for the lengthy code - I left out irrelevant bits as best I could.
document.addEventListener('DOMContentLoaded', () => {
// IF USER SWITCHES / SELECTS EXISTING CHANNEL
document.querySelector('#select_channel').onsubmit = () => {
var channel = document.querySelector('select').value;
const r2 = newXHR();
r2.open('POST', '/select_channel');
const data = new FormData();
data.append('channel', channel);
r2.onload = () => {
connectSocket(channel);
};
r2.send(data);
return false;
}
// IF USER CREATES NEW CHANNEL
document.querySelector('#new_channel').onsubmit = () => {
const new_channel_name = document.querySelector('#new_channel_name').value;
const r1 = newXHR();
r1.open('POST', '/new_channel');
const data = new FormData();
data.append('new_channel_name', new_channel_name);
r1.onload = () => {
const response = JSON.parse(r1.responseText);
if (response.channel_exists) {
alert("Channel already exists");
return false;
}
else {
const option = document.createElement('option');
option.innerHTML = new_channel_name;
document.querySelector('select').append(option);
connectSocket(new_channel_name);
document.getElementById('new_channel').reset();
}
};
r1.send(data);
return false;
};
});
function connectSocket(channel) {
var socket = io();
socket.on('connect', () => {
// if user previously connected to any channel, disconnect him
if (localStorage.getItem('channel') != null)
{
socket.emit('leave', {'room': localStorage.getItem('channel'), 'username': display_name});
}
socket.emit('join', {'room': channel, 'username': display_name});
localStorage.setItem('channel', channel);
const data = new FormData();
data.append('username', display_name);
data.append('room', channel);
document.querySelector('#current_channel').innerHTML = channel;
});
document.querySelector('#send_message').onsubmit = () => {
var message = document.querySelector('#message').value;
socket.emit('send', {'message': message, 'room': channel});
console.log(`SENDING ${message}`);
return false;
}
// PROBLEM: EVERY TIME CHANNEL CHANGED AND MSG SENT IN THAT CHANNEL -> 1 EXTRA COPY OF THAT MESSAGE IS BROADCAST - I>E> THE BELOW IS DONE +1 TIMES
socket.on('broadcast message', function handle_broadcast (data) {
console.log(data);
});
}
The Python snippets:
# [IMPORT & CONFIG STATEMENTS...]
socketio = SocketIO(app, logger=True, engineio_logger=True)
# Global variables
channels = []
messagetext = None
#app.route("/select_channel", methods=["GET", "POST"])
def select_channel():
if request.method == "POST":
channel = request.form.get("channel")
session["channel"] = channel
return jsonify({"success": True})
return render_template("chat.html", channels = channels)
#app.route("/new_channel", methods=["GET", "POST"])
def new_channel():
if request.method == "POST":
new_channel = request.form.get("new_channel_name")
if new_channel in channels:
return jsonify({"channel_exists": True})
else:
channels.append(new_channel)
session["channel"] = new_channel
return json.dumps(channels)
return render_template("chat.html", channels = channels)
#socketio.on('join')
def on_join(data):
username = data['username']
room = data['room']
join_room(room)
send(username + ' has entered the room.', room=room)
#socketio.on('leave')
def on_leave(data):
username = data['username']
room = data['room']
leave_room(room)
send(username + ' has left the room.', room=room)
#socketio.on("send")
def handle_send(data):
messagetext = data["message"]
room = data["room"]
emit("broadcast message", {"message": messagetext}, room=room)
if __name__ == '__main__':
socketio.run(app, debug=True)
I think what's happening is that in the Flask-SocketIO library, when you join a room, if you don't pass in a sid, it uses flask.request.sid. I'm not sure what Flask-SocketIO is using for that property, but my guess is that when you join a room, one sid is set. And when you leave a room, maybe a different sid is being used, which means that your original client didn't actually leave the room. So when they join again, a new connection is made (meaning a second, concurrent connection) which could explain why you get a broadcast message multiple times.
I would recommending trying to create your own sid to pass into the join_room() and leave_room() functions to see if that resolves the issue. You can pass it in from the client to your server and just for testing it could be something simple like session1.
I hope this helps.

exclude entity variable from PUT request

I am sending an entity to the database through a put request, but one of the variables is giving me trouble. I would like to know if there's a way to exclude a single variable from the request.
I am using axios for the db connection.
This is the entity being sent.
$this->id = 0;
$this->user = '';
$this->type = '';
$this->status = null;
$this->signatureList = new ArrayCollection();
//this is the array i want to exclude
$this->amendmentList = new ArrayCollection();
$this->draft = true;
$this->archived = false;
$this->canceled = false;
$this->finished = false;
$this->signed = false;
$this->subject = null;
$this->content = '';
$this->createdAt = new \DateTime();
parent::__construct();
This is the put request.
//it gets the entity through the id and sends it whole
update: (id, data) => {
window.httpMessage = { show: true, success: `Documento <b>#${id}</b> Atualizado`, error: "Documento <b>não Atualizado</b>" }
return http.put(`/eletronic-documents/${id}`, data).then(res => res.data)
}
As suggested by user steadweb, a delete on the client side did the trick.

send value to specific User in SignalR

I have 4 textboxes that are filling in same time after user push send button Using SignalR. In one part I am sending textbox values to all users and this is working. But when I try to send the values to specific user, after pushing the button, all textboxes get empty.
This is the code that is working, sending values to all users:
This is Hub:
public void Send(string loanType, string loanAmount, string interestRates, string payment)
{
User sender = GetUser(Context.User.Identity.Name);
var username = sender.Name;
IEnumerable<string> connectionIds = sender.ConnectionIds;
//All connected clients.
Clients.All.broadcastMessage(loanType, loanAmount, interestRates, payment);
}
and this is js:
$('#sendmessage').click(function (e) {
sendPayment();
e.preventDefault();
});
function sendPayment() {
var msgValue = $msgTxt.val();
var loanType = $('#txtLoanType').val();
var loanAmount = $('#txtLoanAmount').val();
var interestRates = $('#txtInterestRates').val();
var payment = $('#txtPayment').val();
if (loanType !== null && loanType.length > 0 && loanAmount !== null && loanAmount.length > 0 && interestRates !== null && interestRates.length > 0
&& payment !== null && payment.length > 0) {
if (viewModel.isInPrivateChat()) {
$.connection.hub.start();
chatHub.server.send(msgValue, viewModel.privateChatUser(), $('#txtLoanType option:selected').val(), $('#txtLoanAmount').val(), $('#txtInterestRates').val(), $('#txtPayment').val());
}
else {
// Call the Send method on the hub.
chatHub.server.send($('#txtLoanType option:selected').val(), $('#txtLoanAmount').val(), $('#txtInterestRates').val(), $('#txtPayment').val());
}
}
chatHub.client.broadcastMessage = function (loanType, loanAmount, interestRates, payment) {
$('#txtLoanType').val(loanType);
$('#txtLoanAmount').val(loanAmount);
$('#txtInterestRates').val(interestRates);
$('#txtPayment').val(payment);
};
but when I try to send values to specific user it is not working: as I am debussing the C# code is working I thing the problem is in JS:
this is C# method that send values of text boxes to specific user:
public void Send(string message, string to, string loanType, string loanAmount, string interestRates, string payment)
{
User receiver;
if (Users.TryGetValue(to, out receiver))
{
User sender = GetUser(Context.User.Identity.Name);
IEnumerable<string> allReceivers;
lock (receiver.ConnectionIds)
{
lock (sender.ConnectionIds)
{
allReceivers = receiver.ConnectionIds.Concat(sender.ConnectionIds);
}
}
foreach (var cid in allReceivers)
{
Clients.Client(cid).broadcastMessage(new { message = message, isPrivate = true, loanType = loanType,
loanAmount = loanAmount,
interestRates = interestRates,
payment = payment
});
}
}
}
it will call the Private part in JS file that is :
if (viewModel.isInPrivateChat()) {
$.connection.hub.start();
chatHub.server.send(msgValue, viewModel.privateChatUser(), $('#txtLoanType option:selected').val(), $('#txtLoanAmount').val(), $('#txtInterestRates').val(), $('#txtPayment').val());
The function signatures do not match. There are different number of paramerters, they have to match exactly or the javascript function will never be called, it looks like you are trying use the parameters for the send function, when you are calling the broadcastMessage function.
In the JavaScript for the user you are looking for:
function (loanType, loanAmount, interestRates, payment)
But you are sending:
broadcastMessage(new { message = message, isPrivate = true, loanType = loanType,
loanAmount = loanAmount,
interestRates = interestRates,
payment = payment
})

Reference controls within web service?

I have an onBlur() function in a textbox which calls a web service.
The web service checks the email entered in the textbox against a SQL table to see if it's in there and if it is, I need it to deactivate an ASP Button. (Plus a bit more fiddly stuff, but once I crack the button all should be well). However, whenever I try to reference the button control (or any other ASP control) inside the web service I am treated to an error "Cannot refer to an instance member of a class from with a shared method..."
How can I disable a button & change a panel's visibility from the web service?
onBlur()
In VB.net
txtEmail.Attributes.Add("onblur", CStr(IIf(c.AccountNo > 0, "", "CallMe(this.id,this.id);")))
In Jscript.js file
//AJAX Call to server side code
function CallMe(src, dest) {
aForgotPwd.style.display = 'none';
var ctrl = document.getElementById(src);
var cont = document.getElementById(btn);
var panel = document.getElementById(pnl);
// call server side method
return PageMethods.ValidateEmail(ctrl.value, CallSuccess, CallFailed, dest);
}
// set the destination textbox value with the ContactName
function CallSuccess(res, destCtrl) {
var dest = document.getElementById(destCtrl);
if (res == "") {
if(aForgotPwd.style.display != 'none')
{ aForgotPwd.style.display = 'none'; }
return true;
} else {
setTimeout("aForgotPwd.style.display='block';", 1);
setTimeout("dest.focus();", 1);
setTimeout("dest.select();", 1);
alert("We have your email address already in our database. Please visit forgot your password page");
return false;
}
//alert(res.get_message());
// var dest = document.getElementById(destCtrl);
}
// alert message on some failure
function CallFailed(res, destCtrl) {
var dest = document.getElementById(destCtrl);
return true;
}
Web Service called by CallMe() function
'Email Validation
<System.Web.Services.WebMethod()> _
Public Shared Function ValidateEmail(email As String) As String
Dim wbClient As WebClient = New WebClient()
Dim strUrl As String = ConfigurationManager.AppSettings("WebsiteURLFull") + "/ajax/check_email_address.aspx?Email=" + email
Dim reqHTML As Byte()
reqHTML = wbClient.DownloadData(strUrl)
Dim objUTF8 As UTF8Encoding = New UTF8Encoding()
Dim output As String = objUTF8.GetString(reqHTML)
If String.IsNullOrEmpty(output) Then
exists = False
Else
exists = True
btnContinue.enabled = False
End If
If String.IsNullOrEmpty(output) Then Return String.Empty
Dim c As GPCUser
If TypeOf HttpContext.Current.Session("Customer") Is GPCUser Then
c = CType(HttpContext.Current.Session("Customer"), GPCUser)
If c.AccountNo > 0 Then Return ""
End If
Return output
End Function
You cannot acces page objects in the web service method, rather you can disable the button and the visibility of the panel post the execution of the webservice in your call back function. Just return a message from your method which says email already present or new. Let me know if I am unclear.
EDIT
You can find further details of the webmethod implementation in this link https://msdn.microsoft.com/en-us/library/byxd99hx(v=vs.90).aspx
<System.Web.Services.WebMethod(EnableSession:=True)> _
Public Shared Function ValidateEmail(email As String) As String
Dim wbClient As WebClient = New WebClient()
Dim strUrl As String = ConfigurationManager.AppSettings("WebsiteURLFull") + "/ajax/check_email_address.aspx?Email=" + email
Dim reqHTML As Byte()
reqHTML = wbClient.DownloadData(strUrl)
Dim objUTF8 As UTF8Encoding = New UTF8Encoding()
Dim output As String = objUTF8.GetString(reqHTML)
If String.IsNullOrEmpty(output) Then
exists = False
Else
exists = True
'btnContinue.enabled = False
'Commenting the Button enabling
output="disable"
'Assinging the output as disable so that in JS you can disable btn
End If
If String.IsNullOrEmpty(output) Then Return String.Empty
Dim c As GPCUser
If TypeOf HttpContext.Current.Session("Customer") Is GPCUser Then
c = CType(HttpContext.Current.Session("Customer"), GPCUser)
If c.AccountNo > 0 Then Return ""
End If
Return output
End Function
Also now in the CallSuccess before you continue with your functionality check whether the res is disable then you can disable button and display the already existing message.

Categories