Rider HTTP Client Build JWT Token in Pre-Reques Script - javascript

Currently using Rider HTTP Client Plugin as documented here to build out some API test scripts and sample calls. For one of the tests I need to build a JWT token in the Pre-Rquest Script and after many failed attempts I post this question.
this is my current script, have tried a few diff variations with no luck.
let header = JSON.stringify({"alg": "HS512"});
let body = JSON.stringify({
"username": request.environment.get('the_big_username'),
"entity": request.environment.get('the_big_entity'),
"datetime": new Date().toISOString()
});
let theBigSecret = request.environment.get("the_big_secret");
let theHeader = crypto.sha512()
.updateWithText(header)
.digest()
.toBase64(true)
let theBody = crypto.sha512()
.updateWithText(body)
.digest()
.toBase64(true)
const content = `${theHeader}.${theBody}`
let theSignature = encodeURIComponent(crypto.hmac.sha512()
.withTextSecret(theBigSecret)
.updateWithText(content)
.digest()
.toBase64(true))
const allTogetherNow = `${content}.${theSignature}`
// pm.globals.set('jws', signedJws);
request.variables.set('the_big_token', allTogetherNow);
so far all results fail and are not decodable by jwt.io and after much searching and documentation reading I have not gotten any closer to understanding where I am going wrong.

Related

Does verifying the signature of an RS256 JWT really take half a second?

I am trying to verify a JWT signature in Javascript using a public key. I have tried the 'jose' and 'jsrsasign' libraries with similar results: the verification is painfully slow (400-500ms).
After googling, from what I can understand the actual verification of the signature should be sub-millisecond. Am I doing something wrong or have i misunderstood what people are saying?
This is what the current code looks like using 'jsrsasign':
import rs from 'jsrsasign';
// [...]
const timeBeforeTokenVerify = Date.now();
const keyObject = rs.KEYUTIL.getKey(jwks.keys[0]);
const isValid = rs.jws.JWS.verifyJWT(clientToken, keyObject, { alg: ['RS256'] });
if (!isValid) {
throw new Error('Token is not valid');
}
console.log(Date.now() - timeBeforeTokenVerify) // prints 400 to 500

Telegram: check authorization hash mismatch

I'm trying to use javascript to implement this Telegram PHP example, but the hashes don't match. I ran the example's php code; it also failed, and the hash returned by the example and mine are identical. I'm wondering if it has anything to do with my bot settings (I set my domain to 127.0.0.1 and try another https domain - still failed). I'm completely stuck and have no idea how to make it work.
My code is as follows:
'use strict';
const sha256 = require('crypto-js/sha256');
const hmacSHA256 = require('crypto-js/hmac-sha256');
const Hex = require('crypto-js/enc-hex');
const { ValidationError } = require('objection');
const data = {
id: 5528016998,
first_name: 'Lê Văn',
last_name: 'Hùng',
username: 'HungLV46',
photo_url: 'https://t.me/i/userpic/320/gy_L5Q2zLLZyUrtCw0Fh9D0oy0CuabiM2A0-68FY27Inz94yP7ypxCrAF7G7_asy.jpg',
auth_date: 1670774122,
hash: '893e4bd66128d8696d63aa285b0aff6e8b970cbe9c9e43dacfa9e2da7420c16c'
};
function verifyAuthorization(params) {
if ((new Date() - new Date(params.auth_date * 1000)) > 86400000) { // milisecond
throw new ValidationError('Authorization data is outdated');
}
const verificationParams = { ...params };
delete verificationParams.hash;
const message = Object.keys(verificationParams)
.map(key => `${key}=${verificationParams[key]}`)
.sort().join('\n');
const secretKey = sha256('xxxx'); // replace with the token of my bot
const hash = Hex.stringify(hmacSHA256(message, secretKey));
if (hash !== params.hash) {
throw new ValidationError('Authorization data is not from telegram!');
}
}
verifyAuthorization(data);
similar question
Edit:
After experimenting with the login widget for some time, I tried to print return value to the developer console of Chrome (pressing f12, console tab), and then run my code again. The 2 hashes awardly match!. 
I initially got the user info and hash from the response of this API, POST https://oauth.telegram.org/auth/get?bot_id=xxx in network-tab, and it turned out the response of API in network-tab was different from the response printed in console-tab.
I tried some more time, and the response of the API suddenly worked well with my function. Now I am just curious about why?

Error: Only replay-protected (EIP-155) transactions allowed over RPC

When I try to send funds from a token address to another I encounter this error: only replay-protected (EIP-155) transactions allowed over RPC
My Code:
const contract = new web3.eth.Contract(ABI, token_contract_address);
const data = contract.methods.transfer(to, req.body.value).encodeABI();
const rawTransaction = {
'from': from,
'nonce': web3.utils.toHex(web3.eth.getTransactionCount(from)),
'gasPrice': web3.utils.toHex(web3.eth.gasPrice),
'gasLimit': web3.utils.toHex(21000),
'to': token_contract_address,
'value': 0,
'data': data,
'chainId': web3.utils.toHex(chainid)
};
const privateKey = new Buffer.from(req.body.PrivateKey, 'hex');
const tx = new Tx(rawTransaction);
tx.sign(privateKey);
const serializedTx = tx.serialize();
web3.eth.sendSignedTransaction(('0x' + serializedTx.toString('hex')), req.body.PrivateKey)
.then(function (result) {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json(result * decimals);
console.log(result);
})
.catch((err) => next(err));
Notice I have already added ChainId
Here is an excellent example that looks like yours and should definitely work. What I think is happening here, is that there are already some pending transactions, so that your current nonce is causing this error message. Some small steps that might solve your issue and improve your code:
Change value from 0 to 0x00, this should also be hex encoded. Or you could leave it out, because you are also sending data.
Alternatively you could set
value to something like web3.utils.toHex(web3.utils.toWei('123', 'wei')).
Create the nonce with web3.eth.getTransactionCount(account.address, 'pending');. This would also include pending transactions to the count so that they are not used twice.
And what is the reason why you are adding req.body.PrivateKey to sendSignedTransaction(..)? Just adding the serialized transaction that you signed before is enough: '0x' + serializedTx.toString('hex').
It is not clear what your current chainId is. Try running your code on another chain to see if that works.
Ropsten = 3
Rinkeby = 4
Finally, update all your dependencies / the tools you are using. Changes in packages may sometimes cause issues like this.
You'll find another excellent example here.

JS SDK, Thrift error code 12 when getting SharedNotebooksList

It's the first time that I work with evernote,
Like the example given in the JS SDK, I create my client with the token that I get from the OAuth and I get all the notebooks of my current user so it was good for me.
But I'm facing a problem that I can't understand, when I use any method of my shared store it throw an Thrift exception with error code 12 and giving the shard id in the message.
I know that 12 error code is that the shard is temporary unavailable..
But I know that it's another thing because it's not temporary...
I have a full access api key, it work with the note store, did I miss something ?
// This is the example in the JS SDK
var linkedNotebook = noteStore.listLinkedNotebooks()
.then(function(linkedNotebooks) {
// just pick the first LinkedNotebook for this example
return client.getSharedNoteStore(linkedNotebooks[0]);
}).then(function(sharedNoteStore) {
// /!\ There is the problem, throw Thrift exception !
return sharedNoteStore.listNotebooks().then(function(notebooks) {
return sharedNoteStore.listTagsByNotebook(notebooks[0].guid);
}).then(function(tags) {
// tags here is a list of Tag objects
});
});
this seems to be an error with the SDK. I created a PR (https://github.com/evernote/evernote-sdk-js/pull/90).
You can work around this by using authenticateToSharedNotebook yourself.
const client = new Evernote.Client({ token, sandbox });
const noteStore = client.getNoteStore();
const notebooks = await noteStore
.listLinkedNotebooks()
.catch(err => console.error(err));
const notebook = notebooks.find(x => x.guid === guid);
const { authenticationToken } = await client
.getNoteStore(notebook.noteStoreUrl)
.authenticateToSharedNotebook(notebook.sharedNotebookGlobalId);
const client2 = new Evernote.Client({
token: authenticationToken,
sandbox
});
const noteStore2 = client2.getNoteStore();
const [notebook2] = await noteStore2.listNotebooks();
noteStore2.listTagsByNotebook(notebook2.guid)

Generating Twillio Access Tokens using Node JS

I'm developing an application that uses Twillios Programmable Video API.
I'm new to using Node JS, but the documentation has been fairly straightforward, however I still have a few questions.
Here's code I am referencing.
const AccessToken = require('twilio').jwt.AccessToken;
const VideoGrant = AccessToken.VideoGrant;
// Used when generating any kind of tokens
const twilioAccountSid = 'ACxxxxxxxxxx';
const twilioApiKey = 'SKxxxxxxxxxx';
const twilioApiSecret = 'xxxxxxxxxxxx';
const identity = 'user';
// Create Video Grant
const videoGrant = new VideoGrant({
room: 'cool room'
});
// Create an access token which we will sign and return to the client,
// containing the grant we just created
const token = new AccessToken(twilioAccountSid, twilioApiKey, twilioApiSecret);
token.addGrant(videoGrant);
token.identity = identity;
// Serialize the token to a JWT string
console.log(token.toJwt());
In this specific example provided by Twillio, the video grant which I assume is mandatory is explicitly referenced, however that would mean for this specific token generator, the users can only enter rooms of that name.
I was wondering if it was possible to reference the room before configuring the token. Something similar to how the identity is a variable that's entered into the function before the token is output.
In addition, are there any required dependencies or libraries when creating tokens outside of Twillios own function environment?
Any answers, suggestions, or references are greatly appreciated.
Twilio developer evangelist here.
It is possible to supply the room name as a variable too. You might want to create a function that can take an identity and room name as arguments and returns an access token. Something like this:
const AccessToken = require('twilio').jwt.AccessToken;
const VideoGrant = AccessToken.VideoGrant;
// Used when generating any kind of tokens
const twilioAccountSid = 'ACxxxxxxxxxx';
const twilioApiKey = 'SKxxxxxxxxxx';
const twilioApiSecret = 'xxxxxxxxxxxx';
function generateToken(identity, roomName) {
const videoGrant = new VideoGrant({
room: roomName
});
const token = new AccessToken(twilioAccountSid, twilioApiKey, twilioApiSecret);
token.addGrant(videoGrant);
token.identity = identity;
return token.toJwt();
}
Then you can use the function like:
const token = generateToken("Stefan", "StefansRoom");
Let me know if that helps at all.

Categories

Resources