GithubHelp home page GithubHelp logo

tinovyatkin / pass-js Goto Github PK

View Code? Open in Web Editor NEW
669.0 13.0 81.0 3.96 MB

Apple Wallet Passes generating library for Node.JS

License: MIT License

JavaScript 2.59% TypeScript 97.41%
apple wallet pass passkit ios nodejs apple-pass

pass-js's Introduction

npm (scoped) codecov Known Vulnerabilities Maintainability Rating tested with jest install size

Apple Wallet logo

@walletpass/pass-js

A Node.js library for generating Apple Wallet passes with localizations, NFC and web service push updates support. Written in Typescript.




Installation

Install with NPM or yarn:

npm install @walletpass/pass-js --save

yarn add @walletpass/pass-js

Get your certificates

To start with, you'll need a certificate issued by the iOS Provisioning Portal. You need one certificate per Pass Type ID.

After adding this certificate to your Keychain, you need to export it as a .p12 file first (go to Keychain Access, My Certificates and right-click to export), then convert that file into a .pem file using the passkit-keys command:

./bin/passkit-keys ./pathToKeysFolder

or openssl

openssl pkcs12 -in <exported_cert_and_private_key>.p12 -clcerts -out com.example.passbook.pem -passin pass:<private_key_password>

and copy it into the keys directory.

The Apple Worldwide Developer Relations Certification Authority certificate is not needed anymore since it is already included in this package.

Start with a template

Start with a template. A template has all the common data fields that will be shared between your passes.

const { Template } = require("@walletpass/pass-js");

// Create a Template from local folder, see __test__/resources/passes for examples
// .load will load all fields from pass.json,
// as well as all images and com.example.passbook.pem file as key
// and localization string too
const template = await Template.load(
  "./path/to/templateFolder",
  "secretKeyPasswod"
);

// or
// create a Template from a Buffer with ZIP content
const s3 = new AWS.S3({ apiVersion: "2006-03-01", region: "us-west-2" });
const s3file = await s3
  .getObject({
    Bucket: "bucket",
    Key: "pass-template.zip"
  })
  .promise();
const template = await Template.fromBuffer(s3file.Body);

// or create it manually
const template = new Template("coupon", {
  passTypeIdentifier: "pass.com.example.passbook",
  teamIdentifier: "MXL",
  backgroundColor: "red",
  sharingProhibited: true
});
await template.images.add("icon", iconPngFileBuffer)
                     .add("logo", pathToLogoPNGfile)

The first argument is the pass style (coupon, eventTicket, etc), and the second optional argument has any fields you want to set on the template.

You can access template fields directly, or from chained accessor methods, e.g:

template.passTypeIdentifier = "pass.com.example.passbook";
template.teamIdentifier = "MXL";

The following template fields are required:

  • passTypeIdentifier - The Apple Pass Type ID, which has the prefix pass.
  • teamIdentifier - May contain an I

You can set any available fields either on a template or pass instance, such as: backgroundColor, foregroundColor, labelColor, logoText, organizationName, suppressStripShine and webServiceURL.

In addition, you need to tell the template where to find the key file:

await template.loadCertificate(
  "/etc/passbook/certificate_and_key.pem",
  "secret"
);
// or set them as strings
template.setCertificate(pemEncodedPassCertificate);
template.setPrivateKey(pemEncodedPrivateKey, optionalKeyPassword);

If you have images that are common to all passes, you may want to specify them once in the template:

// specify a single image with specific density and localization
await pass.images.add("icon", iconFilename, "2x", "ru");
// load all appropriate images in all densities and localizations
await template.images.load("./images");

You can add the image itself or a Buffer. Image format is enforced to be PNG.

Alternatively, if you have one directory containing the template file pass.json, the key com.example.passbook.pem and all the needed images, you can just use this single command:

const template = await Template.load(
  "./path/to/templateFolder",
  "secretKeyPasswod"
);

You can use the options parameter of the template factory functions to set the allowHttp property. This enables you to use a webServiceUrl in your pass.json that uses the HTTP protocol instead of HTTPS for development purposes:

const template = await Template.load(
  "./path/to/templateFolder",
  "secretKeyPasswod",
  {
    allowHttp: true,
  },
);

Create your pass

To create a new pass from a template:

const pass = template.createPass({
  serialNumber: "123456",
  description: "20% off"
});

Just like the template, you can access pass fields directly, e.g:

pass.serialNumber = "12345";
pass.description = "20% off";

In the JSON specification, structure fields (primary fields, secondary fields, etc) are represented as arrays, but items must have distinct key properties. Le sigh.

To make it easier, you can use methods of standard Map object or add that will do the logical thing. For example, to add a primary field:

pass.primaryFields.add({ key: "time", label: "Time", value: "10:00AM" });

To get one or all fields:

const dateField = pass.primaryFields.get("date");
for (const [key, { value }] of pass.primaryFields.entries()) {
  // ...
}

To remove one or all fields:

pass.primaryFields.delete("date");
pass.primaryFields.clear();

Adding images to a pass is the same as adding images to a template (see above).

Working with Dates

If you have dates in your fields make sure they are in ISO 8601 format with timezone or a Date instance. For example:

const { constants } = require('@walletpass/pass-js');

pass.primaryFields.add({ key: "updated", label: "Updated at", value: new Date(), dateStyle: constants.dateTimeFormat.SHORT, timeStyle: constants.dateTimeFormat.SHORT });

// there is also a helper setDateTime method
pass.auxiliaryFields.setDateTime(
  'serviceDate',
  'DATE',
  serviceMoment.toDate(),
  {
    dateStyle: constants.dateTimeFormat.MEDIUM,
    timeStyle: constants.dateTimeFormat.NONE,
    changeMessage: 'Service date changed to %@.',
  },
);
// main fields also accept Date objects
pass.relevantDate = new Date(2020, 1, 1, 10, 0);
template.expirationDate = new Date(2020, 10, 10, 10, 10);

Localizations

This library fully supports both string localization and/or images localization:

// everything from template
// will load all localized images and strings from folders like ru.lproj/ or fr-CA.lproj/
await template.load(folderPath);

// Strings

pass.localization
  .add("en-GB", {
    GATE: "GATE",
    DEPART: "DEPART",
    ARRIVE: "ARRIVE",
    SEAT: "SEAT",
    PASSENGER: "PASSENGER",
    FLIGHT: "FLIGHT"
  })
  .add("ru", {
    GATE: "ВЫХОД",
    DEPART: "ВЫЛЕТ",
    ARRIVE: "ПРИЛЁТ",
    SEAT: "МЕСТО",
    PASSENGER: "ПАССАЖИР",
    FLIGHT: "РЕЙС"
  });

// Images

await template.images.add(
  "logo" | "icon" | etc,
  imageFilePathOrBufferWithPNGdata,
  "1x" | "2x" | "3x" | undefined,
  "ru"
);

Localization applies for all fields' label and value. There is a note about that in documentation.

Generate the file

To generate a file:

const buf = await pass.asBuffer();
await fs.writeFile("pathToPass.pkpass", buf);

You can send the buffer directly to an HTTP server response:

app.use(async (ctx, next) => {
  ctx.status = 200;
  ctx.type = passkit.constants.PASS_MIME_TYPE;
  ctx.body = await pass.asBuffer();
});

Troubleshooting with Console app

If the pass file generates without errors but you aren't able to open your pass on an iPhone, plug the iPhone into a Mac with macOS 10.14+ and open the 'Console' application. On the left, you can select your iPhone. You will then be able to inspect any errors that occur while adding the pass.

Stay in touch

License

@walletpass/pass-js is MIT licensed.

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

pass-js's People

Contributors

18601673727 avatar akoufa avatar asp3ctus avatar assaf avatar brayovsky avatar coderreview avatar dependabot[bot] avatar greenkeeper[bot] avatar greenkeeperio-bot avatar josh- avatar krivochenko avatar madmaw avatar monkeywithacupcake avatar nchaulet avatar nickasd avatar nlang avatar panman avatar philipheinser avatar ream88 avatar renovate-bot avatar renovate[bot] avatar sja avatar sunsus avatar tinovyatkin avatar tkovis avatar tomasdev avatar wannabehero avatar xzoky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pass-js's Issues

Template. pushUpdates() method does not work

Given my code below, the Template.pushUpdates() method never reaches the APNs:

(async () => {
  res = await template.pushUpdates(push_token);
  console.log(res); // res is 'undefined' here
  process.exit();
})();

Support cyrillic text in pass.json

Hi
After updating from 4.3.1 to 6.4.0 the cyrillic text in pass.json became broken.

I have looked in to this issue and figured out that code in pass.ts
zip.push({ path: 'pass.json', data: JSON.stringify(this) });

should be
zip.push({ path: 'pass.json', data: Buffer.from(JSON.stringify(this)) });

So this way do-not-zip module will make correct files, otherwise it will make non english text to gibberish

I will make a pull request in a few.

Add an example usage project

Thanks for the super useful package! I had quite a hard time setting it up for various reasons so I wrote a rather detailed step by step tutorial on how to get the right keys and certificates: https://github.com/adipasquale/passe-passe

I also wrote a super small Node Express API that uses this lib and can be quickly deployed to Heroku.

Would you be interested in listing it as a useful resource on the pass-js README? I'd be happy to backport a few of the instructions updates directly into the project's README as well if you're open for PRs.

Invalid data error reading pass

[General] Invalid data error reading pass pass.co.uk.xxxxx/1234567890. The passTypeIdentifier or teamIdentifier provided may not match your certificate, or the certificate trust chain could not be verified.

I have create the .pem using your passkit-key and selected both cert and key

The passTypeIdentifier and teamIdentifier are correct in my cert I'm exporting as a .p12

Parsing errors when deploying to firebase

I tried using this module with Google Firebase and got stuck when deploying the project. There are at least two parsing errors:

First one in /node_modules/@destinationstransfers/passkit/dist/lib/images.js:49

        for await (const entry of entries) {
            ^^^^^

SyntaxError: Unexpected reserved word

Second one in /node_modules/@destinationstransfers/passkit/dist/lib/images.js:14:32

SyntaxError: Invalid regular expression: /(^|/)((?<lang>[-A-Z_a-z]+).lproj/)?(?<imageType>icon|logo|background|footer|strip|thumbnail+)(@(?<density>[23]x))?.png$/: Invalid group

Can we safely remove await in the first error?
For the second one, my guess is the slashes have to be escaped / should be \/

Invalid certificate, no key found at decodePrivateKey

I keep getting this error when trying to generate the pass:

Error: Invalid certificate, no key found at decodePrivateKey (/...something.../passkit/node_modules/@destinationstransfers/passkit/src/lib/decodePrivateKey.js:14:11) at signManifest (/...something.../passkit/node_modules/@destinationstransfers/passkit/src/lib/signManifest-forge.js:31:15)

I have a pem file in the correct place, and the pem was generated by passkit-keys from a .p12 file exported from Keychain. I tried exporting a .p12 with the cert+private key, only the key or only the cert...to no avail, I always get the same problem.

Any hint?
Thanks!

Invalid regexp

With the newest version, as soon as I include require('@destinationstransfers/passkit') I get the error

node_modules/@destinationstransfers/passkit/dist/lib/images.js:13
exports.IMAGE_FILENAME_REGEX = new RegExp(`^(?<imageType>${Object.keys(constants_1.IMAGES).join('|')}+)(@(?<density>[23]x))?.png$`);
                               ^

SyntaxError: Invalid regular expression: /^(?<imageType>icon|logo|background|footer|strip|thumbnail+)(@(?<density>[23]x))?.png$/: Invalid group
    at new RegExp (<anonymous>)
    at Object.<anonymous> (node_modules/@destinationstransfers/passkit/dist/lib/images.js:13:32)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (node_modules/@destinationstransfers/passkit/dist/lib/base-pass.js:5:18)

Update README

Hi!

I'm not sure, thats because I don't create a PR, but require("@destinationstransfers/passkit").createTemplate is not a function. I did the following:

const {Template, Pass} = require("@destinationstransfers/passkit");
const template = new Template("eventTicket", {...

That seems to work, but it stops on loading the images. I did a template.images.loadFromDirectory("images"); and the relative path contains e.g. a icon.png and a thumbnail.png but I get the following error:

pass.loadImagesFrom("images");
     ^

TypeError: pass.loadImagesFrom is not a function
    at Object.<anonymous> (/Users/sja/dev/testpass/index.js:20:6)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Function.Module.runMain (module.js:605:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3

end event never fires when calling pipe method

I'm running on Lambda with Node 8.10. When calling pipe into a write stream, the end event is never emitted (nor is the error event, for that matter). Although the file's finish method is emitted, the .pkpass file seems to be corrupt. Here's my code:

const file = fs.createWriteStream("/tmp/mypass.pkpass");
pass.on("error", error => {
    console.error(error);
    process.exit(1);
})
pass.on("end", function() {
    console.log("ended");
})
pass.pipe(file);

Taking the file returned to the client and attempting to install it, the system gives me the following error:

Failed to add pass: 'file:///Users/bryanbartow/Downloads/mypass.pkpass' Error Domain=PKPassKitErrorDomain Code=1 "The pass cannot be read because it isn’t valid." UserInfo={NSLocalizedDescription=The pass cannot be read because it isn’t valid., NSUnderlyingError=0x61000005bba0 {Error Domain=PKPassKitErrorDomain Code=1 "(null)"}}.

Encoding the file as a base64 string, I can decode the string and end up with the contents of the zip(.pkpass) file. The proper files are all present. I just think this is an issue where the last few bytes aren't getting written to the zip file. Has anyone else run into this?

Additionally, "downgrading" to busbud/node-passbook the end event fires on pipe and the resultant .pkpass file is recognized by the system.

Error: EBADF, Bad file descriptor

Sometimes, not always, this string:
https://github.com/destinationstransfers/passkit/blob/8189323aa39c936d9b697001ef31f3587bade2ce/src/lib/images.ts#L140
causes error: Error: EBADF, Bad file descriptor.

Maybe it will better to read file as a buffer in case when pathOrBuffer passed as a string?

async add(
  imageType: ImageType,
  pathOrBuffer: string | Buffer,
  density?: ImageDensity,
  lang?: string,
): Promise<void> {
  if (!IMAGES_TYPES.has(imageType))
    throw new TypeError(`Unknown image type ${imageSize} for ${imageType}`);
  if (density && !DENSITIES.has(density))
    throw new TypeError(`Invalid density ${density} for ${imageType}`);
  if (typeof pathOrBuffer !== 'string' && !Buffer.isBuffer(pathOrBuffer))
    throw new TypeError( `Image data for ${imageType} must be either file path or buffer`);	

  pathOrBuffer = (typeof pathOrBuffer === 'string') ? readFileAsBuffer(pathOrBuffer) : pathOrBuffer;
  const { Parser } = imagesize;
  const parser = Parser();
  const res = parser.parse(pathOrBuffer);
  if (res !== Parser.DONE)
    throw new TypeError(`Supplied buffer doesn't contain valid PNG image for ${imageType}`);
  sizeRes = parser.getResult() as ImageSizeResult;
  this.checkImage(imageType, sizeRes, density);
  super.set(this.getImageFilename(imageType, density, lang), pathOrBuffer);
}

readFileAsBuffer(path: string): Promise<Buffer> {
  return new Promise((resolve, reject) => {
    fs.readFile(path, (error, data) => {
      if (!!error) {
        reject(error);
      } else {
        resolve(data);
      }
    });
  });
}

Loading images from URL

node-passbook mentions you can load images from URL.
I noticed you had removed this from your documentation so I assume that you don't directly support it.

What would be the best approach for loading the images from a URL?

Im currently loading the images using request and buffer, but it feels a bit heavy.

 pass.images.setImage('icon', '1x', function(err, callback) {
            request({
              url: ENDPOINTS.IMAGE + offer.agency.image + '?w=29&h=29&bgcolor=ffffff',
              encoding: null,
              method: 'GET',
              proxy: null
            }, function(error, response, body) {
              callback(body);
            })
          }
        );

Barcode is not supported

Does the library support barcode? I saw an issue related with this it was solved but I am doing the same thing and I can't see the barcode

This is the original issue: #40

I am doing this:
pass.barcodes([{
message: "1234567890",
format: 'PKBarcodeFormatQR',
messageEncoding: 'iso-8859-1'
}]);

@tinovyatkin @nickasd Is this a limitation of the library or I am doing something wrong?
Library version: "@destinationstransfers/passkit": "^6.5.2"
Thanks

Node 6 LTS

AWS lambda is stuck on an older version.

How strict are you about the 8.X requirement?

Would you accept a pull request to get it working on AWS lambda?

end event not fired

The end event is not fired, although the README says so:

const file = fs.createWriteStream("mypass.pkpass");
pass.on("end", () => {
  console.log('end');
})
pass.pipe(file);

Cutting of strip

We pack to pass strip-image of three sizes: 1125x369, 750x246 and 375x123. But on devices it is clipped on right and left.

What is a correct size? Or maybe where is no "correct" size, and width of strip depends on device.

Thanks for help.

is it possible to use this library on device?

Hi,

We try to use PassKit directly in our react native project. Is it somehow possible to use it that way and generate pass on device? Because now we are getting 'there is no module http2', etc. errors.

And by the way, thanks for the library)

Node 8.x support

As per #48 runtime support under node 10.1 was dropped. Node 8.x is still widely used as a runtime, especially in servers. I suggest that it should be supported a bit longer.

Also note that the fs Promises API is still experimental in node 10.

These changes would be needed for node 8 support:

  • fs.promises was unavailable prior to node 10.
    • Use a library like normalize/mz for async fs operations, or use Util.promisify like before.
  • Don't use the global URL object. It was unavailable prior to node 10.
    • require('url').URL references the same object in earlier versions.

Feature Request: Field Types

This library strips out any meta information you add to a field using the add method.

This biggest downfall with this is you can't replicate the key value pairs found in the apple specification for;


Example

  pass.auxiliaryFields.add({
          key: "claim_expiryDate",
          label: "Expires",
          value: moment(offer.claim.expiryDate),
          dateStyle: 'PKDateStyleMedium'
        });

Newline?

Hi, I'm trying to add a longer text on the backside of the wallet card, using the "backFields" property.

I'm supposed to be able to use \n or \r \n for linebreaks, but nothing seems to be working.

Does the library somehow cut linebreaks from texts, or does anybody have linebreaks working?

Thanks

Cannot find module on 5.1.1

i am using node 11 and did a fresh installation on a new project.

I am getting Error: Cannot find module '@destinationstransfers/passkit' when i start the server.
I dont get this error if i try with 4.3.2
I have tried deleting node modules package and package-lock json several times and doing fresh install but I keep getting same error on below line
const { Template } = require("@destinationstransfers/passkit");

Uncaught Error: This file no longer open for writing

When im running pass_test.js im getting this error please help me out what im doing wrong?

` mocha pass_test.js

Pass
from template
√ should copy template fields
√ should start with no images
√ should create a structure based on style
without serial number
√ should not be valid
without organization name
√ should not be valid
without description
√ should not be valid
without icon.png
√ should not be valid
without logo.png
undefined
√ should not be valid
generated
1) "before all" hook

8 passing (49ms)
1 failing

  1. Pass
    generated
    "before all" hook:
    Uncaught Error: This file no longer open for writing
    at File.write (C:\Users\mrima\node-work\passkit\lib\zip.js:278:11)
    at SHAWriteStream.write (C:\Users\mrima\node-work\passkit\lib\pass.js:409:15)
    at ReadStream.ondata (_stream_readable.js:555:20)
    at readableAddChunk (_stream_readable.js:176:18)
    at ReadStream.Readable.push (_stream_readable.js:134:10)
    at onread (fs.js:2018:12)
    at FSReqWrap.wrapper [as oncomplete] (fs.js:682:17)`

[W3C Date] Some iOS devices can't import the pass

I'm trying to figure out why some of the ios devices failing to open generated pass.
I'm testing the same pass on different devices and some works some don't

So far i think it has something to do with IOS becouse after updating ios on iPhone 6 Plus from 12.1.4 to 12.3 it started to work.
Works:
On 5se devices with 12.2 it works
On older 5s with 12.2 it works
On iphone x with 12.3 it works
On iphone 7 plus with 12.2 it works
On iPhone 6 Plus 12.3 works after update from 12.1.4

does not works
On iphone 5 with 10.3.3 it does not work
On iphone 7 with 12.1.4 it does not work - did not yet updated to new 12.3
On iphone 7 with 12.0 it does not work
On iPhone 6 Plus 12.1.4 does not work before update to 12.3

But on thease ^ devies if i import other passes generated from different online services it works.

On android it work.
I tried to open the pass on the mac mini with the newes macos - and it opened it fine with no errors.

This was the reason my i updated from 4.3.1 to 6.4.0 in the first place... but it the newest version did not help.

I don't know that is the reason why it doesn't open on some of the devices.

Then i say it doesn't opens it - i mean
i click to on the link to download pkpass file (all the needed headers are present)
The iphone download it (because if i put break point on server - it waits after resume the error shows) - and shows error safari can not download file (error is in russian Safari не удается загрузить файл.)
if i do the same from chrome i get a much better error it sais that can not enter data to passbook.
Не удалось внести данные в Passbook.
I also tried to send the file over telegram app, but file is not clickable in it - i guess the ios blocks it.

I don't know what else to try, any ideas ?

how do I use the pass?

How do I get the pass out of this,

I ma using a lambda with POST api to create the pass and return it, but how do I use the
pass.asBuffer() to return the data to the iOS app via rest api ?

NFC Datatype Mismatch

The NFCField type does not match the datatype specified in the Apple documentation for the pass.json file.

According to Apple's documentation, the nfc top level attribute should be a single dictionary, with the required nfc fields (message and an optional public key). See: https://developer.apple.com/library/archive/documentation/UserExperience/Reference/PassKit_Bundle/Chapters/TopLevel.html#//apple_ref/doc/uid/TP40012026-CH2-DontLinkElementID_3

However, the NFCField type extends from Array<{message: string; publicKey?: string;}> (see: src/lib/nfc-fields.ts) which means that nfc properties are serialised as an array in pass.json, and that the generated pass file fails to be verified and added to a Wallet.

Unexpected Indentifier

screen shot 2017-10-17 at 2 20 01 pm

I am new with node.js, I don't understand what's wrong with my code. I just followed the instruction on your readme

relevantText not being set correctly

It appears as though the relevantText key of the locations object is never actually being set when the pass is generated.

addLocation(
    point:
      | number[]
      | { lat: number; lng: number; alt?: number }
      | { longitude: number; latitude: number; altitude?: number },
    relevantText?: string,
  ): this {
    const { longitude, latitude, altitude } = getGeoPoint(point);
    const location: import('../interfaces').Location = {
      longitude,
      latitude,
    };
    if (altitude) location.altitude = altitude;
    if (typeof relevantText === 'string') location.relevantText = relevantText;
    if (!Array.isArray(this.fields.locations))
      this.fields.locations = [location];
    else this.fields.locations.push(location);
    return this;
  }

  get locations(): ApplePass['locations'] {
    return this.fields.locations;
  }

  set locations(v: ApplePass['locations']) {
    delete this.fields.locations;
    if (!v) return;
    if (!Array.isArray(v)) throw new TypeError(`locations must be an array`);
    else for (const location of v) this.addLocation(location);
  }

this.addLocation is called without passing the relevantText parameter.

External signing of passes

The apple developer website best practices (and enterpise best practices) requries us to sign the passes on a separate system that handles private keys and signs files.
Below reference from wallet developer guide
Best Practices
As you implement your web service, keep the following best practices in mind:
Always make a backup of your private key and certificate, and keep them in a secure place.
Avoid storing your private keys on your web server, because web servers typically have a larger attack surface. A more secure approach is to have a different server handle creating and signing passes, and push the finished passes to your web server.
https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/PassKit_PG/Updating.html#//apple_ref/doc/uid/TP40012195-CH5-SW1

The template load function only allows to load certificates from a given location of keys,certs with password. Is it possible to externalize the signing like apple suggests?

pass.icon(filename); or pass.loadImagesFrom("./images") pass.loadImagesFrom/icon is not a function

Hi,

while am using pass.icon/ pass.loadimages it always returning as not a function error, can you please let me know if there is a work around to overcome this, please find my whole source code below

var express = require('express');
var app = express();
var fs = require('fs');

app.set('port', process.env.PORT || 3000 );
const { Template } = require("@destinationstransfers/passkit");
const { Pass } = require("@destinationstransfers/passkit");

const template = new Template("coupon", {
passTypeIdentifier: "pass.org.example.walletpoc",
teamIdentifier: "2343234",
backgroundColor: "rgb(255,255,255)",
organizationName: "poc"
});

const pass = template.createPass({
serialNumber: "123456",
description: "20% off"
});

pass.images.icon = "logo.png";
pass.icon("logo.png");
pass.loadImagesFrom("./images");

const file = fs.createWriteStream("mypass.pkpass");
pass.on("error", error => {
console.error(error);
process.exit(1);
})
pass.pipe(file);

app.get("/mypass", (request, response) => {
file();
pass.render(response, error => {
if (error)
console.error(error);
});
});

var server = app.listen(app.get('port'), function() {
console.log('Listening on port ' + app.get('port'));
});

or any reference to working example is much help full, thanks in advance

String valued keys at structure elements

Original module implementation seems to not support string values at structure level (the only entry of this type currently is transitType for boardingPass). Such values also a good candidate to be included in templates, however, it's not clear how to fix that from API point of view, as it doesn't support any second level properties now.
Breaking changes?

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

Setting images causes error

First of all, thank you for maintaining this useful library.

The README says that in order to load some images:

pass.images.icon = iconFilename;
pass.icon(iconFilename);
await pass.images.loadFromDirectory('./images');

I understand that each of these lines can be used alone (and you don't have to call the first or second line followed by the third one), but when I use template.images.loadFromDirectory(directoryname) followed by pass.images.icon = filename, I get the following error:

error: Unhandled Rejection at: Promise {
   <rejected> { Error: EISDIR: illegal operation on a directory, read errno: -21, code: 'EISDIR', syscall: 'read' } } reason: Error: EISDIR: illegal operation on a directory, read

What am I doing wrong?

How to use async/await with node 8

I'm using NodeJS 8.3.0 and I get the following error:

/Users/sja/.nvm/versions/node/v8.3.0/bin/node /Users/sja/dev/mypass/index.js
/Users/sja/dev/mypass/index.js:12
await template.images.loadFromDirectory("./images");
      ^^^^^^^^

SyntaxError: Unexpected identifier
    at createScript (vm.js:74:10)
    at Object.runInThisContext (vm.js:116:10)
    at Module._compile (module.js:537:28)
    at Object.Module._extensions..js (module.js:584:10)
    at Module.load (module.js:507:32)
    at tryModuleLoad (module.js:470:12)
    at Function.Module._load (module.js:462:3)
    at Function.Module.runMain (module.js:609:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:578:3

Process finished with exit code 1

Set private key in pass template before producing pass buffers

Hello, I faced a fix when a "createPass" attempt shows this message:

"INFO ReferenceError: Set private key in pass template before producing pass buffers
at Pass.asBuffer (/var/task/node_modules/@walletpass/pass-js/dist/pass.js:53:19)
at createTemplate (/var/task/customers/customerAddWallet.js:67:28)"

How do I fix it?

Please any insight.

[New Feature] Create JSON schema for pass.json

Issuehunt badges

We can use it then at Pass.validate and for providing autocomplete in VSCode pass.json editing


IssueHunt Summary

brayovsky brayovsky has been rewarded.

Backers (Total: $50.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Does not support barcode?

I was following Apple's examples and the sign_pass utility successfully outputs the barcode object, but when using your passkit no barcode is on the pass

In my pass.json I have:

"barcode" : {
    "message" : "123456",
    "format" : "PKBarcodeFormatQR",
    "messageEncoding" : "iso-8859-1"
  },

But no barcode is present in the generated pass.

Trailing slash in webServiceUrl

In process of render pass trailing slash added even if I specify webServiceUrl without it.
How I can control it? I need it because Wallet Union adds one more slash and requests //v1/... causes 404 error.

Add property sharingProhibited

Hi
In some passes in pass.json I see sharingProhibited: true. This button hides "Share" button.
Why it absent in your package?

Cannot add pass in wallet

Hello, we have created a pass using your library, but we cannot add it to Apple Wallet.
We have tried to send it via email, download it from our server but iOS doesn't open Wallet.
Instead, it prompts us to select which application to use to open the pkpass file (Wallet is not in the list).

What could be the issue here??

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.