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.
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
.
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
.
References:
- https://developer.apple.com/documentation/walletpasses/register_a_pass_for_update_notifications
- https://developer.apple.com/documentation/walletpasses/unregister_a_pass_for_update_notifications
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>;
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>;
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>;
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;