IntentJS Documentation - alexandercerutti/passkit-webservice-toolkit GitHub Wiki

This package exposes a set of typescript-ready IntentJS Controllers and Services to let you focus on your business logic integration. In this document, they are organized per Apple Service.

Before using this library, a look at the Apple Documentation for Wallet webservice is suggested, in order to understand how the business logic should be developed and how data should be saved.

Controllers and Services

Each endpoint documented by Apple in its documentation is a couple of Controller and Service, as you might not want add all of them, or add them conditionally based on the environment. All the entry points expose a property Controller and a property Service, as per the example below. They are also organized by endpoint version and by endpoint name.

This package is studied to be compatible only with CJS, as per the framework compiles only in CJS through SWC (at this moment).

It can be imported in the following ways:

/** Registering Service inside: app/boot/sp/app.ts **/
/** Use require or import as a CJS TS */
const { v1: { Registration: { Service: RegistrationService }} } = require("intent-passkit-webservice");

export class AppServiceProvider extends ServiceProvider {
	/**
	 * Register any application services here.
	 */
	register() {
		this.bindWithValue(RegistrationService, {
			async onRegister(
				deviceLibraryIdentifier: string,
				passTypeIdentifier: string,
				serialNumber: string,
				pushToken: string,
			): Promise<boolean> {
				/** your implementation */
			},
			async onUnregister(
				deviceLibraryIdentifier: string,
				passTypeIdentifier: string,
				serialNumber: string,
			): Promise<void> {
				/** your implementation */
			},
			async tokenVerifier(token: string): Promise<boolean> {
				/** your implementation */
			},
		});
	}

	// ...
}

/** Registering Controller inside: app/http/kernel.ts **/
/** Use require or import as a CJS TS */
const { v1: { Registration: { Controller: RegistrationController }} } = require("intent-passkit-webservice");

export class HttpKernel extends Kernel {
	public controllers(): Type<any>[] {
		return [
			RegistrationController,
		];
	}

	// ...
}

Note

In order to change the prefix of the where Apple will be going to send you requests, a new controller must be created and it can extend the provided one. Like this:

const { v1: { List } } = require("intent-passkit-webservice");
const { Controller } = require("@intentjs/core");

@Controller("/pass")
export default class ExtendedListController extends List.Controller {
  constructor(service: List.Service) {
  	super(service);
  }
}

Please note that once a controller will get extended, all the other controllers will have to be extended, as the path you see /pass, is sent through the property webServiceURL in the pass.json when a pass is generated. Failing to override all the controllers, will make some services and controllers unreachable.

Please note as well that providing a service parameter is required as per library service injection inside the controller.

Once a controller has been extended, you'll need to register it inside your app/http/kernel.ts file, like above, instead of the one from the library.

Each service accepts some mandatory callbacks, which are required by the controller to work. If not provided, the router will throw a ServiceMethodNotReplacedError.

Validation and authentication

Some endpoints require, by Apple specification, a token to be set in the pass.json file inside the .pkpass bundle. In order to let you implement your own token validation logic, some middlewares allow you to specify an async function, that will let you implement the token validation logic.

A light validation is performed directly by the middlewares by looking at the Authorization Schema for it to be ApplePass.


Registration

References:

Entrypoint: (intent-passkit-webservice).v1.Registration.

Description:

This wraps both device registration and unregistration endpoints, as they are coupled, as a controller and service.

Service callbacks:

  • onRegister (mandatory)
onRegister(deviceLibraryIdentifier: string, passTypeIdentifier: string, serialNumber: string, pushToken: string): PromiseLike<boolean>;
  • onUnregister (mandatory)
onUnregister(deviceLibraryIdentifier: string, passTypeIdentifier: string, serialNumber: string): PromiseLike<boolean>;
  • tokenVerifier (optional)

Can be used to verify the token sent by Apple Wallet and that is available in a pass. If set, this function is called before both onRegister and onUnregister.

tokenVerifier?(token: string): PromiseLike<boolean>;

Update

References:

Entrypoint: (intent-passkit-webservice).v1.Update

Description:

This wraps the request for a Pass update made by Apple Wallet on two occasions:

  • Manual refresh by the user
  • Refresh by application following an APNS notification by your server and the list endpoint invocation (see below for the right Controller and Service).

Service callbacks:

  • onUpdateRequest (mandatory)

Generate your pass when this callback is received. You can use whatever system you want to generate a pass, but you might find passkit-generator interesting for this.

Returning undefined will make the call to return HTTP 304, as per Apple (legacy) documentation. Otherwise, HTTP 200 will be returned.

Returning something else, except undefined and Uint8Array will make the call to return HTTP 500.

onUpdateRequest(passTypeIdentifier: string, serialNumber: string): PromiseLike<Uint8Array>;
  • tokenVerifier (optional)

Can be used to verify the token sent by Apple Wallet and that is available in a pass. If set, this function is called before both onUpdateRequest.

tokenVerifier?(token: string): PromiseLike<boolean>;

List

References:

Entrypoint: (intent-passkit-webservice).v1.List.

Description:

This wraps the request for changed passes that Apple Wallet sends after receiving an APNS notification. After the list of updated serial numbers is provided, Apple Wallet will use that information to perform a request per serial number to your update middleware.

Service callbacks:

  • onListRetrieve (mandatory)

This endpoint is called with two parameters and a query string: passesUpdatedSince. This value is the value you sent in the previous list request (won't be provided, therefore, on the first request).

As the format is not enforced by Apple specifications, for Typescript LastUpdatedFormat is set to be unknown and can be specified in the middleware signature or casted when you use the function.

onListRetrieve(deviceLibraryIdentifier: string, passTypeIdentifier: string, filters: {
	passesUpdatedSince?: LastUpdatedFormat
}): PromiseLike<SerialNumbers | undefined>;

Log

References:

Entrypoint: (intent-passkit-webservice).v1.Log.

Description:

This wraps the request Apple will perform in case of logs. Logs may contain records about failed requests (e.g. missing endpoints or bad status code).

Service callbacks:

  • onIncomingLogs (mandatory)
onIncomingLogs(logs: string[]): void;
⚠️ **GitHub.com Fallback** ⚠️