Implementing TLV in javascript - javascript

I am trying to implement TLV for e-invoice in Javascript. I am able to convert the values to hex and from hex to base64. When I add the base64 value to the QRcode and try to test it, I get an error telling me there is something wrong with my data. Below is my implementation
const __toString = (tag, value) => {
const tagToHex = "0"+(tag).toString(16)
const valueLengthToHex = value.length <= 15 ? "0" + (value.length).toString(16) :(value.length).toString(16)
const valueToHex = this.toHex(value)
return `${tagToHex}${valueLengthToHex}${valueToHex}`;
}
const toHex = (str) => {
let result = '';
for (let i=0; i<str.length; i++) {
result += str.charCodeAt(i).toString(16);
}
return result;
}
Entry point
const generateString = [
__toString(1, 'Bobs Records'),
__toString(2, '310122393500003'),
__toString(3, '2022-04-25T15:30:00Z'),
__toString(4, '1000.00'),
__toString(5, '150.00'),
];
return btoa(generateString.join(''))
MDEwYzQyNmY2MjczMjA1MjY1NjM2ZjcyNjQ3MzAyMGYzMzMxMzAzMTMyMzIzMzM5MzMzNTMwMzAzMDMwMzMwMzE0MzIzMDMyMzIyZDMwMzQyZDMyMzU1NDMxMzUzYTMzMzAzYTMwMzA1YTA0MDczMTMwMzAzMDJlMzAzMDA1MDYzMTM1MzAyZTMwMzA=
I get the base64 string above. When I set it as the value of the qrcode and try to scan it, I get errors and I do not know where I am missing it.

I was able to use this NPM package npm i --save #axenda/zatca to solve the problem. For more info, visit this page https://github.com/axenda/zatca

Related

How to create a Markdown table of contents

I want to create a table of contents from a markdown file in next.js and I want it to be in markdown format as well.
To achieve that I have made this function:
const getMarkdownTOC = (slug) => {
const folder = process.env.PATH_ARTICULOS
const file = `${folder}${slug}.md`
const content = fs.readFileSync(file, 'utf8')
const matterResult = matter(content)
let prevLevel = 99
let spaces = ''
let toc = ''
for (const [, value] of Object.entries(compiler(matterResult.content).props.children)) {
if (value.type !== undefined && value.type.startsWith('h') && !isNaN(value.type[1])) {
const level = Number(value.type[1])
const title = value.props.children[0]
const id = value.props.id
if (level > prevLevel) {
spaces += ' '
} else {
if (level < prevLevel) {
spaces = spaces.slice(0, spaces.length - 2 * (prevLevel - level))
}
}
toc += `${spaces}* [${title}](#${id})\n`
prevLevel = level
}
}
And the function does actually work, it returns a table of contents in markdown format that can be rendered wherever I want.
However, I think there has to be some easier way to achieve that, but I've been searching and haven't found anything. There is a plugin called remark-toc which is almost what I want, but it seems to create the table of contents at the beginning of the document and I want to keep it apart.
Any ideas? Thank you!

JavaScript Object - Split() method + '\n'

I reached 'fetch' method...
A simple question (complicated for me) ...
How to use 'fetch()' method, 'split()' and '\ n' together?
I will show you an example (i am here to learn and master some skills and i am not ashamed to ask):
I need to read and print the following data using the 'fetch' method:
from the following link 'https://v-dresevic.github.io/Advanced-JavaScript-Programming/data/students.txt' - it is necessary to read the data and print them on the page.
And that is quite clear to me! I managed to do that!
code: enter image description here
my result (wrong result): enter image description here
correct result: enter image description here
My question is:
After reading the data from the file, I have to parse them and create Student objects based on them.
Parsing can be done using the split () method of the String object.
It is best to divide the read text by line breaks, specifying "\ n" for the split () method parameter.
thanks in advance :)
here is a fast example of parsing your data to an array of objects as i think this is the only thing you ask here, from there you can loop that array and display the object as you need.
const url =
"https://v-dresevic.github.io/Advanced-JavaScript-Programming/data/students.txt";
let result = fetch(url)
.then((r) => r.text())
.then(process);
function process(result) {
const linesDescription = ["Name", "Address", "Phone", "Course"];
const array = [];
let obj = {};
var lines = result.split("\n");
let x = 0;
for(var line = 0; line < lines.length; line++){
obj[linesDescription[x]] = lines[line].trim();
x++;
if (x >= linesDescription.length) {
array.push(obj);
x = 0;
obj = {};
}
};
console.log(array);
}

Convert object with arrays to new objects and attach it

I will this typescript object convert:
api:{
accessToken:[user1::aaaaa,user2::bbbbb],
accessSecret:[user1:aaaaa,userb::bbbbb]
}
i will split the string inside the arrays by :: sign.
Finish object should look like this
api:{
accessToken:[user1::aaaaa,user2::bbbbb],
accessSecret:[user1:aaaaa,userb::bbbbb],
user1_access:aaaaa,
user2_access:bbbbb,
user1_secret:aaaaa,
user2_secret:bbbbb
}
What is the best solution without compile errors in typescript, please Help.
Here is a sample which gives you an idea of how to go about it,
const api = {
accessToken:["user1::aaaaa","user2::bbbbb"],
accessSecret:["user1::xxxx","user2::yyyy"]
};
const newApiObj: any = {};
const accessTokenvalues = api.accessToken.map(x => x.split("::")) ?? [];
for(const item of accessTokenvalues){
newApiObj[item[0] + '_access'] = item[1];
}
const accessSecretvalues = api.accessSecret.map(x => x.split("::")) ?? [];
for(const item of accessSecretvalues){
newApiObj[item[0] + '_secret'] = item[1];
}
console.log(newApiObj);

How to convert this QueryString to a JS Object? [NODEJS]

I have the following querystring which is a IPN by wirecard, so i can't modify this input, this is what i receive in the POST.
I have no clue why is this being sent as text/plain instead of application/json
https://doc.wirecard.com/GeneralPlatformFeatures.html#GeneralPlatformFeatures_IPN
response-signature-base64=sGwuDEpTnTB7XwzPga8DG+pYYjB3bga7YOZI8n26yOns=&response-signature-algorithm=HmacSHA256&response-base64=eyJwYXltZW50Ijp7InN0YXR1c2VzIjp7InN0YXR1cyI6W3siY29kZSI6Ij
IwMS4wMDAwIiwiZGVzY3JpcHRpb24iOiIzZC1hY3F1aXJlcjpUaGUgcmVzb3VyY2Ugd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiIsInNldmVyaXR5IjoiaW5mb3JtYXRpb24ifV19LCJjYXJkIjp7ImV4cGlyYXRpb24tbW9udGgiOjEsImV4cGl
yYXRpb24teWVhciI6MjAyMywiY2FyZC10eXBlIjoidmlzYSJ9LCJkZXNjcmlwdG9yIjoiIiwibm90aWZpY2F0aW9ucyI6eyJub3RpZmljYXRpb24iOlt7InVybCI6Imh0dHBzOi8vNDY0Yjk4N2M2ZDk5Lm5ncm9rLmlvL3B1YmxpY3Mvd2lyZWNh
cmQyIn1dLCJmb3JtYXQiOiJhcHBsaWNhdGlvbi9qc29uLXNpZ25lZCJ9LCJtZXJjaGFudC1hY2NvdW50LWlkIjp7InZhbHVlIjoiN2E2ZGQ3NGYtMDZhYi00ZjNmLWE4NjQtYWRjNTI2ODcyNzBhIn0sInRyYW5zYWN0aW9uLWlkIjoiOTQwNGIxN
jQtMTgzYy00ZjllLThmNGEtN2QzMGUxODA2ZWRjIiwicmVxdWVzdC1pZCI6Ijk3NzJiMzViLTdmYmUtNGYxZS04NmQ5LThhNjMwZDljZDg3YyIsInRyYW5zYWN0aW9uLXR5cGUiOiJwdXJjaGFzZSIsInRyYW5zYWN0aW9uLXN0YXRlIjoic3VjY2
VzcyIsImNvbXBsZXRpb24tdGltZS1zdGFtcCI6MTU5NTkyNDA0OTAwMCwicmVxdWVzdGVkLWFtb3VudCI6eyJ2YWx1ZSI6MTAsImN1cnJlbmN5IjoiVVNEIn0sImFjY291bnQtaG9sZGVyIjp7ImZpcnN0LW5hbWUiOiJkIiwibGFzdC1uYW1lIjo
iZCJ9LCJjYXJkLXRva2VuIjp7InRva2VuLWlkIjoiNDI0Mjc5NjQ0NDA5MDAxOCIsIm1hc2tlZC1hY2NvdW50LW51bWJlciI6IjQyMDAwMCoqKioqKjAwMTgifSwicGF5bWVudC1tZXRob2RzIjp7InBheW1lbnQtbWV0aG9kIjpbeyJuYW1lIjoi
Y3JlZGl0Y2FyZCJ9XX0sImF1dGhvcml6YXRpb24tY29kZSI6IjE0Mzk3NyIsImFwaS1pZCI6IndwcCIsImNhbmNlbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvY2FuY2VsIiwiZ
mFpbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvZXJyb3IiLCJzdWNjZXNzLXJlZGlyZWN0LXVybCI6Imh0dHBzOi8vZGVtb3Nob3AtdGVzdC53aXJlY2FyZC5jb20vZGVtb3Nob3
AvIy9zdWNjZXNzIiwicHJvdmlkZXItYWNjb3VudC1pZCI6IjcwMDEwIn19
As you can see the query parameters are base64 encoded, which is a problem because it includes + and = that are going to break if use URLSearchParams or any other method of converting .
I tried using bodyparser.urlencoded but this transforms '+' to ' '
how can i split this safely while keeping the 3 variables intact
response-signature-base64
response-signature-algorithm
response-base64
If the URL Web API available you could create a URL and read the searchParams from it.
If not you can use Javascripts split() function using the limit argument:
queryString.split('&').map((value) => value.split('=', 2));
if an array of arrays is not what you want you can append an other processing step and do something like this:
queryString
.split('&').map((value) => value.split('=', 2))
.reduce((obj, value) => {
obj[value[0]] = value[1];
return obj;
}, {});
the following snippet shows the code in action
const queryString = 'response-signature-base64=sGwuDEpTnTB7XwzPga8DG+pYYjB3bga7YOZI8n26yOns=&response-signature-algorithm=HmacSHA256&response-base64=eyJwYXltZW50Ijp7InN0YXR1c2VzIjp7InN0YXR1cyI6W3siY29kZSI6IjIwMS4wMDAwIiwiZGVzY3JpcHRpb24iOiIzZC1hY3F1aXJlcjpUaGUgcmVzb3VyY2Ugd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiIsInNldmVyaXR5IjoiaW5mb3JtYXRpb24ifV19LCJjYXJkIjp7ImV4cGlyYXRpb24tbW9udGgiOjEsImV4cGlyYXRpb24teWVhciI6MjAyMywiY2FyZC10eXBlIjoidmlzYSJ9LCJkZXNjcmlwdG9yIjoiIiwibm90aWZpY2F0aW9ucyI6eyJub3RpZmljYXRpb24iOlt7InVybCI6Imh0dHBzOi8vNDY0Yjk4N2M2ZDk5Lm5ncm9rLmlvL3B1YmxpY3Mvd2lyZWNhcmQyIn1dLCJmb3JtYXQiOiJhcHBsaWNhdGlvbi9qc29uLXNpZ25lZCJ9LCJtZXJjaGFudC1hY2NvdW50LWlkIjp7InZhbHVlIjoiN2E2ZGQ3NGYtMDZhYi00ZjNmLWE4NjQtYWRjNTI2ODcyNzBhIn0sInRyYW5zYWN0aW9uLWlkIjoiOTQwNGIxNjQtMTgzYy00ZjllLThmNGEtN2QzMGUxODA2ZWRjIiwicmVxdWVzdC1pZCI6Ijk3NzJiMzViLTdmYmUtNGYxZS04NmQ5LThhNjMwZDljZDg3YyIsInRyYW5zYWN0aW9uLXR5cGUiOiJwdXJjaGFzZSIsInRyYW5zYWN0aW9uLXN0YXRlIjoic3VjY2VzcyIsImNvbXBsZXRpb24tdGltZS1zdGFtcCI6MTU5NTkyNDA0OTAwMCwicmVxdWVzdGVkLWFtb3VudCI6eyJ2YWx1ZSI6MTAsImN1cnJlbmN5IjoiVVNEIn0sImFjY291bnQtaG9sZGVyIjp7ImZpcnN0LW5hbWUiOiJkIiwibGFzdC1uYW1lIjoiZCJ9LCJjYXJkLXRva2VuIjp7InRva2VuLWlkIjoiNDI0Mjc5NjQ0NDA5MDAxOCIsIm1hc2tlZC1hY2NvdW50LW51bWJlciI6IjQyMDAwMCoqKioqKjAwMTgifSwicGF5bWVudC1tZXRob2RzIjp7InBheW1lbnQtbWV0aG9kIjpbeyJuYW1lIjoiY3JlZGl0Y2FyZCJ9XX0sImF1dGhvcml6YXRpb24tY29kZSI6IjE0Mzk3NyIsImFwaS1pZCI6IndwcCIsImNhbmNlbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvY2FuY2VsIiwiZmFpbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvZXJyb3IiLCJzdWNjZXNzLXJlZGlyZWN0LXVybCI6Imh0dHBzOi8vZGVtb3Nob3AtdGVzdC53aXJlY2FyZC5jb20vZGVtb3Nob3AvIy9zdWNjZXNzIiwicHJvdmlkZXItYWNjb3VudC1pZCI6IjcwMDEwIn19'
const result = queryString
.split('&').map((value) => value.split('=', 2))
.reduce((obj, value) => {
obj[value[0]] = value[1];
return obj;
}, {});
console.log(result)
ALMOST, but not quite, using this code
function fromBinary(binary) {
console.log(binary.length)
if (binary.length%2 != 0) binary += "="; // my hack - may not work
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < bytes.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return String.fromCharCode(...new Uint16Array(bytes.buffer));
};
const str = `response-signature-base64=sGwuDEpTnTB7XwzPga8DG+pYYjB3bga7YOZI8n26yOns=&response-signature-algorithm=HmacSHA256&response-base64=eyJwYXltZW50Ijp7InN0YXR1c2VzIjp7InN0YXR1cyI6W3siY29kZSI6Ij
IwMS4wMDAwIiwiZGVzY3JpcHRpb24iOiIzZC1hY3F1aXJlcjpUaGUgcmVzb3VyY2Ugd2FzIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiIsInNldmVyaXR5IjoiaW5mb3JtYXRpb24ifV19LCJjYXJkIjp7ImV4cGlyYXRpb24tbW9udGgiOjEsImV4cGl
yYXRpb24teWVhciI6MjAyMywiY2FyZC10eXBlIjoidmlzYSJ9LCJkZXNjcmlwdG9yIjoiIiwibm90aWZpY2F0aW9ucyI6eyJub3RpZmljYXRpb24iOlt7InVybCI6Imh0dHBzOi8vNDY0Yjk4N2M2ZDk5Lm5ncm9rLmlvL3B1YmxpY3Mvd2lyZWNh
cmQyIn1dLCJmb3JtYXQiOiJhcHBsaWNhdGlvbi9qc29uLXNpZ25lZCJ9LCJtZXJjaGFudC1hY2NvdW50LWlkIjp7InZhbHVlIjoiN2E2ZGQ3NGYtMDZhYi00ZjNmLWE4NjQtYWRjNTI2ODcyNzBhIn0sInRyYW5zYWN0aW9uLWlkIjoiOTQwNGIxN
jQtMTgzYy00ZjllLThmNGEtN2QzMGUxODA2ZWRjIiwicmVxdWVzdC1pZCI6Ijk3NzJiMzViLTdmYmUtNGYxZS04NmQ5LThhNjMwZDljZDg3YyIsInRyYW5zYWN0aW9uLXR5cGUiOiJwdXJjaGFzZSIsInRyYW5zYWN0aW9uLXN0YXRlIjoic3VjY2
VzcyIsImNvbXBsZXRpb24tdGltZS1zdGFtcCI6MTU5NTkyNDA0OTAwMCwicmVxdWVzdGVkLWFtb3VudCI6eyJ2YWx1ZSI6MTAsImN1cnJlbmN5IjoiVVNEIn0sImFjY291bnQtaG9sZGVyIjp7ImZpcnN0LW5hbWUiOiJkIiwibGFzdC1uYW1lIjo
iZCJ9LCJjYXJkLXRva2VuIjp7InRva2VuLWlkIjoiNDI0Mjc5NjQ0NDA5MDAxOCIsIm1hc2tlZC1hY2NvdW50LW51bWJlciI6IjQyMDAwMCoqKioqKjAwMTgifSwicGF5bWVudC1tZXRob2RzIjp7InBheW1lbnQtbWV0aG9kIjpbeyJuYW1lIjoi
Y3JlZGl0Y2FyZCJ9XX0sImF1dGhvcml6YXRpb24tY29kZSI6IjE0Mzk3NyIsImFwaS1pZCI6IndwcCIsImNhbmNlbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvY2FuY2VsIiwiZ
mFpbC1yZWRpcmVjdC11cmwiOiJodHRwczovL2RlbW9zaG9wLXRlc3Qud2lyZWNhcmQuY29tL2RlbW9zaG9wLyMvZXJyb3IiLCJzdWNjZXNzLXJlZGlyZWN0LXVybCI6Imh0dHBzOi8vZGVtb3Nob3AtdGVzdC53aXJlY2FyZC5jb20vZGVtb3Nob3
AvIy9zdWNjZXNzIiwicHJvdmlkZXItYWNjb3VudC1pZCI6IjcwMDEwIn19`
console.log([...new URLSearchParams(str).values()].map(val => fromBinary(atob(val))))

How to save richEmbed to file using FS in discord.js?

I created a unpurge feature on my discord bot, where it recovers the last bulk purged messages by just sending them to the general channel. In order to do this, I need the bot to save the richEmbed (which contains all the purged messages), and save it in a text file, which I will then encrypt using simple-crypto.js for security.
The issue arises when I try to save the richEmbed to the text file using fs, where the FS does not save the RichEmbed as UTF-8 text, and instead just saves '[object Object]', and also get an error,
DeprecationWarning: Calling an asynchronous function without callback is deprecated.
Here is that part of the code:
var fs = require("fs");
fs.writeFileSync("./unpurgeData.txt", embed ,{"encoding": "utf-8"});
...and here is the whole unpurge code:
if (cmd.startsWith("unpurge")) {
let x = 10, // x should be form 0 to 25
embed = new Discord.RichEmbed().setTitle('Fecthed messages');
msg.channel.fetchMessages({ limit: x }).then(messages => {
let arr = messages.array(); // you get the array of messages
for (let i = 0; i < arr.length; i++) { // you loop through them
let curr = arr[i],
str = curr.content.trim();
if (str.length > 2048) str = str.substring(0, 2045) + '...';
// if the content is over the limit, you cut it
embed.addField(curr.author, str); // then you add it to the embed
if (i == arr.length - 1) {
msg.channel.send(embed);
var fs = require("fs");
fs.writeFileSync("./unpurgeData.txt", embed ,{"encoding": "utf-8"});
}
}
}).catch(console.error);
}
Your embed variable is an object type. You can check by doing:
console.log(typeof embed);
In this case you'd have to use JSON.Stringify to convert your object into a JSON string as it states in Mozilla docs.
const text = JSON.stringify(embed);
Then in your fs function just replace embed with the text variable.

Categories

Resources