getAsBuffer() fails with "Cannot read property 'length' of undefined"
AlexisBian opened this issue · comments
Hi,
Thanks for your work and hope everything goes well!
I am using this library in lambda and i got "Cannot read property 'length' of undefined" when I call getAsBuffer() or getAsStream()
Here is my code:
async createApplePassCard(S3,modelFile, userID, balance) {
console.log(modelFile)
const pass = await PKPass.from({
model: modelFile,
certificates: {
wwdr: fs.readFileSync(this.wwdr).toString(),
signerCert: fs.readFileSync(this.signerCert).toString(),
signerKey: fs.readFileSync(this.signerKey).toString(),
signerKeyPassphrase: this.signerKeyPassPhrase,
},
}, {
serialNumber: userID
});
pass.setBarcodes(userID);
pass.primaryFields.push({
"key": "balance",
"label": "Balance",
"value": balance
});
pass.secondaryFields.push({
"key": "cardID",
"label": "cardID",
"value": userID
});
const buffer = pass.getAsBuffer() // goes wrong here
}
And it is Error Message:
{
"errorType": "TypeError",
"errorMessage": "Cannot read property 'length' of undefined",
"trace": [
"TypeError: Cannot read property 'length' of undefined",
" at Object.ctx.start (/opt/nodejs/node_modules/node-forge/lib/hmac.js:79:24)",
" at Object.module.exports.forge.pbkdf2.pkcs5.pbkdf2 (/opt/nodejs/node_modules/node-forge/lib/pbkdf2.js:136:7)",
" at Object.pki.pbe.getCipherForPBES2 (/opt/nodejs/node_modules/node-forge/lib/pbe.js:854:24)",
" at Object.pki.pbe.getCipher (/opt/nodejs/node_modules/node-forge/lib/pbe.js:757:20)",
" at Object.pki.decryptPrivateKeyInfo (/opt/nodejs/node_modules/node-forge/lib/pbe.js:372:24)",
" at Object.pki.decryptRsaPrivateKey (/opt/nodejs/node_modules/node-forge/lib/pbe.js:616:16)",
" at parseCertificates (/opt/nodejs/node_modules/passkit-generator/lib/Signature.js:91:45)",
" at Object.create (/opt/nodejs/node_modules/passkit-generator/lib/Signature.js:30:45)",
" at PKPass.[pass.close] (/opt/nodejs/node_modules/passkit-generator/lib/PKPass.js:474:43)",
" at PKPass.getAsBuffer (/opt/nodejs/node_modules/passkit-generator/lib/PKPass.js:489:42)"
]
}
I am not sure what goes wrong. if it is possible would you please take a look at it? Thanks a lot!🙏
Alexis
Hey there @AlexisBian!
Thanks for using passkit-generator!
I'm not very sure of what is happening, but my suspect is directed towards that .toString()
on wwdr
, signerCert
and signerKey
calls.
I mean, I don't know if those .toString()
make the string invalid somehow. I guess you used it because fs.readFileSync
was returning you a Buffer instead of a string.
I can suggest you to separate and log and see if something changes. Something like this.
const wwdr = fs.readFileSync(this.wwdr);
const signerCert = fs.readFileSync(this.signerCert);
const signerKey = fs.readFileSync(this.signerKey);
const signerKeyPassphrase = this.signerKeyPassPhrase;
console.log("RAW WWDR", wwdr, "tostring:", wwdr.toString());
console.log("RAW signerCert", signerCert, "tostring:", signerCert.toString());
console.log("RAW signerKey", signerKey, "tostring:", signerKey.toString());
const pass = await PKPass.from({
model: modelFile,
certificates: {
wwdr,
signerCert,
signerKey,
signerKeyPassphrase,
},
}, {
serialNumber: userID
});
Also, you might want to set the encoding to ensure they are strings without the need to convert them.
const wwdr = fs.readFileSync(this.wwdr, { encoding: "utf-8" });
const signerCert = fs.readFileSync(this.signerCert, { encoding: "utf-8" });
const signerKey = fs.readFileSync(this.signerKey, { encoding: "utf-8" });
const signerKeyPassphrase = this.signerKeyPassPhrase;
And check if the content changes somehow.
Let me know!
Hi @alexandercerutti Thanks for your quick response! I figure it out.
The certificates part is the source of the problem but not toString() Part. I found if I pass certs through the function"createApplePassCard" it would work but if I pass certs through the constructor function it does not work.
I am not good at js so I am not sure why it happened.
Here is the code which works
class ApplePassCard {
constructor() {
}
async createApplePassCard(certs, S3, modelFile, userID, balance) {
const wwdr = certs.wwdr
const signerCert = certs.signerCert
const signerKey = certs.signerKey
const signerKeyPassphrase = certs.signerKeyPassphrase
try{
const pass = await PKPass.from({
model: modelFile,
certificates: {
wwdr: fs.readFileSync(wwdr).toString(),
signerCert:fs.readFileSync(signerCert).toString(),
signerKey:fs.readFileSync(signerKey).toString(),
signerKeyPassphrase:signerKeyPassphrase,
},
}, {
// keys to be added or overridden
serialNumber: userID
});
pass.setBarcodes(userID); // Random value
pass.primaryFields.push({
"key": "balance",
"label": "Balance",
"value": balance
});
pass.secondaryFields.push({
"key": "cardID",
"label": "cardID",
"value": userID
});
const buffer = pass.getAsBuffer()
···
}
}
Thanks again!
Sorry for the delay in my response, I thought to have answered you back eheh!
Glad you solved it. However, what you are saying to me sounds really weird, you know?
Sadly I don't have a full context here, so I'm not quite sure about what is happening, but it feels like it should be the same thing.
Guess we could close this now! Let me know if this should be re-opened 👍.
Thank you again for using passkit-generator